00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00040
00041 static unsigned debugCount = 0;
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
00061
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
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
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
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
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
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
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) {
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
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) {
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;
00164 part23Length0b -= adjustment;
00165 part23Length0bTruncation += adjustment;
00166
00167 p23L1 += adjustment;
00168
00169 if (part23Length0aTruncation > 0) {
00170
00171 gr->big_values = i;
00172 }
00173 }
00174
00175
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
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
00202 p23L1 = 0;
00203 }
00204
00205 part23Length1a = hei.bigvalStart;
00206 part23Length1b = origTotABsize - hei.bigvalStart;
00207 part23Length1aTruncation = part23Length1bTruncation = 0;
00208 if (origTotABsize > p23L1) {
00209
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
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
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) {
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
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) {
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;
00275 part23Length1b -= adjustment;
00276 part23Length1bTruncation += adjustment;
00277
00278 if (part23Length1aTruncation > 0) {
00279
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
00307 while (*(*fi)++ != '\0') {}
00308 }
00309
00310
00311 while (*(*fi) <= ' ') ++(*fi);
00312
00313
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];
00324 unsigned int xlen;
00325 unsigned int ylen;
00326 unsigned int linbits;
00327 unsigned int linmax;
00328 int ref;
00329 HUFFBITS *table;
00330 unsigned char *hlen;
00331 unsigned char(*val)[2];
00332 unsigned int treelen;
00333 };
00334
00335 static struct huffcodetab rsf_ht[HTN];
00336
00337
00338
00339
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
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
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);
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;
00459 }
00460 }
00461 else
00462 {
00463 int scfsi = gr_info->scfsi;
00464
00465 if(scfsi < 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);
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
00552 scaleFactorsLength = getScaleFactorsLength(gr, isMPEG2);
00553 bv.skipBits(scaleFactorsLength);
00554
00555 initialize_huffman();
00556
00557 hei.reg1Start = hei.reg2Start = hei.numSamples = 0;
00558
00559
00560 if (gr->big_values < gr->region1start + gr->region2start) {
00561 gr->big_values = gr->region1start + gr->region2start;
00562 }
00563 for (i = 0; i < gr->big_values; ++i) {
00564 if (i < gr->region1start) {
00565
00566 h = &rsf_ht[gr->table_select[0]];
00567 } else if (i < gr->region2start) {
00568
00569 h = &rsf_ht[gr->table_select[1]];
00570 if (hei.reg1Start == 0) {
00571 hei.reg1Start = bv.curBitIndex();
00572 }
00573 } else {
00574
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
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
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
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
00612 static int rsf_huffman_decoder(BitVector& bv,
00613 struct huffcodetab const* h,
00614 int *x,
00615 int *y,
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
00625 if (h->treelen == 0) return 0;
00626
00627
00628
00629 do {
00630 if (h->val[point][0]==0) {
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
00650
00651 if (error) {
00652 printf("Illegal Huffman code in data.\n");
00653 *x = ((h->xlen-1) << 1);
00654 *y = ((h->ylen-1) << 1);
00655 }
00656
00657
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
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
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);
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
00727 unsigned big_values = gr->big_values;
00728 if (big_values < gr->region1start + gr->region2start) {
00729 big_values = gr->region1start + gr->region2start;
00730 }
00731 for (i = 0; i < big_values; ++i) {
00732 if (i < gr->region1start) {
00733
00734 h = &rsf_ht[gr->table_select[0]];
00735 } else if (i < gr->region2start) {
00736
00737 h = &rsf_ht[gr->table_select[1]];
00738 } else {
00739
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
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) {
00772 xy = h->val[point][1];
00773 if (h->hlen[xy] == 0) {
00774 h->table[xy] = bits;
00775 h->hlen[xy] = bitsLength;
00776 return True;
00777 } else {
00778 return False;
00779 }
00780 }
00781
00782 if (numBitsTestedSoFar++ == bitsLength) {
00783
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
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
00816 unsigned char xy;
00817 if (lookupHuffmanTableEntry(h, bits, bitsLength, xy)) {
00818 ++numEntries;
00819 if (numEntries == maxNumEntries) return;
00820 }
00821 }
00822 }
00823 #ifdef DEBUG
00824 fprintf(stderr, "Didn't find enough entries!\n");
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
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
00851 if (h->treelen == 0) return;
00852
00853 if (h->table == NULL) {
00854
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
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
00872
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')) {
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
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 {
00902
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
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
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 {
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 {
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