liveMedia/MP3InternalsHuffman.cpp

Go to the documentation of this file.
00001 /**********
00002 This library is free software; you can redistribute it and/or modify it under
00003 the terms of the GNU Lesser General Public License as published by the
00004 Free Software Foundation; either version 2.1 of the License, or (at your
00005 option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
00006 
00007 This library is distributed in the hope that it will be useful, but WITHOUT
00008 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00009 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
00010 more details.
00011 
00012 You should have received a copy of the GNU Lesser General Public License
00013 along with this library; if not, write to the Free Software Foundation, Inc.,
00014 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
00015 **********/
00016 // "liveMedia"
00017 // Copyright (c) 1996-2012 Live Networks, Inc.  All rights reserved.
00018 // MP3 internal implementation details (Huffman encoding)
00019 // Implementation
00020 
00021 #include "MP3InternalsHuffman.hh"
00022 #include <stdio.h>
00023 #include <string.h>
00024 #include <stdlib.h>
00025 
00026 MP3HuffmanEncodingInfo
00027 ::MP3HuffmanEncodingInfo(Boolean includeDecodedValues) {
00028   if (includeDecodedValues) {
00029     decodedValues = new unsigned[(SBLIMIT*SSLIMIT + 1)*4];
00030   } else {
00031     decodedValues = NULL;
00032   }
00033 }
00034 
00035 MP3HuffmanEncodingInfo::~MP3HuffmanEncodingInfo() {
00036   delete[] decodedValues;
00037 }
00038 
00039 // This is crufty old code that needs to be cleaned up #####
00040 
00041 static unsigned debugCount = 0; /* for debugging */
00042 
00043 #define TRUNC_FAVORa
00044 
00045 void updateSideInfoForHuffman(MP3SideInfo& sideInfo, Boolean isMPEG2,
00046                               unsigned char const* mainDataPtr,
00047                               unsigned p23L0, unsigned p23L1,
00048                               unsigned& part23Length0a,
00049                               unsigned& part23Length0aTruncation,
00050                               unsigned& part23Length0b,
00051                               unsigned& part23Length0bTruncation,
00052                               unsigned& part23Length1a,
00053                               unsigned& part23Length1aTruncation,
00054                               unsigned& part23Length1b,
00055                               unsigned& part23Length1bTruncation) {
00056   int i, j;
00057   unsigned sfLength, origTotABsize, adjustment;
00058   MP3SideInfo::gr_info_s_t* gr;
00059 
00060   /* First, Huffman-decode each part of the segment's main data,
00061      to see at which bit-boundaries the samples appear:
00062    */
00063   MP3HuffmanEncodingInfo hei;
00064 
00065   ++debugCount;
00066 #ifdef DEBUG
00067   fprintf(stderr, "usifh-start: p23L0: %d, p23L1: %d\n", p23L0, p23L1);
00068 #endif
00069 
00070   /* Process granule 0 */
00071   {
00072     gr = &(sideInfo.ch[0].gr[0]);
00073     origTotABsize = gr->part2_3_length;
00074 
00075     MP3HuffmanDecode(gr, isMPEG2, mainDataPtr, 0, origTotABsize, sfLength, hei);
00076 
00077     /* Begin by computing new sizes for parts a & b (& their truncations) */
00078 #ifdef DEBUG
00079     fprintf(stderr, "usifh-0: %d, %d:%d, %d:%d, %d:%d, %d:%d, %d:%d\n",
00080             hei.numSamples,
00081             sfLength/8, sfLength%8,
00082             hei.reg1Start/8, hei.reg1Start%8,
00083             hei.reg2Start/8, hei.reg2Start%8,
00084             hei.bigvalStart/8, hei.bigvalStart%8,
00085             origTotABsize/8, origTotABsize%8);
00086 #endif
00087     if (p23L0 < sfLength) {
00088       /* We can't use this, so give it all to the next granule: */
00089       p23L1 += p23L0;
00090       p23L0 = 0;
00091     }
00092 
00093     part23Length0a = hei.bigvalStart;
00094     part23Length0b = origTotABsize - hei.bigvalStart;
00095     part23Length0aTruncation = part23Length0bTruncation = 0;
00096     if (origTotABsize > p23L0) {
00097       /* We need to shorten one or both of fields a & b */
00098       unsigned truncation = origTotABsize - p23L0;
00099 #ifdef TRUNC_FAIRLY
00100       part23Length0aTruncation  = (truncation*(part23Length0a-sfLength))
00101                                   /(origTotABsize-sfLength);
00102       part23Length0bTruncation = truncation - part23Length0aTruncation;
00103 #endif
00104 #ifdef TRUNC_FAVORa
00105       part23Length0bTruncation
00106         = (truncation > part23Length0b) ? part23Length0b : truncation;
00107       part23Length0aTruncation = truncation - part23Length0bTruncation;
00108 #endif
00109 #ifdef TRUNC_FAVORb
00110       part23Length0aTruncation  = (truncation > part23Length0a-sfLength)
00111         ? (part23Length0a-sfLength) : truncation;
00112       part23Length0bTruncation = truncation - part23Length0aTruncation;
00113 #endif
00114     }
00115     /* ASSERT:  part23Length0xTruncation <= part23Length0x */
00116     part23Length0a -= part23Length0aTruncation;
00117     part23Length0b -= part23Length0bTruncation;
00118 #ifdef DEBUG
00119     fprintf(stderr, "usifh-0: interim sizes: %d (%d), %d (%d)\n",
00120             part23Length0a, part23Length0aTruncation,
00121             part23Length0b, part23Length0bTruncation);
00122 #endif
00123 
00124     /* Adjust these new lengths so they end on sample bit boundaries: */
00125     for (i = 0; i < (int)hei.numSamples; ++i) {
00126       if (hei.allBitOffsets[i] == part23Length0a) break;
00127       else if (hei.allBitOffsets[i] > part23Length0a) {--i; break;}
00128     }
00129     if (i < 0) { /* should happen only if we couldn't fit sfLength */
00130       i = 0; adjustment = 0;
00131     } else {
00132       adjustment = part23Length0a - hei.allBitOffsets[i];
00133     }
00134 #ifdef DEBUG
00135     fprintf(stderr, "%d usifh-0: adjustment 1: %d\n", debugCount, adjustment);
00136 #endif
00137     part23Length0a -= adjustment;
00138     part23Length0aTruncation += adjustment;
00139     /* Assign the bits we just shaved to field b and granule 1: */
00140     if (part23Length0bTruncation < adjustment) {
00141       p23L1 += (adjustment - part23Length0bTruncation);
00142       adjustment = part23Length0bTruncation;
00143     }
00144     part23Length0b += adjustment;
00145     part23Length0bTruncation -= adjustment;
00146     for (j = i; j < (int)hei.numSamples; ++j) {
00147       if (hei.allBitOffsets[j]
00148           == part23Length0a + part23Length0aTruncation + part23Length0b)
00149         break;
00150       else if (hei.allBitOffsets[j]
00151           > part23Length0a + part23Length0aTruncation + part23Length0b)
00152         {--j; break;}
00153     }
00154     if (j < 0) { /* should happen only if we couldn't fit sfLength */
00155       j = 0; adjustment = 0;
00156     } else {
00157       adjustment = part23Length0a+part23Length0aTruncation+part23Length0b
00158                    - hei.allBitOffsets[j];
00159     }
00160 #ifdef DEBUG
00161     fprintf(stderr, "%d usifh-0: adjustment 2: %d\n", debugCount, adjustment);
00162 #endif
00163     if (adjustment > part23Length0b) adjustment = part23Length0b; /*sanity*/
00164     part23Length0b -= adjustment;
00165     part23Length0bTruncation += adjustment;
00166     /* Assign the bits we just shaved to granule 1 */
00167     p23L1 += adjustment;
00168 
00169     if (part23Length0aTruncation > 0) {
00170       /* Change the granule's 'big_values' field to reflect the truncation */
00171       gr->big_values = i;
00172     }
00173   }
00174 
00175   /* Process granule 1 (MPEG-1 only) */
00176 
00177   if (isMPEG2) {
00178     part23Length1a = part23Length1b = 0;
00179     part23Length1aTruncation = part23Length1bTruncation = 0;
00180   } else {
00181     unsigned granule1Offset
00182       = origTotABsize + sideInfo.ch[1].gr[0].part2_3_length;
00183 
00184     gr = &(sideInfo.ch[0].gr[1]);
00185     origTotABsize = gr->part2_3_length;
00186 
00187     MP3HuffmanDecode(gr, isMPEG2, mainDataPtr, granule1Offset,
00188                      origTotABsize, sfLength, hei);
00189 
00190     /* Begin by computing new sizes for parts a & b (& their truncations) */
00191 #ifdef DEBUG
00192     fprintf(stderr, "usifh-1: %d, %d:%d, %d:%d, %d:%d, %d:%d, %d:%d\n",
00193             hei.numSamples,
00194             sfLength/8, sfLength%8,
00195             hei.reg1Start/8, hei.reg1Start%8,
00196             hei.reg2Start/8, hei.reg2Start%8,
00197             hei.bigvalStart/8, hei.bigvalStart%8,
00198             origTotABsize/8, origTotABsize%8);
00199 #endif
00200     if (p23L1 < sfLength) {
00201       /* We can't use this, so give up on this granule: */
00202       p23L1 = 0;
00203     }
00204 
00205     part23Length1a = hei.bigvalStart;
00206     part23Length1b = origTotABsize - hei.bigvalStart;
00207     part23Length1aTruncation = part23Length1bTruncation = 0;
00208     if (origTotABsize > p23L1) {
00209       /* We need to shorten one or both of fields a & b */
00210       unsigned truncation = origTotABsize - p23L1;
00211 #ifdef TRUNC_FAIRLY
00212       part23Length1aTruncation  = (truncation*(part23Length1a-sfLength))
00213                                   /(origTotABsize-sfLength);
00214       part23Length1bTruncation = truncation - part23Length1aTruncation;
00215 #endif
00216 #ifdef TRUNC_FAVORa
00217       part23Length1bTruncation
00218         = (truncation > part23Length1b) ? part23Length1b : truncation;
00219       part23Length1aTruncation = truncation - part23Length1bTruncation;
00220 #endif
00221 #ifdef TRUNC_FAVORb
00222       part23Length1aTruncation  = (truncation > part23Length1a-sfLength)
00223         ? (part23Length1a-sfLength) : truncation;
00224       part23Length1bTruncation = truncation - part23Length1aTruncation;
00225 #endif
00226     }
00227     /* ASSERT:  part23Length1xTruncation <= part23Length1x */
00228     part23Length1a -= part23Length1aTruncation;
00229     part23Length1b -= part23Length1bTruncation;
00230 #ifdef DEBUG
00231     fprintf(stderr, "usifh-1: interim sizes: %d (%d), %d (%d)\n",
00232             part23Length1a, part23Length1aTruncation,
00233             part23Length1b, part23Length1bTruncation);
00234 #endif
00235 
00236     /* Adjust these new lengths so they end on sample bit boundaries: */
00237     for (i = 0; i < (int)hei.numSamples; ++i) {
00238       if (hei.allBitOffsets[i] == part23Length1a) break;
00239       else if (hei.allBitOffsets[i] > part23Length1a) {--i; break;}
00240     }
00241     if (i < 0) { /* should happen only if we couldn't fit sfLength */
00242       i = 0; adjustment = 0;
00243     } else {
00244       adjustment = part23Length1a - hei.allBitOffsets[i];
00245     }
00246 #ifdef DEBUG
00247     fprintf(stderr, "%d usifh-1: adjustment 0: %d\n", debugCount, adjustment);
00248 #endif
00249     part23Length1a -= adjustment;
00250     part23Length1aTruncation += adjustment;
00251     /* Assign the bits we just shaved to field b: */
00252     if (part23Length1bTruncation < adjustment) {
00253       adjustment = part23Length1bTruncation;
00254     }
00255     part23Length1b += adjustment;
00256     part23Length1bTruncation -= adjustment;
00257     for (j = i; j < (int)hei.numSamples; ++j) {
00258       if (hei.allBitOffsets[j]
00259           == part23Length1a + part23Length1aTruncation + part23Length1b)
00260         break;
00261       else if (hei.allBitOffsets[j]
00262           > part23Length1a + part23Length1aTruncation + part23Length1b)
00263         {--j; break;}
00264     }
00265     if (j < 0) { /* should happen only if we couldn't fit sfLength */
00266       j = 0; adjustment = 0;
00267     } else {
00268       adjustment = part23Length1a+part23Length1aTruncation+part23Length1b
00269                    - hei.allBitOffsets[j];
00270     }
00271 #ifdef DEBUG
00272     fprintf(stderr, "%d usifh-1: adjustment 1: %d\n", debugCount, adjustment);
00273 #endif
00274     if (adjustment > part23Length1b) adjustment = part23Length1b; /*sanity*/
00275     part23Length1b -= adjustment;
00276     part23Length1bTruncation += adjustment;
00277 
00278     if (part23Length1aTruncation > 0) {
00279       /* Change the granule's 'big_values' field to reflect the truncation */
00280       gr->big_values = i;
00281     }
00282   }
00283 #ifdef DEBUG
00284   fprintf(stderr, "usifh-end, new vals: %d (%d), %d (%d), %d (%d), %d (%d)\n",
00285           part23Length0a, part23Length0aTruncation,
00286           part23Length0b, part23Length0bTruncation,
00287           part23Length1a, part23Length1aTruncation,
00288           part23Length1b, part23Length1bTruncation);
00289 #endif
00290 }
00291 
00292 static void rsf_getline(char* line, unsigned max, unsigned char**fi) {
00293   unsigned i;
00294   for (i = 0; i < max; ++i) {
00295     line[i] = *(*fi)++;
00296     if (line[i] == '\n') {
00297       line[i++] = '\0';
00298       return;
00299     }
00300   }
00301   line[i] = '\0';
00302 }
00303 
00304 static void rsfscanf(unsigned char **fi, unsigned int* v) {
00305   while (sscanf((char*)*fi, "%x", v) == 0) {
00306     /* skip past the next '\0' */
00307     while (*(*fi)++ != '\0') {}
00308   }
00309 
00310   /* skip past any white-space before the value: */
00311   while (*(*fi) <= ' ') ++(*fi);
00312 
00313   /* skip past the value: */
00314   while (*(*fi) > ' ') ++(*fi);
00315 }
00316 
00317 #define HUFFBITS unsigned long int
00318 #define SIZEOF_HUFFBITS 4
00319 #define HTN     34
00320 #define MXOFF   250
00321 
00322 struct huffcodetab {
00323   char tablename[3];    /*string, containing table_description  */
00324   unsigned int xlen;    /*max. x-index+                         */
00325   unsigned int ylen;    /*max. y-index+                         */
00326   unsigned int linbits; /*number of linbits                     */
00327   unsigned int linmax;  /*max number to be stored in linbits    */
00328   int ref;              /*a positive value indicates a reference*/
00329   HUFFBITS *table;      /*pointer to array[xlen][ylen]          */
00330   unsigned char *hlen;  /*pointer to array[xlen][ylen]          */
00331   unsigned char(*val)[2];/*decoder tree                         */
00332   unsigned int treelen; /*length of decoder tree                */
00333 };
00334 
00335 static struct huffcodetab rsf_ht[HTN]; // array of all huffcodetable headers
00336                                 /* 0..31 Huffman code table 0..31       */
00337                                 /* 32,33 count1-tables                  */
00338 
00339 /* read the huffman decoder table */
00340 static int read_decoder_table(unsigned char* fi) {
00341   int n,i,nn,t;
00342   unsigned int v0,v1;
00343   char command[100],line[100];
00344   for (n=0;n<HTN;n++) {
00345     rsf_ht[n].table = NULL;
00346     rsf_ht[n].hlen = NULL;
00347 
00348     /* .table number treelen xlen ylen linbits */
00349     do {
00350       rsf_getline(line,99,&fi);
00351     } while ((line[0] == '#') || (line[0] < ' '));
00352 
00353     sscanf(line,"%s %s %u %u %u %u",command,rsf_ht[n].tablename,
00354            &rsf_ht[n].treelen, &rsf_ht[n].xlen, &rsf_ht[n].ylen, &rsf_ht[n].linbits);
00355     if (strcmp(command,".end")==0)
00356       return n;
00357     else if (strcmp(command,".table")!=0) {
00358 #ifdef DEBUG
00359       fprintf(stderr,"huffman table %u data corrupted\n",n);
00360 #endif
00361       return -1;
00362     }
00363     rsf_ht[n].linmax = (1<<rsf_ht[n].linbits)-1;
00364 
00365     sscanf(rsf_ht[n].tablename,"%u",&nn);
00366     if (nn != n) {
00367 #ifdef DEBUG
00368       fprintf(stderr,"wrong table number %u\n",n);
00369 #endif
00370       return(-2);
00371     }
00372     do {
00373       rsf_getline(line,99,&fi);
00374     } while ((line[0] == '#') || (line[0] < ' '));
00375 
00376     sscanf(line,"%s %u",command,&t);
00377     if (strcmp(command,".reference")==0) {
00378       rsf_ht[n].ref   = t;
00379       rsf_ht[n].val   = rsf_ht[t].val;
00380       rsf_ht[n].treelen  = rsf_ht[t].treelen;
00381       if ( (rsf_ht[n].xlen != rsf_ht[t].xlen) ||
00382            (rsf_ht[n].ylen != rsf_ht[t].ylen)  ) {
00383 #ifdef DEBUG
00384         fprintf(stderr,"wrong table %u reference\n",n);
00385 #endif
00386         return (-3);
00387       };
00388       while ((line[0] == '#') || (line[0] < ' ') ) {
00389         rsf_getline(line,99,&fi);
00390       }
00391     }
00392     else if (strcmp(command,".treedata")==0) {
00393       rsf_ht[n].ref  = -1;
00394       rsf_ht[n].val = (unsigned char (*)[2])
00395         new unsigned char[2*(rsf_ht[n].treelen)];
00396       if ((rsf_ht[n].val == NULL) && ( rsf_ht[n].treelen != 0 )){
00397 #ifdef DEBUG
00398         fprintf(stderr, "heaperror at table %d\n",n);
00399 #endif
00400         abort();
00401       }
00402       for (i=0;(unsigned)i<rsf_ht[n].treelen; i++) {
00403         rsfscanf(&fi, &v0);
00404         rsfscanf(&fi, &v1);
00405 /*replaces        fscanf(fi,"%x %x",&v0, &v1);*/
00406         rsf_ht[n].val[i][0]=(unsigned char)v0;
00407         rsf_ht[n].val[i][1]=(unsigned char)v1;
00408       }
00409       rsf_getline(line,99,&fi); /* read the rest of the line */
00410     }
00411     else {
00412 #ifdef DEBUG
00413       fprintf(stderr,"huffman decodertable error at table %d\n",n);
00414 #endif
00415     }
00416   }
00417   return n;
00418 }
00419 
00420 static void initialize_huffman() {
00421   static Boolean huffman_initialized = False;
00422 
00423    if (huffman_initialized) return;
00424 
00425    if (read_decoder_table(huffdec) != HTN) {
00426 #ifdef DEBUG
00427       fprintf(stderr,"decoder table read error\n");
00428 #endif
00429       abort();
00430       }
00431    huffman_initialized = True;
00432 }
00433 
00434 static unsigned char const slen[2][16] = {
00435   {0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4},
00436   {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3}
00437 };
00438 
00439 static unsigned char const stab[3][6][4] = {
00440   { { 6, 5, 5,5 } , { 6, 5, 7,3 } , { 11,10,0,0} ,
00441     { 7, 7, 7,0 } , { 6, 6, 6,3 } , {  8, 8,5,0} } ,
00442   { { 9, 9, 9,9 } , { 9, 9,12,6 } , { 18,18,0,0} ,
00443     {12,12,12,0 } , {12, 9, 9,6 } , { 15,12,9,0} } ,
00444   { { 6, 9, 9,9 } , { 6, 9,12,6 } , { 15,18,0,0} ,
00445     { 6,15,12,0 } , { 6,12, 9,6 } , {  6,18,9,0} }
00446 };
00447 
00448 static unsigned rsf_get_scale_factors_1(MP3SideInfo::gr_info_s_t *gr_info) {
00449    int numbits;
00450    int num0 = slen[0][gr_info->scalefac_compress];
00451    int num1 = slen[1][gr_info->scalefac_compress];
00452 
00453     if (gr_info->block_type == 2)
00454     {
00455       numbits = (num0 + num1) * 18;
00456 
00457       if (gr_info->mixed_block_flag) {
00458          numbits -= num0; /* num0 * 17 + num1 * 18 */
00459       }
00460     }
00461     else
00462     {
00463       int scfsi = gr_info->scfsi;
00464 
00465       if(scfsi < 0) { /* scfsi < 0 => granule == 0 */
00466          numbits = (num0 + num1) * 10 + num0;
00467       }
00468       else {
00469         numbits = 0;
00470         if(!(scfsi & 0x8)) {
00471           numbits += num0 * 6;
00472         }
00473         else {
00474         }
00475 
00476         if(!(scfsi & 0x4)) {
00477           numbits += num0 * 5;
00478         }
00479         else {
00480         }
00481 
00482         if(!(scfsi & 0x2)) {
00483           numbits += num1 * 5;
00484         }
00485         else {
00486         }
00487 
00488         if(!(scfsi & 0x1)) {
00489           numbits += num1 * 5;
00490         }
00491         else {
00492         }
00493       }
00494     }
00495 
00496     return numbits;
00497 }
00498 
00499 extern unsigned n_slen2[];
00500 extern unsigned i_slen2[];
00501 
00502 static unsigned rsf_get_scale_factors_2(MP3SideInfo::gr_info_s_t *gr_info) {
00503   unsigned char const* pnt;
00504   int i;
00505   unsigned int slen;
00506   int n = 0;
00507   int numbits = 0;
00508 
00509   slen = n_slen2[gr_info->scalefac_compress];
00510 
00511   gr_info->preflag = (slen>>15) & 0x1;
00512 
00513   n = 0;
00514   if( gr_info->block_type == 2 ) {
00515     n++;
00516     if(gr_info->mixed_block_flag)
00517       n++;
00518   }
00519 
00520   pnt = stab[n][(slen>>12)&0x7];
00521 
00522   for(i=0;i<4;i++) {
00523     int num = slen & 0x7;
00524     slen >>= 3;
00525     numbits += pnt[i] * num;
00526   }
00527 
00528   return numbits;
00529 }
00530 
00531 static unsigned getScaleFactorsLength(MP3SideInfo::gr_info_s_t* gr,
00532                                       Boolean isMPEG2) {
00533   return isMPEG2 ? rsf_get_scale_factors_2(gr)
00534                  : rsf_get_scale_factors_1(gr);
00535 }
00536 
00537 static int rsf_huffman_decoder(BitVector& bv,
00538                                struct huffcodetab const* h,
00539                                int* x, int* y, int* v, int* w); // forward
00540 
00541 void MP3HuffmanDecode(MP3SideInfo::gr_info_s_t* gr, int isMPEG2,
00542                       unsigned char const* fromBasePtr,
00543                       unsigned fromBitOffset, unsigned fromLength,
00544                       unsigned& scaleFactorsLength,
00545                       MP3HuffmanEncodingInfo& hei) {
00546    unsigned i;
00547    int x, y, v, w;
00548    struct huffcodetab *h;
00549    BitVector bv((unsigned char*)fromBasePtr, fromBitOffset, fromLength);
00550 
00551    /* Compute the size of the scale factors (& also advance bv): */
00552    scaleFactorsLength = getScaleFactorsLength(gr, isMPEG2);
00553    bv.skipBits(scaleFactorsLength);
00554 
00555    initialize_huffman();
00556 
00557    hei.reg1Start = hei.reg2Start = hei.numSamples = 0;
00558 
00559    /* Read bigvalues area. */
00560    if (gr->big_values < gr->region1start + gr->region2start) {
00561      gr->big_values = gr->region1start + gr->region2start; /* sanity check */
00562    }
00563    for (i = 0; i < gr->big_values; ++i) {
00564      if (i < gr->region1start) {
00565        /* in region 0 */
00566        h = &rsf_ht[gr->table_select[0]];
00567      } else if (i < gr->region2start) {
00568        /* in region 1 */
00569        h = &rsf_ht[gr->table_select[1]];
00570        if (hei.reg1Start == 0) {
00571          hei.reg1Start = bv.curBitIndex();
00572        }
00573      } else {
00574        /* in region 2 */
00575        h = &rsf_ht[gr->table_select[2]];
00576        if (hei.reg2Start == 0) {
00577          hei.reg2Start = bv.curBitIndex();
00578        }
00579      }
00580 
00581      hei.allBitOffsets[i] = bv.curBitIndex();
00582      rsf_huffman_decoder(bv, h, &x, &y, &v, &w);
00583      if (hei.decodedValues != NULL) {
00584        // Record the decoded values:
00585        unsigned* ptr = &hei.decodedValues[4*i];
00586        ptr[0] = x; ptr[1] = y; ptr[2] = v; ptr[3] = w;
00587      }
00588    }
00589    hei.bigvalStart = bv.curBitIndex();
00590 
00591    /* Read count1 area. */
00592    h = &rsf_ht[gr->count1table_select+32];
00593    while (bv.curBitIndex() < bv.totNumBits() &&  i < SSLIMIT*SBLIMIT) {
00594      hei.allBitOffsets[i] = bv.curBitIndex();
00595      rsf_huffman_decoder(bv, h, &x, &y, &v, &w);
00596      if (hei.decodedValues != NULL) {
00597        // Record the decoded values:
00598        unsigned* ptr = &hei.decodedValues[4*i];
00599        ptr[0] = x; ptr[1] = y; ptr[2] = v; ptr[3] = w;
00600      }
00601      ++i;
00602    }
00603 
00604    hei.allBitOffsets[i] = bv.curBitIndex();
00605    hei.numSamples = i;
00606 }
00607 
00608 HUFFBITS dmask = 1 << (SIZEOF_HUFFBITS*8-1);
00609 unsigned int hs = SIZEOF_HUFFBITS*8;
00610 
00611 /* do the huffman-decoding                                              */
00612 static int rsf_huffman_decoder(BitVector& bv,
00613                 struct huffcodetab const* h, // ptr to huffman code record
00614                         /* unsigned */ int *x, // returns decoded x value
00615                         /* unsigned */ int *y,  // returns decoded y value
00616                                int* v, int* w) {
00617   HUFFBITS level;
00618   unsigned point = 0;
00619   int error = 1;
00620   level     = dmask;
00621   *x = *y = *v = *w = 0;
00622   if (h->val == NULL) return 2;
00623 
00624   /* table 0 needs no bits */
00625   if (h->treelen == 0) return 0;
00626 
00627   /* Lookup in Huffman table. */
00628 
00629   do {
00630     if (h->val[point][0]==0) {   /*end of tree*/
00631       *x = h->val[point][1] >> 4;
00632       *y = h->val[point][1] & 0xf;
00633 
00634       error = 0;
00635       break;
00636     }
00637     if (bv.get1Bit()) {
00638       while (h->val[point][1] >= MXOFF) point += h->val[point][1];
00639       point += h->val[point][1];
00640     }
00641     else {
00642       while (h->val[point][0] >= MXOFF) point += h->val[point][0];
00643       point += h->val[point][0];
00644     }
00645     level >>= 1;
00646   } while (level  || (point < h->treelen) );
00648 
00649   /* Check for error. */
00650 
00651   if (error) { /* set x and y to a medium value as a simple concealment */
00652     printf("Illegal Huffman code in data.\n");
00653     *x = ((h->xlen-1) << 1);
00654     *y = ((h->ylen-1) << 1);
00655   }
00656 
00657   /* Process sign encodings for quadruples tables. */
00658 
00659   if (h->tablename[0] == '3'
00660       && (h->tablename[1] == '2' || h->tablename[1] == '3')) {
00661      *v = (*y>>3) & 1;
00662      *w = (*y>>2) & 1;
00663      *x = (*y>>1) & 1;
00664      *y = *y & 1;
00665 
00666      if (*v)
00667         if (bv.get1Bit() == 1) *v = -*v;
00668      if (*w)
00669         if (bv.get1Bit() == 1) *w = -*w;
00670      if (*x)
00671         if (bv.get1Bit() == 1) *x = -*x;
00672      if (*y)
00673         if (bv.get1Bit() == 1) *y = -*y;
00674      }
00675 
00676   /* Process sign and escape encodings for dual tables. */
00677 
00678   else {
00679      if (h->linbits)
00680        if ((h->xlen-1) == (unsigned)*x)
00681          *x += bv.getBits(h->linbits);
00682      if (*x)
00683         if (bv.get1Bit() == 1) *x = -*x;
00684      if (h->linbits)
00685        if ((h->ylen-1) == (unsigned)*y)
00686          *y += bv.getBits(h->linbits);
00687      if (*y)
00688         if (bv.get1Bit() == 1) *y = -*y;
00689   }
00690 
00691   return error;
00692 }
00693 
00694 #ifdef DO_HUFFMAN_ENCODING
00695 inline int getNextSample(unsigned char const*& fromPtr) {
00696   int sample
00697 #ifdef FOUR_BYTE_SAMPLES
00698     = (fromPtr[0]<<24) | (fromPtr[1]<<16) | (fromPtr[2]<<8) | fromPtr[3];
00699 #else
00700 #ifdef TWO_BYTE_SAMPLES
00701     = (fromPtr[0]<<8) | fromPtr[1];
00702 #else
00703     // ONE_BYTE_SAMPLES
00704     = fromPtr[0];
00705 #endif
00706 #endif
00707   fromPtr += BYTES_PER_SAMPLE_VALUE;
00708   return sample;
00709 }
00710 
00711 static void rsf_huffman_encoder(BitVector& bv,
00712                                 struct huffcodetab* h,
00713                                 int x, int y, int v, int w); // forward
00714 
00715 unsigned MP3HuffmanEncode(MP3SideInfo::gr_info_s_t const* gr,
00716                           unsigned char const* fromPtr,
00717                           unsigned char* toPtr, unsigned toBitOffset,
00718                           unsigned numHuffBits) {
00719    unsigned i;
00720    struct huffcodetab *h;
00721    int x, y, v, w;
00722    BitVector bv(toPtr, toBitOffset, numHuffBits);
00723 
00724    initialize_huffman();
00725 
00726    // Encode big_values area:
00727    unsigned big_values = gr->big_values;
00728    if (big_values < gr->region1start + gr->region2start) {
00729      big_values = gr->region1start + gr->region2start; /* sanity check */
00730    }
00731    for (i = 0; i < big_values; ++i) {
00732      if (i < gr->region1start) {
00733        /* in region 0 */
00734        h = &rsf_ht[gr->table_select[0]];
00735      } else if (i < gr->region2start) {
00736        /* in region 1 */
00737        h = &rsf_ht[gr->table_select[1]];
00738      } else {
00739        /* in region 2 */
00740        h = &rsf_ht[gr->table_select[2]];
00741      }
00742 
00743      x = getNextSample(fromPtr);
00744      y = getNextSample(fromPtr);
00745      v = getNextSample(fromPtr);
00746      w = getNextSample(fromPtr);
00747      rsf_huffman_encoder(bv, h, x, y, v, w);
00748    }
00749 
00750    // Encode count1 area:
00751    h = &rsf_ht[gr->count1table_select+32];
00752    while (bv.curBitIndex() < bv.totNumBits() &&  i < SSLIMIT*SBLIMIT) {
00753      x = getNextSample(fromPtr);
00754      y = getNextSample(fromPtr);
00755      v = getNextSample(fromPtr);
00756      w = getNextSample(fromPtr);
00757      rsf_huffman_encoder(bv, h, x, y, v, w);
00758      ++i;
00759    }
00760 
00761    return i;
00762 }
00763 
00764 static Boolean lookupHuffmanTableEntry(struct huffcodetab const* h,
00765                                        HUFFBITS bits, unsigned bitsLength,
00766                                        unsigned char& xy) {
00767   unsigned point = 0;
00768   unsigned mask = 1;
00769   unsigned numBitsTestedSoFar = 0;
00770   do {
00771     if (h->val[point][0]==0) { // end of tree
00772       xy = h->val[point][1];
00773       if (h->hlen[xy] == 0) { // this entry hasn't already been used
00774         h->table[xy] = bits;
00775         h->hlen[xy] = bitsLength;
00776         return True;
00777       } else { // this entry has already been seen
00778         return False;
00779       }
00780     }
00781 
00782     if (numBitsTestedSoFar++ == bitsLength) {
00783       // We don't yet have enough bits for this prefix
00784       return False;
00785     }
00786     if (bits&mask) {
00787       while (h->val[point][1] >= MXOFF) point += h->val[point][1];
00788       point += h->val[point][1];
00789     } else {
00790       while (h->val[point][0] >= MXOFF) point += h->val[point][0];
00791       point += h->val[point][0];
00792     }
00793     mask <<= 1;
00794   } while (mask || (point < h->treelen));
00795 
00796   return False;
00797 }
00798 
00799 static void buildHuffmanEncodingTable(struct huffcodetab* h) {
00800   h->table = new unsigned long[256];
00801   h->hlen = new unsigned char[256];
00802   if (h->table == NULL || h->hlen == NULL) { h->table = NULL; return; }
00803   for (unsigned i = 0; i < 256; ++i) {
00804     h->table[i] = 0; h->hlen[i] = 0;
00805   }
00806 
00807   // Look up entries for each possible bit sequence length:
00808   unsigned maxNumEntries = h->xlen * h->ylen;
00809   unsigned numEntries = 0;
00810   unsigned powerOf2 = 1;
00811   for (unsigned bitsLength = 1;
00812        bitsLength <= 8*SIZEOF_HUFFBITS; ++bitsLength) {
00813     powerOf2 *= 2;
00814     for (HUFFBITS bits = 0; bits < powerOf2; ++bits) {
00815       // Find the table value - if any - for 'bits' (length 'bitsLength'):
00816       unsigned char xy;
00817       if (lookupHuffmanTableEntry(h, bits, bitsLength, xy)) {
00818         ++numEntries;
00819         if (numEntries == maxNumEntries) return; // we're done
00820       }
00821     }
00822   }
00823 #ifdef DEBUG
00824   fprintf(stderr, "Didn't find enough entries!\n"); // shouldn't happen
00825 #endif
00826 }
00827 
00828 static void lookupXYandPutBits(BitVector& bv, struct huffcodetab const* h,
00829                                unsigned char xy) {
00830   HUFFBITS bits = h->table[xy];
00831   unsigned bitsLength = h->hlen[xy];
00832 
00833   // Note that "bits" is in reverse order, so read them from right-to-left:
00834   while (bitsLength-- > 0) {
00835     bv.put1Bit(bits&0x00000001);
00836     bits >>= 1;
00837   }
00838 }
00839 
00840 static void putLinbits(BitVector& bv, struct huffcodetab const* h,
00841                        HUFFBITS bits) {
00842   bv.putBits(bits, h->linbits);
00843 }
00844 
00845 static void rsf_huffman_encoder(BitVector& bv,
00846                                 struct huffcodetab* h,
00847                                 int x, int y, int v, int w) {
00848   if (h->val == NULL) return;
00849 
00850   /* table 0 produces no bits */
00851   if (h->treelen == 0) return;
00852 
00853   if (h->table == NULL) {
00854     // We haven't yet built the encoding array for this table; do it now:
00855     buildHuffmanEncodingTable(h);
00856     if (h->table == NULL) return;
00857   }
00858 
00859   Boolean xIsNeg = False, yIsNeg = False, vIsNeg = False, wIsNeg = False;
00860   unsigned char xy;
00861 
00862 #ifdef FOUR_BYTE_SAMPLES
00863 #else
00864 #ifdef TWO_BYTE_SAMPLES
00865   // Convert 2-byte negative numbers to their 4-byte equivalents:
00866   if (x&0x8000) x |= 0xFFFF0000;
00867   if (y&0x8000) y |= 0xFFFF0000;
00868   if (v&0x8000) v |= 0xFFFF0000;
00869   if (w&0x8000) w |= 0xFFFF0000;
00870 #else
00871   // ONE_BYTE_SAMPLES
00872   // Convert 1-byte negative numbers to their 4-byte equivalents:
00873   if (x&0x80) x |= 0xFFFFFF00;
00874   if (y&0x80) y |= 0xFFFFFF00;
00875   if (v&0x80) v |= 0xFFFFFF00;
00876   if (w&0x80) w |= 0xFFFFFF00;
00877 #endif
00878 #endif
00879 
00880   if (h->tablename[0] == '3'
00881       && (h->tablename[1] == '2' || h->tablename[1] == '3')) {// quad tables
00882     if (x < 0) { xIsNeg = True; x = -x; }
00883     if (y < 0) { yIsNeg = True; y = -y; }
00884     if (v < 0) { vIsNeg = True; v = -v; }
00885     if (w < 0) { wIsNeg = True; w = -w; }
00886 
00887     // Sanity check: x,y,v,w must all be 0 or 1:
00888     if (x>1 || y>1 || v>1 || w>1) {
00889 #ifdef DEBUG
00890       fprintf(stderr, "rsf_huffman_encoder quad sanity check fails: %x,%x,%x,%x\n", x, y, v, w);
00891 #endif
00892     }
00893 
00894     xy = (v<<3)|(w<<2)|(x<<1)|y;
00895     lookupXYandPutBits(bv, h, xy);
00896 
00897     if (v) bv.put1Bit(vIsNeg);
00898     if (w) bv.put1Bit(wIsNeg);
00899     if (x) bv.put1Bit(xIsNeg);
00900     if (y) bv.put1Bit(yIsNeg);
00901   } else { // dual tables
00902     // Sanity check: v and w must be 0:
00903     if (v != 0 || w != 0) {
00904 #ifdef DEBUG
00905       fprintf(stderr, "rsf_huffman_encoder dual sanity check 1 fails: %x,%x,%x,%x\n", x, y, v, w);
00906 #endif
00907     }
00908 
00909     if (x < 0) { xIsNeg = True; x = -x; }
00910     if (y < 0) { yIsNeg = True; y = -y; }
00911 
00912     // Sanity check: x and y must be <= 255:
00913     if (x > 255 || y > 255) {
00914 #ifdef DEBUG
00915       fprintf(stderr, "rsf_huffman_encoder dual sanity check 2 fails: %x,%x,%x,%x\n", x, y, v, w);
00916 #endif
00917     }
00918 
00919     int xl1 = h->xlen-1;
00920     int yl1 = h->ylen-1;
00921     unsigned linbitsX = 0; unsigned linbitsY = 0;
00922 
00923     if (((x < xl1) || (xl1 == 0)) && (y < yl1)) {
00924       // normal case
00925       xy = (x<<4)|y;
00926       lookupXYandPutBits(bv, h, xy);
00927       if (x) bv.put1Bit(xIsNeg);
00928       if (y) bv.put1Bit(yIsNeg);
00929     } else if (x >= xl1) {
00930       linbitsX = (unsigned)(x - xl1);
00931       if (linbitsX > h->linmax) {
00932 #ifdef DEBUG
00933         fprintf(stderr,"warning: Huffman X table overflow\n");
00934 #endif
00935         linbitsX = h->linmax;
00936       };
00937 
00938       if (y >= yl1) {
00939         xy = (xl1<<4)|yl1;
00940         lookupXYandPutBits(bv, h, xy);
00941         linbitsY = (unsigned)(y - yl1);
00942         if (linbitsY > h->linmax) {
00943 #ifdef DEBUG
00944           fprintf(stderr,"warning: Huffman Y table overflow\n");
00945 #endif
00946           linbitsY = h->linmax;
00947         };
00948 
00949         if (h->linbits) putLinbits(bv, h, linbitsX);
00950         if (x) bv.put1Bit(xIsNeg);
00951         if (h->linbits) putLinbits(bv, h, linbitsY);
00952         if (y) bv.put1Bit(yIsNeg);
00953       } else { /* x >= h->xlen, y < h->ylen */
00954         xy = (xl1<<4)|y;
00955         lookupXYandPutBits(bv, h, xy);
00956         if (h->linbits) putLinbits(bv, h, linbitsX);
00957         if (x) bv.put1Bit(xIsNeg);
00958         if (y) bv.put1Bit(yIsNeg);
00959       }
00960     } else { /* ((x < h->xlen) && (y >= h->ylen)) */
00961       xy = (x<<4)|yl1;
00962       lookupXYandPutBits(bv, h, xy);
00963       linbitsY = y-yl1;
00964       if (linbitsY > h->linmax) {
00965 #ifdef DEBUG
00966         fprintf(stderr,"warning: Huffman Y table overflow\n");
00967 #endif
00968         linbitsY = h->linmax;
00969       };
00970       if (x) bv.put1Bit(xIsNeg);
00971       if (h->linbits) putLinbits(bv, h, linbitsY);
00972       if (y) bv.put1Bit(yIsNeg);
00973     }
00974   }
00975 }
00976 #endif

Generated on Thu May 17 07:11:46 2012 for live by  doxygen 1.5.2