📄 mp3internalshuffman.cpp
字号:
static unsigned rsf_get_scale_factors_2(MP3SideInfo::gr_info_s_t *gr_info) { unsigned char const* pnt; int i; unsigned int slen; int n = 0; int numbits = 0;#ifdef undef if(i_stereo) /* i_stereo AND second channel -> do_layer3() checks this */ slen = i_slen2[gr_info->scalefac_compress>>1]; else#endif slen = n_slen2[gr_info->scalefac_compress]; gr_info->preflag = (slen>>15) & 0x1; n = 0; if( gr_info->block_type == 2 ) { n++; if(gr_info->mixed_block_flag) n++; } pnt = stab[n][(slen>>12)&0x7]; for(i=0;i<4;i++) { int num = slen & 0x7; slen >>= 3; numbits += pnt[i] * num; } return numbits;}static unsigned getScaleFactorsLength(MP3SideInfo::gr_info_s_t* gr, Boolean isMPEG2) { return isMPEG2 ? rsf_get_scale_factors_2(gr) : rsf_get_scale_factors_1(gr);}static int rsf_huffman_decoder(BitVector& bv, struct huffcodetab const* h, int* x, int* y, int* v, int* w); // forwardvoid MP3HuffmanDecode(MP3SideInfo::gr_info_s_t* gr, int isMPEG2, unsigned char const* fromBasePtr, unsigned fromBitOffset, unsigned fromLength, unsigned& scaleFactorsLength, MP3HuffmanEncodingInfo& hei) { unsigned i; int x, y, v, w; struct huffcodetab *h; BitVector bv((unsigned char*)fromBasePtr, fromBitOffset, fromLength); /* Compute the size of the scale factors (& also advance bv): */ scaleFactorsLength = getScaleFactorsLength(gr, isMPEG2); bv.skipBits(scaleFactorsLength); initialize_huffman(); hei.reg1Start = hei.reg2Start = hei.numSamples = 0; /* Read bigvalues area. */ if (gr->big_values < gr->region1start + gr->region2start) { gr->big_values = gr->region1start + gr->region2start; /* sanity check */ } for (i = 0; i < gr->big_values; ++i) { if (i < gr->region1start) { /* in region 0 */ h = &rsf_ht[gr->table_select[0]]; } else if (i < gr->region2start) { /* in region 1 */ h = &rsf_ht[gr->table_select[1]]; if (hei.reg1Start == 0) { hei.reg1Start = bv.curBitIndex(); } } else { /* in region 2 */ h = &rsf_ht[gr->table_select[2]]; if (hei.reg2Start == 0) { hei.reg2Start = bv.curBitIndex(); } } hei.allBitOffsets[i] = bv.curBitIndex(); rsf_huffman_decoder(bv, h, &x, &y, &v, &w); if (hei.decodedValues != NULL) { // Record the decoded values: unsigned* ptr = &hei.decodedValues[4*i]; ptr[0] = x; ptr[1] = y; ptr[2] = v; ptr[3] = w; } } hei.bigvalStart = bv.curBitIndex(); /* Read count1 area. */ h = &rsf_ht[gr->count1table_select+32]; while (bv.curBitIndex() < bv.totNumBits() && i < SSLIMIT*SBLIMIT) { hei.allBitOffsets[i] = bv.curBitIndex(); rsf_huffman_decoder(bv, h, &x, &y, &v, &w); if (hei.decodedValues != NULL) { // Record the decoded values: unsigned* ptr = &hei.decodedValues[4*i]; ptr[0] = x; ptr[1] = y; ptr[2] = v; ptr[3] = w; } ++i; } hei.allBitOffsets[i] = bv.curBitIndex(); hei.numSamples = i;}HUFFBITS dmask = 1 << (SIZEOF_HUFFBITS*8-1);unsigned int hs = SIZEOF_HUFFBITS*8;/* do the huffman-decoding */static int rsf_huffman_decoder(BitVector& bv, struct huffcodetab const* h, // ptr to huffman code record /* unsigned */ int *x, // returns decoded x value /* unsigned */ int *y, // returns decoded y value int* v, int* w) { HUFFBITS level; unsigned point = 0; int error = 1; level = dmask; *x = *y = *v = *w = 0; if (h->val == NULL) return 2; /* table 0 needs no bits */ if (h->treelen == 0) return 0; /* Lookup in Huffman table. */ do { if (h->val[point][0]==0) { /*end of tree*/ *x = h->val[point][1] >> 4; *y = h->val[point][1] & 0xf; error = 0; break; } if (bv.get1Bit()) { while (h->val[point][1] >= MXOFF) point += h->val[point][1]; point += h->val[point][1]; } else { while (h->val[point][0] >= MXOFF) point += h->val[point][0]; point += h->val[point][0]; } level >>= 1; } while (level || (point < h->treelen) );///// } while (level || (point < rsf_ht->treelen) ); /* Check for error. */ if (error) { /* set x and y to a medium value as a simple concealment */ printf("Illegal Huffman code in data.\n"); *x = ((h->xlen-1) << 1); *y = ((h->ylen-1) << 1); } /* Process sign encodings for quadruples tables. */ if (h->tablename[0] == '3' && (h->tablename[1] == '2' || h->tablename[1] == '3')) { *v = (*y>>3) & 1; *w = (*y>>2) & 1; *x = (*y>>1) & 1; *y = *y & 1; if (*v) if (bv.get1Bit() == 1) *v = -*v; if (*w) if (bv.get1Bit() == 1) *w = -*w; if (*x) if (bv.get1Bit() == 1) *x = -*x; if (*y) if (bv.get1Bit() == 1) *y = -*y; } /* Process sign and escape encodings for dual tables. */ else { if (h->linbits) if ((h->xlen-1) == (unsigned)*x) *x += bv.getBits(h->linbits); if (*x) if (bv.get1Bit() == 1) *x = -*x; if (h->linbits) if ((h->ylen-1) == (unsigned)*y) *y += bv.getBits(h->linbits); if (*y) if (bv.get1Bit() == 1) *y = -*y; } return error; }#ifdef DO_HUFFMAN_ENCODINGinline int getNextSample(unsigned char const*& fromPtr) { int sample#ifdef FOUR_BYTE_SAMPLES = (fromPtr[0]<<24) | (fromPtr[1]<<16) | (fromPtr[2]<<8) | fromPtr[3];#else#ifdef TWO_BYTE_SAMPLES = (fromPtr[0]<<8) | fromPtr[1];#else // ONE_BYTE_SAMPLES = fromPtr[0];#endif#endif fromPtr += BYTES_PER_SAMPLE_VALUE; return sample;}static void rsf_huffman_encoder(BitVector& bv, struct huffcodetab* h, int x, int y, int v, int w); // forwardunsigned MP3HuffmanEncode(MP3SideInfo::gr_info_s_t const* gr, unsigned char const* fromPtr, unsigned char* toPtr, unsigned toBitOffset, unsigned numHuffBits) { unsigned i; struct huffcodetab *h; int x, y, v, w; BitVector bv(toPtr, toBitOffset, numHuffBits); initialize_huffman(); // Encode big_values area: unsigned big_values = gr->big_values; if (big_values < gr->region1start + gr->region2start) { big_values = gr->region1start + gr->region2start; /* sanity check */ } for (i = 0; i < big_values; ++i) { if (i < gr->region1start) { /* in region 0 */ h = &rsf_ht[gr->table_select[0]]; } else if (i < gr->region2start) { /* in region 1 */ h = &rsf_ht[gr->table_select[1]]; } else { /* in region 2 */ h = &rsf_ht[gr->table_select[2]]; } x = getNextSample(fromPtr); y = getNextSample(fromPtr); v = getNextSample(fromPtr); w = getNextSample(fromPtr); rsf_huffman_encoder(bv, h, x, y, v, w); } // Encode count1 area: h = &rsf_ht[gr->count1table_select+32]; while (bv.curBitIndex() < bv.totNumBits() && i < SSLIMIT*SBLIMIT) { x = getNextSample(fromPtr); y = getNextSample(fromPtr); v = getNextSample(fromPtr); w = getNextSample(fromPtr); rsf_huffman_encoder(bv, h, x, y, v, w); ++i; } return i;}static Boolean lookupHuffmanTableEntry(struct huffcodetab const* h, HUFFBITS bits, unsigned bitsLength, unsigned char& xy) { unsigned point = 0; unsigned mask = 1; unsigned numBitsTestedSoFar = 0; do { if (h->val[point][0]==0) { // end of tree xy = h->val[point][1]; if (h->hlen[xy] == 0) { // this entry hasn't already been used h->table[xy] = bits; h->hlen[xy] = bitsLength; return True; } else { // this entry has already been seen return False; } } if (numBitsTestedSoFar++ == bitsLength) { // We don't yet have enough bits for this prefix return False; } if (bits&mask) { while (h->val[point][1] >= MXOFF) point += h->val[point][1]; point += h->val[point][1]; } else { while (h->val[point][0] >= MXOFF) point += h->val[point][0]; point += h->val[point][0]; } mask <<= 1; } while (mask || (point < h->treelen)); return False;}static void buildHuffmanEncodingTable(struct huffcodetab* h) { h->table = new unsigned long[256]; h->hlen = new unsigned char[256]; if (h->table == NULL || h->hlen == NULL) { h->table = NULL; return; } for (unsigned i = 0; i < 256; ++i) { h->table[i] = 0; h->hlen[i] = 0; } // Look up entries for each possible bit sequence length: unsigned maxNumEntries = h->xlen * h->ylen; unsigned numEntries = 0; unsigned powerOf2 = 1; for (unsigned bitsLength = 1; bitsLength <= 8*SIZEOF_HUFFBITS; ++bitsLength) { powerOf2 *= 2; for (HUFFBITS bits = 0; bits < powerOf2; ++bits) { // Find the table value - if any - for 'bits' (length 'bitsLength'): unsigned char xy; if (lookupHuffmanTableEntry(h, bits, bitsLength, xy)) { ++numEntries; if (numEntries == maxNumEntries) return; // we're done } } }#ifdef DEBUG fprintf(stderr, "Didn't find enough entries!\n"); // shouldn't happen#endif}static void lookupXYandPutBits(BitVector& bv, struct huffcodetab const* h, unsigned char xy) { HUFFBITS bits = h->table[xy]; unsigned bitsLength = h->hlen[xy]; // Note that "bits" is in reverse order, so read them from right-to-left: while (bitsLength-- > 0) { bv.put1Bit(bits&0x00000001); bits >>= 1; }}static void putLinbits(BitVector& bv, struct huffcodetab const* h, HUFFBITS bits) { bv.putBits(bits, h->linbits);}static void rsf_huffman_encoder(BitVector& bv, struct huffcodetab* h, int x, int y, int v, int w) { if (h->val == NULL) return; /* table 0 produces no bits */ if (h->treelen == 0) return; if (h->table == NULL) { // We haven't yet built the encoding array for this table; do it now: buildHuffmanEncodingTable(h); if (h->table == NULL) return; } Boolean xIsNeg = False, yIsNeg = False, vIsNeg = False, wIsNeg = False; unsigned char xy;#ifdef FOUR_BYTE_SAMPLES#else#ifdef TWO_BYTE_SAMPLES // Convert 2-byte negative numbers to their 4-byte equivalents: if (x&0x8000) x |= 0xFFFF0000; if (y&0x8000) y |= 0xFFFF0000; if (v&0x8000) v |= 0xFFFF0000; if (w&0x8000) w |= 0xFFFF0000;#else // ONE_BYTE_SAMPLES // Convert 1-byte negative numbers to their 4-byte equivalents: if (x&0x80) x |= 0xFFFFFF00; if (y&0x80) y |= 0xFFFFFF00; if (v&0x80) v |= 0xFFFFFF00; if (w&0x80) w |= 0xFFFFFF00;#endif#endif if (h->tablename[0] == '3' && (h->tablename[1] == '2' || h->tablename[1] == '3')) {// quad tables if (x < 0) { xIsNeg = True; x = -x; } if (y < 0) { yIsNeg = True; y = -y; } if (v < 0) { vIsNeg = True; v = -v; } if (w < 0) { wIsNeg = True; w = -w; } // Sanity check: x,y,v,w must all be 0 or 1: if (x>1 || y>1 || v>1 || w>1) {#ifdef DEBUG fprintf(stderr, "rsf_huffman_encoder quad sanity check fails: %x,%x,%x,%x\n", x, y, v, w);#endif } xy = (v<<3)|(w<<2)|(x<<1)|y; lookupXYandPutBits(bv, h, xy); if (v) bv.put1Bit(vIsNeg); if (w) bv.put1Bit(wIsNeg); if (x) bv.put1Bit(xIsNeg); if (y) bv.put1Bit(yIsNeg); } else { // dual tables // Sanity check: v and w must be 0: if (v != 0 || w != 0) {#ifdef DEBUG fprintf(stderr, "rsf_huffman_encoder dual sanity check 1 fails: %x,%x,%x,%x\n", x, y, v, w);#endif } if (x < 0) { xIsNeg = True; x = -x; } if (y < 0) { yIsNeg = True; y = -y; } // Sanity check: x and y must be <= 255: if (x > 255 || y > 255) {#ifdef DEBUG fprintf(stderr, "rsf_huffman_encoder dual sanity check 2 fails: %x,%x,%x,%x\n", x, y, v, w);#endif } int xl1 = h->xlen-1; int yl1 = h->ylen-1; unsigned linbitsX = 0; unsigned linbitsY = 0; if (((x < xl1) || (xl1 == 0)) && (y < yl1)) { // normal case xy = (x<<4)|y; lookupXYandPutBits(bv, h, xy); if (x) bv.put1Bit(xIsNeg); if (y) bv.put1Bit(yIsNeg); } else if (x >= xl1) { linbitsX = (unsigned)(x - xl1); if (linbitsX > h->linmax) {#ifdef DEBUG fprintf(stderr,"warning: Huffman X table overflow\n");#endif linbitsX = h->linmax; }; if (y >= yl1) { xy = (xl1<<4)|yl1; lookupXYandPutBits(bv, h, xy); linbitsY = (unsigned)(y - yl1); if (linbitsY > h->linmax) {#ifdef DEBUG fprintf(stderr,"warning: Huffman Y table overflow\n");#endif linbitsY = h->linmax; }; if (h->linbits) putLinbits(bv, h, linbitsX); if (x) bv.put1Bit(xIsNeg); if (h->linbits) putLinbits(bv, h, linbitsY); if (y) bv.put1Bit(yIsNeg); } else { /* x >= h->xlen, y < h->ylen */ xy = (xl1<<4)|y; lookupXYandPutBits(bv, h, xy); if (h->linbits) putLinbits(bv, h, linbitsX); if (x) bv.put1Bit(xIsNeg); if (y) bv.put1Bit(yIsNeg); } } else { /* ((x < h->xlen) && (y >= h->ylen)) */ xy = (x<<4)|yl1; lookupXYandPutBits(bv, h, xy); linbitsY = y-yl1; if (linbitsY > h->linmax) {#ifdef DEBUG fprintf(stderr,"warning: Huffman Y table overflow\n");#endif linbitsY = h->linmax; }; if (x) bv.put1Bit(xIsNeg); if (h->linbits) putLinbits(bv, h, linbitsY); if (y) bv.put1Bit(yIsNeg); } }}#endif#ifdef undef/* The system uses a variety of data files. By opening them via this function, we can accommodate various locations. */FILE *OpenTableFile(name)char *name;{char fulname[80];FILE *f; fulname[0] = '\0'; strcat(fulname, name); if( (f=fopen(fulname,"r"))==NULL ) { fprintf(stderr,"OpenTable: could not find %s\n", fulname); }/* The following was used to generate an internal version of the file #####*/ {FILE *testfd = fopen("rsf_hufftab.c", "w");unsigned char buf[100];unsigned i;for (i = 0; i < 100; ++i) buf[i] = '\0';while (fgets(buf, 100, f) != NULL) { unsigned j; for (j = 0; buf[j] != '\0'; ++j) { fprintf(testfd, "0x%02x, ", buf[j]); } for (i = 0; i < 100; ++i) buf[i] = '\0';}fclose(testfd);exit(0); }/*#####*/ return f;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -