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