1 /**********
2 This library is free software; you can redistribute it and/or modify it under
3 the terms of the GNU Lesser General Public License as published by the
4 Free Software Foundation; either version 3 of the License, or (at your
5 option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6 
7 This library is distributed in the hope that it will be useful, but WITHOUT
8 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
10 more details.
11 
12 You should have received a copy of the GNU Lesser General Public License
13 along with this library; if not, write to the Free Software Foundation, Inc.,
14 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
15 **********/
16 // "liveMedia"
17 // Copyright (c) 1996-2020 Live Networks, Inc.  All rights reserved.
18 // MP3 internal implementation details
19 // Implementation
20 
21 #include "MP3InternalsHuffman.hh"
22 
23 #include <stdlib.h>
24 #include <math.h>
25 #include <stdio.h>
26 #include <string.h>
27 
28 // This is crufty old code that needs to be cleaned up #####
29 
30 static unsigned const live_tabsel[2][3][16] = {
31    { {32,32,64,96,128,160,192,224,256,288,320,352,384,416,448,448},
32      {32,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,384},
33      {32,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,320} },
34 
35    { {32,32,48,56,64,80,96,112,128,144,160,176,192,224,256,256},
36      {8,8,16,24,32,40,48,56,64,80,96,112,128,144,160,160},
37      {8,8,16,24,32,40,48,56,64,80,96,112,128,144,160,160} }
38 };
39 /* Note: live_tabsel[*][*][0 or 15] shouldn't occur; use dummy values there */
40 
41 static long const live_freqs[]
42 = { 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000, 0 };
43 
44 struct bandInfoStruct {
45   int longIdx[23];
46   int longDiff[22];
47   int shortIdx[14];
48   int shortDiff[13];
49 };
50 
51 static struct bandInfoStruct const bandInfo[7] = {
52 /* MPEG 1.0 */
53  { {0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576},
54    {4,4,4,4,4,4,6,6,8, 8,10,12,16,20,24,28,34,42,50,54, 76,158},
55    {0,4*3,8*3,12*3,16*3,22*3,30*3,40*3,52*3,66*3, 84*3,106*3,136*3,192*3},
56    {4,4,4,4,6,8,10,12,14,18,22,30,56} } ,
57 
58  { {0,4,8,12,16,20,24,30,36,42,50,60,72, 88,106,128,156,190,230,276,330,384,576},
59    {4,4,4,4,4,4,6,6,6, 8,10,12,16,18,22,28,34,40,46,54, 54,192},
60    {0,4*3,8*3,12*3,16*3,22*3,28*3,38*3,50*3,64*3, 80*3,100*3,126*3,192*3},
61    {4,4,4,4,6,6,10,12,14,16,20,26,66} } ,
62 
63  { {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576} ,
64    {4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102, 26} ,
65    {0,4*3,8*3,12*3,16*3,22*3,30*3,42*3,58*3,78*3,104*3,138*3,180*3,192*3} ,
66    {4,4,4,4,6,8,12,16,20,26,34,42,12} }  ,
67 
68 /* MPEG 2.0 */
69  { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
70    {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } ,
71    {0,4*3,8*3,12*3,18*3,24*3,32*3,42*3,56*3,74*3,100*3,132*3,174*3,192*3} ,
72    {4,4,4,6,6,8,10,14,18,26,32,42,18 } } ,
73 
74  { {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576},
75    {6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,52,64,70,76,36 } ,
76    {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,136*3,180*3,192*3} ,
77    {4,4,4,6,8,10,12,14,18,24,32,44,12 } } ,
78 
79  { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
80    {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 },
81    {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,134*3,174*3,192*3},
82    {4,4,4,6,8,10,12,14,18,24,30,40,18 } } ,
83 
84 /* MPEG 2.5, wrong! table (it's just a copy of MPEG 2.0/44.1kHz) */
85  { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
86    {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } ,
87    {0,4*3,8*3,12*3,18*3,24*3,32*3,42*3,56*3,74*3,100*3,132*3,174*3,192*3} ,
88    {4,4,4,6,6,8,10,14,18,26,32,42,18 } } ,
89 };
90 
91 unsigned int n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */
92 unsigned int i_slen2[256]; /* MPEG 2.0 slen for intensity stereo */
93 
94 #define MPG_MD_MONO 3
95 
96 
97 ////////// MP3FrameParams //////////
98 
MP3FrameParams()99 MP3FrameParams::MP3FrameParams()
100   : bv(frameBytes, 0, sizeof frameBytes) /* by default */ {
101   oldHdr = firstHdr = 0;
102 
103   static Boolean doneInit = False;
104   if (doneInit) return;
105 
106   int i,j,k,l;
107 
108   for (i=0;i<5;i++) {
109     for (j=0;j<6;j++) {
110       for (k=0;k<6;k++) {
111         int n = k + j * 6 + i * 36;
112         i_slen2[n] = i|(j<<3)|(k<<6)|(3<<12);
113       }
114     }
115   }
116   for (i=0;i<4;i++) {
117     for (j=0;j<4;j++) {
118       for (k=0;k<4;k++) {
119         int n = k + j * 4 + i * 16;
120         i_slen2[n+180] = i|(j<<3)|(k<<6)|(4<<12);
121       }
122     }
123   }
124   for (i=0;i<4;i++) {
125     for (j=0;j<3;j++) {
126       int n = j + i * 3;
127       i_slen2[n+244] = i|(j<<3) | (5<<12);
128       n_slen2[n+500] = i|(j<<3) | (2<<12) | (1<<15);
129     }
130   }
131 
132   for (i=0;i<5;i++) {
133     for (j=0;j<5;j++) {
134       for (k=0;k<4;k++) {
135         for (l=0;l<4;l++) {
136           int n = l + k * 4 + j * 16 + i * 80;
137           n_slen2[n] = i|(j<<3)|(k<<6)|(l<<9)|(0<<12);
138         }
139       }
140     }
141   }
142   for (i=0;i<5;i++) {
143     for (j=0;j<5;j++) {
144       for (k=0;k<4;k++) {
145         int n = k + j * 4 + i * 20;
146         n_slen2[n+400] = i|(j<<3)|(k<<6)|(1<<12);
147       }
148     }
149   }
150   doneInit = True;
151 }
152 
~MP3FrameParams()153 MP3FrameParams::~MP3FrameParams() {
154 }
155 
setParamsFromHeader()156 void MP3FrameParams::setParamsFromHeader() {
157   if (hdr & (1<<20)) {
158     isMPEG2 = (hdr & (1<<19)) ? 0x0 : 0x1;
159     isMPEG2_5 = 0;
160   }
161   else {
162     isMPEG2 = 1;
163     isMPEG2_5 = 1;
164   }
165 
166   layer = 4-((hdr>>17)&3);
167   if (layer == 4) layer = 3; // layer==4 is not allowed
168   bitrateIndex = ((hdr>>12)&0xf);
169 
170   if (isMPEG2_5) {
171     samplingFreqIndex = ((hdr>>10)&0x3) + 6;
172   } else {
173     samplingFreqIndex = ((hdr>>10)&0x3) + (isMPEG2*3);
174   }
175 
176   hasCRC = (hdr & 0x10000) == 0;
177 
178   padding   = ((hdr>>9)&0x1);
179   extension = ((hdr>>8)&0x1);
180   mode      = ((hdr>>6)&0x3);
181   mode_ext  = ((hdr>>4)&0x3);
182   copyright = ((hdr>>3)&0x1);
183   original  = ((hdr>>2)&0x1);
184   emphasis  = hdr & 0x3;
185 
186   stereo    = (mode == MPG_MD_MONO) ? 1 : 2;
187 
188   if (((hdr>>10)&0x3) == 0x3) {
189 #ifdef DEBUG_ERRORS
190     fprintf(stderr,"Stream error - hdr: 0x%08x\n", hdr);
191 #endif
192   }
193 
194   bitrate = live_tabsel[isMPEG2][layer-1][bitrateIndex];
195   samplingFreq = live_freqs[samplingFreqIndex];
196   isStereo = (stereo > 1);
197   isFreeFormat = (bitrateIndex == 0);
198   frameSize
199     = ComputeFrameSize(bitrate, samplingFreq, padding, isMPEG2, layer);
200   sideInfoSize = computeSideInfoSize();
201  }
202 
computeSideInfoSize()203 unsigned MP3FrameParams::computeSideInfoSize() {
204   unsigned size;
205 
206   if (isMPEG2) {
207     size = isStereo ? 17 : 9;
208   } else {
209     size = isStereo ? 32 : 17;
210   }
211 
212   if (hasCRC) {
213     size += 2;
214   }
215 
216   return size;
217 }
218 
ComputeFrameSize(unsigned bitrate,unsigned samplingFreq,Boolean usePadding,Boolean isMPEG2,unsigned char layer)219 unsigned ComputeFrameSize(unsigned bitrate, unsigned samplingFreq,
220 			  Boolean usePadding, Boolean isMPEG2,
221 			  unsigned char layer) {
222   if (samplingFreq == 0) return 0;
223   unsigned const bitrateMultiplier = (layer == 1) ? 12000*4 : 144000;
224   unsigned framesize;
225 
226   framesize = bitrate*bitrateMultiplier;
227   framesize /= samplingFreq<<(isMPEG2 ? 1 : 0);
228   framesize = framesize + usePadding - 4;
229 
230   return framesize;
231 }
232 
233 #define TRUNC_FAIRLY
updateSideInfoSizes(MP3SideInfo & sideInfo,Boolean isMPEG2,unsigned char const * mainDataPtr,unsigned allowedNumBits,unsigned & part23Length0a,unsigned & part23Length0aTruncation,unsigned & part23Length0b,unsigned & part23Length0bTruncation,unsigned & part23Length1a,unsigned & part23Length1aTruncation,unsigned & part23Length1b,unsigned & part23Length1bTruncation)234 static unsigned updateSideInfoSizes(MP3SideInfo& sideInfo, Boolean isMPEG2,
235 				    unsigned char const* mainDataPtr,
236 				    unsigned allowedNumBits,
237 				    unsigned& part23Length0a,
238 				    unsigned& part23Length0aTruncation,
239 				    unsigned& part23Length0b,
240 				    unsigned& part23Length0bTruncation,
241 				    unsigned& part23Length1a,
242 				    unsigned& part23Length1aTruncation,
243 				    unsigned& part23Length1b,
244 				    unsigned& part23Length1bTruncation) {
245   unsigned p23L0, p23L1 = 0, p23L0Trunc = 0, p23L1Trunc = 0;
246 
247   p23L0 = sideInfo.ch[0].gr[0].part2_3_length;
248   p23L1 = isMPEG2 ? 0 : sideInfo.ch[0].gr[1].part2_3_length;
249 #ifdef TRUNC_ONLY0
250   if (p23L0 < allowedNumBits)
251     allowedNumBits = p23L0;
252 #endif
253 #ifdef TRUNC_ONLY1
254   if (p23L1 < allowedNumBits)
255     allowedNumBits = p23L1;
256 #endif
257   if (p23L0 + p23L1 > allowedNumBits) {
258     /* We need to shorten one or both fields */
259     unsigned truncation = p23L0 + p23L1 - allowedNumBits;
260 #ifdef TRUNC_FAIRLY
261     p23L0Trunc = (truncation*p23L0)/(p23L0 + p23L1);
262     p23L1Trunc = truncation - p23L0Trunc;
263 #endif
264 #if defined(TRUNC_FAVOR0) || defined(TRUNC_ONLY0)
265     p23L1Trunc = (truncation>p23L1) ? p23L1 : truncation;
266     p23L0Trunc = truncation - p23L1Trunc;
267 #endif
268 #if defined(TRUNC_FAVOR1) || defined(TRUNC_ONLY1)
269     p23L0Trunc = (truncation>p23L0) ? p23L0 : truncation;
270     p23L1Trunc = truncation - p23L0Trunc;
271 #endif
272   }
273 
274   /* ASSERT: (p23L0Trunc <= p23L0) && (p23l1Trunc <= p23L1) */
275   p23L0 -= p23L0Trunc; p23L1 -= p23L1Trunc;
276 #ifdef DEBUG
277   fprintf(stderr, "updateSideInfoSizes (allowed: %d): %d->%d, %d->%d\n", allowedNumBits, p23L0+p23L0Trunc, p23L0, p23L1+p23L1Trunc, p23L1);
278 #endif
279 
280   // The truncations computed above are still estimates.  We need to
281   // adjust them so that the new fields will continue to end on
282   // Huffman-encoded sample boundaries:
283   updateSideInfoForHuffman(sideInfo, isMPEG2, mainDataPtr,
284 			   p23L0, p23L1,
285 			   part23Length0a, part23Length0aTruncation,
286 			   part23Length0b, part23Length0bTruncation,
287 			   part23Length1a, part23Length1aTruncation,
288 			   part23Length1b, part23Length1bTruncation);
289   p23L0 = part23Length0a + part23Length0b;
290   p23L1 = part23Length1a + part23Length1b;
291 
292   sideInfo.ch[0].gr[0].part2_3_length = p23L0;
293   sideInfo.ch[0].gr[1].part2_3_length = p23L1;
294   part23Length0bTruncation
295     += sideInfo.ch[1].gr[0].part2_3_length; /* allow for stereo */
296   sideInfo.ch[1].gr[0].part2_3_length = 0; /* output mono */
297   sideInfo.ch[1].gr[1].part2_3_length = 0; /* output mono */
298 
299   return p23L0 + p23L1;
300 }
301 
302 
GetADUInfoFromMP3Frame(unsigned char const * framePtr,unsigned totFrameSize,unsigned & hdr,unsigned & frameSize,MP3SideInfo & sideInfo,unsigned & sideInfoSize,unsigned & backpointer,unsigned & aduSize)303 Boolean GetADUInfoFromMP3Frame(unsigned char const* framePtr,
304 			       unsigned totFrameSize,
305 			       unsigned& hdr, unsigned& frameSize,
306 			       MP3SideInfo& sideInfo, unsigned& sideInfoSize,
307 			       unsigned& backpointer, unsigned& aduSize) {
308   if (totFrameSize < 4) return False; // there's not enough data
309 
310   MP3FrameParams fr;
311   fr.hdr =   ((unsigned)framePtr[0] << 24) | ((unsigned)framePtr[1] << 16)
312            | ((unsigned)framePtr[2] << 8) | (unsigned)framePtr[3];
313   fr.setParamsFromHeader();
314   fr.setBytePointer(framePtr + 4, totFrameSize - 4); // skip hdr
315 
316   frameSize = 4 + fr.frameSize;
317 
318   if (fr.layer != 3) {
319     // Special case for non-layer III frames
320     backpointer = 0;
321     sideInfoSize = 0;
322     aduSize = fr.frameSize;
323     return True;
324   }
325 
326   sideInfoSize = fr.sideInfoSize;
327   if (totFrameSize < 4 + sideInfoSize) return False; // not enough data
328 
329   fr.getSideInfo(sideInfo);
330 
331   hdr = fr.hdr;
332   backpointer = sideInfo.main_data_begin;
333   unsigned numBits = sideInfo.ch[0].gr[0].part2_3_length;
334   numBits += sideInfo.ch[0].gr[1].part2_3_length;
335   numBits += sideInfo.ch[1].gr[0].part2_3_length;
336   numBits += sideInfo.ch[1].gr[1].part2_3_length;
337   aduSize = (numBits+7)/8;
338 #ifdef DEBUG
339   fprintf(stderr, "mp3GetADUInfoFromFrame: hdr: %08x, frameSize: %d, part2_3_lengths: %d,%d,%d,%d, aduSize: %d, backpointer: %d\n", hdr, frameSize, sideInfo.ch[0].gr[0].part2_3_length, sideInfo.ch[0].gr[1].part2_3_length, sideInfo.ch[1].gr[0].part2_3_length, sideInfo.ch[1].gr[1].part2_3_length, aduSize, backpointer);
340 #endif
341 
342   return True;
343 }
344 
345 
getSideInfo1(MP3FrameParams & fr,MP3SideInfo & si,int stereo,int ms_stereo,long sfreq,int)346 static void getSideInfo1(MP3FrameParams& fr, MP3SideInfo& si,
347 			 int stereo, int ms_stereo, long sfreq,
348 			 int /*single*/) {
349    int ch, gr;
350 #if 0
351    int powdiff = (single == 3) ? 4 : 0;
352 #endif
353 
354    /* initialize all four "part2_3_length" fields to zero: */
355    si.ch[0].gr[0].part2_3_length = 0; si.ch[1].gr[0].part2_3_length = 0;
356    si.ch[0].gr[1].part2_3_length = 0; si.ch[1].gr[1].part2_3_length = 0;
357 
358    si.main_data_begin = fr.getBits(9);
359    if (stereo == 1)
360      si.private_bits = fr.getBits(5);
361    else
362      si.private_bits = fr.getBits(3);
363 
364    for (ch=0; ch<stereo; ch++) {
365        si.ch[ch].gr[0].scfsi = -1;
366        si.ch[ch].gr[1].scfsi = fr.getBits(4);
367    }
368 
369    for (gr=0; gr<2; gr++) {
370      for (ch=0; ch<stereo; ch++) {
371        MP3SideInfo::gr_info_s_t& gr_info = si.ch[ch].gr[gr];
372 
373        gr_info.part2_3_length = fr.getBits(12);
374        gr_info.big_values = fr.getBits(9);
375        gr_info.global_gain = fr.getBits(8);
376 #if 0
377        gr_info.pow2gain = gainpow2+256 - gr_info.global_gain + powdiff;
378        if (ms_stereo) gr_info.pow2gain += 2;
379 #endif
380        gr_info.scalefac_compress = fr.getBits(4);
381 /* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */
382        gr_info.window_switching_flag = fr.get1Bit();
383        if (gr_info.window_switching_flag) {
384          int i;
385          gr_info.block_type = fr.getBits(2);
386          gr_info.mixed_block_flag = fr.get1Bit();
387          gr_info.table_select[0] = fr.getBits(5);
388          gr_info.table_select[1] = fr.getBits(5);
389          /*
390           * table_select[2] not needed, because there is no region2,
391           * but to satisfy some verifications tools we set it either.
392           */
393          gr_info.table_select[2] = 0;
394          for (i=0;i<3;i++) {
395 	   gr_info.subblock_gain[i] = fr.getBits(3);
396            gr_info.full_gain[i]
397 	     = gr_info.pow2gain + ((gr_info.subblock_gain[i])<<3);
398 	 }
399 
400 #ifdef DEBUG_ERRORS
401          if (gr_info.block_type == 0) {
402            fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n");
403          }
404 #endif
405          /* region_count/start parameters are implicit in this case. */
406          gr_info.region1start = 36>>1;
407          gr_info.region2start = 576>>1;
408        }
409        else
410        {
411          int i,r0c,r1c;
412          for (i=0; i<3; i++) {
413 	   gr_info.table_select[i] = fr.getBits(5);
414 	 }
415          r0c = gr_info.region0_count = fr.getBits(4);
416          r1c = gr_info.region1_count = fr.getBits(3);
417          gr_info.region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
418          gr_info.region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
419          gr_info.block_type = 0;
420          gr_info.mixed_block_flag = 0;
421        }
422        gr_info.preflag = fr.get1Bit();
423        gr_info.scalefac_scale = fr.get1Bit();
424        gr_info.count1table_select = fr.get1Bit();
425      }
426    }
427 }
428 
getSideInfo2(MP3FrameParams & fr,MP3SideInfo & si,int stereo,int ms_stereo,long sfreq,int)429 static void getSideInfo2(MP3FrameParams& fr, MP3SideInfo& si,
430 			 int stereo, int ms_stereo, long sfreq,
431 			 int /*single*/) {
432    int ch;
433 #if 0
434    int powdiff = (single == 3) ? 4 : 0;
435 #endif
436 
437    /* initialize all four "part2_3_length" fields to zero: */
438    si.ch[0].gr[0].part2_3_length = 0; si.ch[1].gr[0].part2_3_length = 0;
439    si.ch[0].gr[1].part2_3_length = 0; si.ch[1].gr[1].part2_3_length = 0;
440 
441    si.main_data_begin = fr.getBits(8);
442    if (stereo == 1)
443      si.private_bits = fr.get1Bit();
444    else
445      si.private_bits = fr.getBits(2);
446 
447    for (ch=0; ch<stereo; ch++) {
448        MP3SideInfo::gr_info_s_t& gr_info = si.ch[ch].gr[0];
449 
450        gr_info.part2_3_length = fr.getBits(12);
451        si.ch[ch].gr[1].part2_3_length = 0; /* to ensure granule 1 unused */
452 
453        gr_info.big_values = fr.getBits(9);
454        gr_info.global_gain = fr.getBits(8);
455 #if 0
456        gr_info.pow2gain = gainpow2+256 - gr_info.global_gain + powdiff;
457        if (ms_stereo) gr_info.pow2gain += 2;
458 #endif
459        gr_info.scalefac_compress = fr.getBits(9);
460 /* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */
461        gr_info.window_switching_flag = fr.get1Bit();
462        if (gr_info.window_switching_flag) {
463          int i;
464          gr_info.block_type = fr.getBits(2);
465          gr_info.mixed_block_flag = fr.get1Bit();
466          gr_info.table_select[0] = fr.getBits(5);
467          gr_info.table_select[1] = fr.getBits(5);
468          /*
469           * table_select[2] not needed, because there is no region2,
470           * but to satisfy some verifications tools we set it either.
471           */
472          gr_info.table_select[2] = 0;
473          for (i=0;i<3;i++) {
474 	   gr_info.subblock_gain[i] = fr.getBits(3);
475            gr_info.full_gain[i]
476 	     = gr_info.pow2gain + ((gr_info.subblock_gain[i])<<3);
477 	 }
478 
479 #ifdef DEBUG_ERRORS
480          if (gr_info.block_type == 0) {
481            fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n");
482          }
483 #endif
484          /* region_count/start parameters are implicit in this case. */
485 /* check this again! */
486          if (gr_info.block_type == 2)
487            gr_info.region1start = 36>>1;
488          else {
489            gr_info.region1start = 54>>1;
490          }
491          gr_info.region2start = 576>>1;
492        }
493        else
494        {
495          int i,r0c,r1c;
496          for (i=0; i<3; i++) {
497            gr_info.table_select[i] = fr.getBits(5);
498 	 }
499          r0c = gr_info.region0_count = fr.getBits(4);
500          r1c = gr_info.region1_count = fr.getBits(3);
501          gr_info.region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
502          gr_info.region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
503          gr_info.block_type = 0;
504          gr_info.mixed_block_flag = 0;
505        }
506        gr_info.scalefac_scale = fr.get1Bit();
507        gr_info.count1table_select = fr.get1Bit();
508    }
509 }
510 
511 
512 #define         MPG_MD_JOINT_STEREO     1
513 
getSideInfo(MP3SideInfo & si)514 void MP3FrameParams::getSideInfo(MP3SideInfo& si) {
515   // First skip over the CRC if present:
516   if (hasCRC) getBits(16);
517 
518   int single = -1;
519   int ms_stereo;
520   int sfreq = samplingFreqIndex;
521 
522   if (stereo == 1) {
523     single = 0;
524   }
525 
526   ms_stereo = (mode == MPG_MD_JOINT_STEREO) && (mode_ext & 0x2);
527 
528   if (isMPEG2) {
529     getSideInfo2(*this, si, stereo, ms_stereo, sfreq, single);
530   } else {
531     getSideInfo1(*this, si, stereo, ms_stereo, sfreq, single);
532   }
533 }
534 
putSideInfo1(BitVector & bv,MP3SideInfo const & si,Boolean isStereo)535 static void putSideInfo1(BitVector& bv,
536 			 MP3SideInfo const& si, Boolean isStereo) {
537   int ch, gr, i;
538   int stereo = isStereo ? 2 : 1;
539 
540   bv.putBits(si.main_data_begin,9);
541   if (stereo == 1)
542     bv.putBits(si.private_bits, 5);
543   else
544     bv.putBits(si.private_bits, 3);
545 
546   for (ch=0; ch<stereo; ch++) {
547     bv.putBits(si.ch[ch].gr[1].scfsi, 4);
548   }
549 
550   for (gr=0; gr<2; gr++) {
551     for (ch=0; ch<stereo; ch++) {
552       MP3SideInfo::gr_info_s_t const& gr_info = si.ch[ch].gr[gr];
553 
554       bv.putBits(gr_info.part2_3_length, 12);
555       bv.putBits(gr_info.big_values, 9);
556       bv.putBits(gr_info.global_gain, 8);
557       bv.putBits(gr_info.scalefac_compress, 4);
558       bv.put1Bit(gr_info.window_switching_flag);
559       if (gr_info.window_switching_flag) {
560 	bv.putBits(gr_info.block_type, 2);
561 	bv.put1Bit(gr_info.mixed_block_flag);
562 	for (i=0; i<2; i++)
563 	  bv.putBits(gr_info.table_select[i], 5);
564 	for (i=0; i<3; i++)
565 	  bv.putBits(gr_info.subblock_gain[i], 3);
566       }
567       else {
568 	for (i=0; i<3; i++)
569 	  bv.putBits(gr_info.table_select[i], 5);
570 	bv.putBits(gr_info.region0_count, 4);
571 	bv.putBits(gr_info.region1_count, 3);
572       }
573 
574       bv.put1Bit(gr_info.preflag);
575       bv.put1Bit(gr_info.scalefac_scale);
576       bv.put1Bit(gr_info.count1table_select);
577     }
578   }
579 }
580 
putSideInfo2(BitVector & bv,MP3SideInfo const & si,Boolean isStereo)581 static void putSideInfo2(BitVector& bv,
582 			 MP3SideInfo const& si, Boolean isStereo) {
583   int ch, i;
584   int stereo = isStereo ? 2 : 1;
585 
586   bv.putBits(si.main_data_begin,8);
587   if (stereo == 1)
588     bv.put1Bit(si.private_bits);
589   else
590     bv.putBits(si.private_bits, 2);
591 
592   for (ch=0; ch<stereo; ch++) {
593     MP3SideInfo::gr_info_s_t const& gr_info = si.ch[ch].gr[0];
594 
595     bv.putBits(gr_info.part2_3_length, 12);
596     bv.putBits(gr_info.big_values, 9);
597     bv.putBits(gr_info.global_gain, 8);
598     bv.putBits(gr_info.scalefac_compress, 9);
599     bv.put1Bit(gr_info.window_switching_flag);
600     if (gr_info.window_switching_flag) {
601       bv.putBits(gr_info.block_type, 2);
602       bv.put1Bit(gr_info.mixed_block_flag);
603       for (i=0; i<2; i++)
604 	bv.putBits(gr_info.table_select[i], 5);
605       for (i=0; i<3; i++)
606 	bv.putBits(gr_info.subblock_gain[i], 3);
607     }
608     else {
609       for (i=0; i<3; i++)
610 	bv.putBits(gr_info.table_select[i], 5);
611       bv.putBits(gr_info.region0_count, 4);
612       bv.putBits(gr_info.region1_count, 3);
613     }
614 
615     bv.put1Bit(gr_info.scalefac_scale);
616     bv.put1Bit(gr_info.count1table_select);
617   }
618 }
619 
PutMP3SideInfoIntoFrame(MP3SideInfo const & si,MP3FrameParams const & fr,unsigned char * framePtr)620 static void PutMP3SideInfoIntoFrame(MP3SideInfo const& si,
621 				    MP3FrameParams const& fr,
622 				    unsigned char* framePtr) {
623   if (fr.hasCRC) framePtr += 2; // skip CRC
624 
625   BitVector bv(framePtr, 0, 8*fr.sideInfoSize);
626 
627   if (fr.isMPEG2) {
628     putSideInfo2(bv, si, fr.isStereo);
629   } else {
630     putSideInfo1(bv, si, fr.isStereo);
631   }
632 }
633 
634 
ZeroOutMP3SideInfo(unsigned char * framePtr,unsigned totFrameSize,unsigned newBackpointer)635 Boolean ZeroOutMP3SideInfo(unsigned char* framePtr, unsigned totFrameSize,
636                            unsigned newBackpointer) {
637   if (totFrameSize < 4) return False; // there's not enough data
638 
639   MP3FrameParams fr;
640   fr.hdr =   ((unsigned)framePtr[0] << 24) | ((unsigned)framePtr[1] << 16)
641            | ((unsigned)framePtr[2] << 8) | (unsigned)framePtr[3];
642   fr.setParamsFromHeader();
643   fr.setBytePointer(framePtr + 4, totFrameSize - 4); // skip hdr
644 
645   if (totFrameSize < 4 + fr.sideInfoSize) return False; // not enough data
646 
647   MP3SideInfo si;
648   fr.getSideInfo(si);
649 
650   si.main_data_begin = newBackpointer; /* backpointer */
651   /* set all four "part2_3_length" and "big_values" fields to zero: */
652   si.ch[0].gr[0].part2_3_length = si.ch[0].gr[0].big_values = 0;
653   si.ch[1].gr[0].part2_3_length = si.ch[1].gr[0].big_values = 0;
654   si.ch[0].gr[1].part2_3_length = si.ch[0].gr[1].big_values = 0;
655   si.ch[1].gr[1].part2_3_length = si.ch[1].gr[1].big_values = 0;
656 
657   PutMP3SideInfoIntoFrame(si, fr, framePtr + 4);
658 
659   return True;
660 }
661 
662 
MP3BitrateToBitrateIndex(unsigned bitrate,Boolean isMPEG2)663 static unsigned MP3BitrateToBitrateIndex(unsigned bitrate /* in kbps */,
664 					 Boolean isMPEG2) {
665   for (unsigned i = 1; i < 15; ++i) {
666     if (live_tabsel[isMPEG2][2][i] >= bitrate)
667       return i;
668   }
669 
670   // "bitrate" was larger than any possible, so return the largest possible:
671   return 14;
672 }
673 
outputHeader(unsigned char * toPtr,unsigned hdr)674 static void outputHeader(unsigned char* toPtr, unsigned hdr) {
675   toPtr[0] = (unsigned char)(hdr>>24);
676   toPtr[1] = (unsigned char)(hdr>>16);
677   toPtr[2] = (unsigned char)(hdr>>8);
678   toPtr[3] = (unsigned char)(hdr);
679 }
680 
assignADUBackpointer(MP3FrameParams const & fr,unsigned aduSize,MP3SideInfo & sideInfo,unsigned & availableBytesForBackpointer)681 static void assignADUBackpointer(MP3FrameParams const& fr,
682 				 unsigned aduSize,
683 				 MP3SideInfo& sideInfo,
684 				 unsigned& availableBytesForBackpointer) {
685   // Give the ADU as large a backpointer as possible:
686   unsigned maxBackpointerSize = fr.isMPEG2 ? 255 : 511;
687 
688   unsigned backpointerSize = availableBytesForBackpointer;
689   if (backpointerSize > maxBackpointerSize) {
690     backpointerSize = maxBackpointerSize;
691   }
692 
693   // Store the new backpointer now:
694   sideInfo.main_data_begin = backpointerSize;
695 
696   // Figure out how many bytes are available for the *next* ADU's backpointer:
697   availableBytesForBackpointer
698     = backpointerSize + fr.frameSize - fr.sideInfoSize ;
699   if (availableBytesForBackpointer < aduSize) {
700     availableBytesForBackpointer = 0;
701   } else {
702     availableBytesForBackpointer -= aduSize;
703   }
704 }
705 
TranscodeMP3ADU(unsigned char const * fromPtr,unsigned fromSize,unsigned toBitrate,unsigned char * toPtr,unsigned toMaxSize,unsigned & availableBytesForBackpointer)706 unsigned TranscodeMP3ADU(unsigned char const* fromPtr, unsigned fromSize,
707                       unsigned toBitrate,
708 		      unsigned char* toPtr, unsigned toMaxSize,
709 		      unsigned& availableBytesForBackpointer) {
710   // Begin by parsing the input ADU's parameters:
711   unsigned hdr, inFrameSize, inSideInfoSize, backpointer, inAduSize;
712   MP3SideInfo sideInfo;
713   if (!GetADUInfoFromMP3Frame(fromPtr, fromSize,
714                               hdr, inFrameSize, sideInfo, inSideInfoSize,
715 			      backpointer, inAduSize)) {
716     return 0;
717   }
718   fromPtr += (4+inSideInfoSize); // skip to 'main data'
719 
720   // Alter the 4-byte MPEG header to reflect the output ADU:
721   // (different bitrate; mono; no CRC)
722   Boolean isMPEG2 = ((hdr&0x00080000) == 0);
723   unsigned toBitrateIndex = MP3BitrateToBitrateIndex(toBitrate, isMPEG2);
724   hdr &=~ 0xF000; hdr |= (toBitrateIndex<<12); // set bitrate index
725   hdr |= 0x10200; // turn on !error-prot and padding bits
726   hdr &=~ 0xC0; hdr |= 0xC0; // set mode to 3 (mono)
727 
728   // Set up the rest of the parameters of the new ADU:
729   MP3FrameParams outFr;
730   outFr.hdr = hdr;
731   outFr.setParamsFromHeader();
732 
733   // Figure out how big to make the output ADU:
734   unsigned inAveAduSize = inFrameSize - inSideInfoSize;
735   unsigned outAveAduSize = outFr.frameSize - outFr.sideInfoSize;
736   unsigned desiredOutAduSize /*=inAduSize*outAveAduSize/inAveAduSize*/
737     = (2*inAduSize*outAveAduSize + inAveAduSize)/(2*inAveAduSize);
738       // this rounds to the nearest integer
739 
740   if (toMaxSize < (4 + outFr.sideInfoSize)) return 0;
741   unsigned maxOutAduSize = toMaxSize - (4 + outFr.sideInfoSize);
742   if (desiredOutAduSize > maxOutAduSize) {
743     desiredOutAduSize = maxOutAduSize;
744   }
745 
746   // Figure out the new sizes of the various 'part23 lengths',
747   // and how much they are truncated:
748   unsigned part23Length0a, part23Length0aTruncation;
749   unsigned part23Length0b, part23Length0bTruncation;
750   unsigned part23Length1a, part23Length1aTruncation;
751   unsigned part23Length1b, part23Length1bTruncation;
752   unsigned numAduBits
753     = updateSideInfoSizes(sideInfo, outFr.isMPEG2,
754 			  fromPtr, 8*desiredOutAduSize,
755 			  part23Length0a, part23Length0aTruncation,
756 			  part23Length0b, part23Length0bTruncation,
757 			  part23Length1a, part23Length1aTruncation,
758 			  part23Length1b, part23Length1bTruncation);
759 #ifdef DEBUG
760 fprintf(stderr, "shrinkage %d->%d [(%d,%d),(%d,%d)] (trunc: [(%d,%d),(%d,%d)]) {%d}\n", inAduSize, (numAduBits+7)/8,
761 	      part23Length0a, part23Length0b, part23Length1a, part23Length1b,
762 	      part23Length0aTruncation, part23Length0bTruncation,
763 	      part23Length1aTruncation, part23Length1bTruncation,
764 	      maxOutAduSize);
765 #endif
766  unsigned actualOutAduSize = (numAduBits+7)/8;
767 
768  // Give the new ADU an appropriate 'backpointer':
769  assignADUBackpointer(outFr, actualOutAduSize, sideInfo, availableBytesForBackpointer);
770 
771  ///// Now output the new ADU:
772 
773  // 4-byte header
774  outputHeader(toPtr, hdr); toPtr += 4;
775 
776  // side info
777  PutMP3SideInfoIntoFrame(sideInfo, outFr, toPtr); toPtr += outFr.sideInfoSize;
778 
779  // 'main data', using the new lengths
780  unsigned toBitOffset = 0;
781  unsigned fromBitOffset = 0;
782 
783  /* rebuild portion 0a: */
784  memmove(toPtr, fromPtr, (part23Length0a+7)/8);
785  toBitOffset += part23Length0a;
786  fromBitOffset += part23Length0a + part23Length0aTruncation;
787 
788  /* rebuild portion 0b: */
789  shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length0b);
790  toBitOffset += part23Length0b;
791  fromBitOffset += part23Length0b + part23Length0bTruncation;
792 
793  /* rebuild portion 1a: */
794  shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length1a);
795  toBitOffset += part23Length1a;
796  fromBitOffset += part23Length1a + part23Length1aTruncation;
797 
798  /* rebuild portion 1b: */
799  shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length1b);
800  toBitOffset += part23Length1b;
801 
802  /* zero out any remaining bits (probably unnecessary, but...) */
803  unsigned char const zero = '\0';
804  shiftBits(toPtr, toBitOffset, &zero, 0,
805 	   actualOutAduSize*8 - numAduBits);
806 
807  return 4 + outFr.sideInfoSize + actualOutAduSize;
808 }
809