📄 huffman.c
字号:
} } // create and write the symbol decode table to file if (tab_name == NULL) { sym_tab * pSymTab = (sym_tab *) malloc (SYM_TAB_LEN * sizeof(sym_tab));#ifndef NO_ASSERTS assert(pSymTab != NULL);#endif for (i=0; i<SYM_TAB_LEN; i++) { pSymTab[i] = st[i]; // JBN printf("%d %d\n", st[i].sym, st[i].len); } pPHD[0] = (PHUFFMAN_DEC_STRUCT) pSymTab; } else { fd = fopen(tab_name, "wb"); if (fd == (FILE *) 0) { printf("ERROR: can't open sym tab file %s for write\n", tab_name); } i = fwrite(st, sizeof(sym_tab), SYM_TAB_LEN, fd); if (i != SYM_TAB_LEN) { printf("ERROR: can't write to sym_tab %s\n", tab_name); } fclose(fd); }}/*** decodeSymbol:** given huffman code state structure PHD, parse the incoming data stream** (obtained through global 32-bit variable <m_chDecBuffer>, which is fed via** MyBuffer[]) and return code for symbol, which is the offset of the symbol string** in the code definition vector found in vlc.h*/Int decodeSymbol(PPHUFFMAN_DEC_STRUCT pPHD){ Int ix, len; sym_tab *pLUT; /* get lookup table ptr, which is first element in PHD ptr struct */ pLUT = (sym_tab *) pPHD[0]; /* ** If we have 8 bits or more in buffer, OK to proceed directly to decode. ** This is the most common case, as we are using a 32-bit m_chDecBuffer ** and the mean entropy of the test clip is about 4.7 bits/symbol. */ if (m_uNumOfBitsInBuffer < 8) { unsigned char *pBuf; if (m_uNumOfBitsInBuffer > 0) { /* ** At least one bit in buffer: load 24 bits. ** Note that MyBuffer[] bounds will be exceeded if ** less than 3 bytes remain. */ if(nBytesAvailable < 3) ReadFileMP4(); pBuf = (unsigned char *)&(MyBuffer[nTotalBytes-nBytesAvailable]); m_chDecBuffer |= pBuf[0] << (24-m_uNumOfBitsInBuffer); m_chDecBuffer |= pBuf[1] << (16-m_uNumOfBitsInBuffer); m_chDecBuffer |= pBuf[2] << ( 8-m_uNumOfBitsInBuffer); nBytesAvailable -= 3; m_uNumOfBitsInBuffer += 24; } else { /* ** empty buffer: load 32 bits. ** Note that MyBuffer[] bounds will be exceeded if ** less than 4 bytes remain. */ if(nBytesAvailable < 4) ReadFileMP4(); pBuf = (unsigned char *)&(MyBuffer[nTotalBytes-nBytesAvailable]); m_chDecBuffer = pBuf[0] << 24; m_chDecBuffer |= pBuf[1] << 16; m_chDecBuffer |= pBuf[2] << 8; m_chDecBuffer |= pBuf[3]; nBytesAvailable -= 4; m_uNumOfBitsInBuffer = 32; } } /* ** A decoded symbol's length is positive. ** If the symbol can't be decoded by the LUT (len<0), ** we do a bit-wise parse based on the FSM state ** returned by the LUT for the output state following ** a parse of the eight <ix> bits */ ix = (UInt) m_chDecBuffer >> 24; // bits 24:31 len = pLUT[ix].len; if (len > 0) { /* update bit fifo to reflect number of bits taken from stream for the symbol just decoded */ m_chDecBuffer <<= len; m_uNumOfBitsInBuffer -= len;#ifdef SYM_DUMP printf("%d\n", pLUT[ix].sym); fflush(stdout);#endif return pLUT[ix].sym; } else { Int cEnd=0, lNextNodeOrSymbol=0, nLocalBit; PHUFFMAN_DEC_STRUCT pHuffDec; /* update bit fifo to reflect number of bits taken from stream for the symbol just decoded */ m_chDecBuffer <<= 8; m_uNumOfBitsInBuffer -= 8; /* ** decode remaining bits of current symbol in stream ** using the decoder state after 8 bits, provided by LUT */ lNextNodeOrSymbol = pLUT[ix].sym; /* PHD actually starts at first offset; zero entry is LUT pointer */ pPHD = (PPHUFFMAN_DEC_STRUCT)((int) pPHD + 4); do { MP4V_RETSINGLEBIT (&nLocalBit); // Save the current pointer pHuffDec = pPHD[lNextNodeOrSymbol]; cEnd=TRUE; if(nLocalBit==0) { if (pHuffDec->m_l0NextNodeOrSymbol != -1) { cEnd=pHuffDec->m_c0End; lNextNodeOrSymbol=pHuffDec->m_l0NextNodeOrSymbol; } } else { if (pHuffDec->m_l1NextNodeOrSymbol != -1) { cEnd=pHuffDec->m_c1End; lNextNodeOrSymbol=pHuffDec->m_l1NextNodeOrSymbol; } } } while(cEnd==0);#ifdef SYM_DUMP printf("%d\n", lNextNodeOrSymbol); fflush(stdout);#endif return lNextNodeOrSymbol; }}#else // !FAST_LUT_DECODEInt decodeSymbol(PPHUFFMAN_DEC_STRUCT pPHD){ Int cEnd=0, lNextNodeOrSymbol=0, nLocalBit; register PHUFFMAN_DEC_STRUCT pHuffDec; do { MP4V_RETSINGLEBIT (&nLocalBit); // Save the current pointer pHuffDec = pPHD[lNextNodeOrSymbol]; cEnd=TRUE; if(nLocalBit==0) { if (pHuffDec->m_l0NextNodeOrSymbol >= 0) { cEnd=pHuffDec->m_c0End; lNextNodeOrSymbol=pHuffDec->m_l0NextNodeOrSymbol; } } else { if (pHuffDec->m_l1NextNodeOrSymbol >= 0) { cEnd=pHuffDec->m_c1End; lNextNodeOrSymbol=pHuffDec->m_l1NextNodeOrSymbol; } } } while(cEnd==0);#ifdef SYM_DUMP printf("%d\n", lNextNodeOrSymbol);#endif return lNextNodeOrSymbol;}#endif //FAST_LUT_DECODE#ifdef USE_BSFASTInt decodeSymbol_WithFastBS(PPHUFFMAN_DEC_STRUCT pPHD, UInt cbits, UInt *pbitsused){ Char cEnd=0; Int lNextNodeOrSymbol=0; PHUFFMAN_DEC_STRUCT pHuffDec; UInt nextbit; *pbitsused = 0; do { _BSFastGetBits2(cbits,1,*pbitsused, nextbit); // Save the current pointer pHuffDec = pPHD[lNextNodeOrSymbol]; cEnd=TRUE; if(nextbit==0) { if (pHuffDec->m_l0NextNodeOrSymbol != -1) { cEnd=pHuffDec->m_c0End; lNextNodeOrSymbol=pHuffDec->m_l0NextNodeOrSymbol; } } else { if (pHuffDec->m_l1NextNodeOrSymbol != -1) { cEnd=pHuffDec->m_c1End; lNextNodeOrSymbol=pHuffDec->m_l1NextNodeOrSymbol; } } } while(cEnd==0); return lNextNodeOrSymbol;}#endifVoid CEntropyDecoderSet (){ m_pentrdecCBPY = (PPHUFFMAN_DEC_STRUCT) malloc (MAX_TABLE_SIZE_CBPY*4); // number of elements * sizeof (int) loadTable (g_rgVlcCBPY, m_pentrdecCBPY); m_pentrdecIntraDCy = (PPHUFFMAN_DEC_STRUCT) malloc (MAX_TABLE_SIZE_INTRA_DCY*4); // number of elements * sizeof (int) loadTable (g_rgVlcIntraDCy, m_pentrdecIntraDCy); m_pentrdecIntraDCc = (PPHUFFMAN_DEC_STRUCT) malloc (MAX_TABLE_SIZE_INTRA_DCC*4); // number of elements * sizeof (int) loadTable (g_rgVlcIntraDCc, m_pentrdecIntraDCc); m_pentrdecMbTypeBVOP = (PPHUFFMAN_DEC_STRUCT) malloc (MAX_TABLE_SIZE_MBTYPE_BVOP*4); // number of elements * sizeof (int) loadTable (g_rgVlcMbTypeBVOP, m_pentrdecMbTypeBVOP); m_pentrdecMCBPCintra = (PPHUFFMAN_DEC_STRUCT) malloc (MAX_TABLE_SIZE_MCBPC_INTRA*4); // number of elements * sizeof (int) loadTable (g_rgVlcMCBPCintra, m_pentrdecMCBPCintra); m_pentrdecMCBPCinter = (PPHUFFMAN_DEC_STRUCT) malloc (MAX_TABLE_SIZE_MCBPC_INTER*4); // number of elements * sizeof (int) loadTable (g_rgVlcMCBPCinter, m_pentrdecMCBPCinter); m_pentrdecMV = (PPHUFFMAN_DEC_STRUCT) malloc (MAX_TABLE_SIZE_MV*4); // number of elements * sizeof (int) loadTable (g_rgVlcMV, m_pentrdecMV); m_pentrdecDCT = (PPHUFFMAN_DEC_STRUCT) malloc (MAX_TABLE_SIZE_DCT*4); // number of elements * sizeof (int) loadTable (g_rgVlcDCT, m_pentrdecDCT); m_pentrdecDCTIntra = (PPHUFFMAN_DEC_STRUCT) malloc (MAX_TABLE_SIZE_DCT_INTRA*4); // number of elements * sizeof (int) loadTable (g_rgVlcDCTIntra, m_pentrdecDCTIntra);}#ifdef DUAL_MODEPPHUFFMAN_DEC_STRUCT realloc(Int lOldSize, Int lNewSize, PPHUFFMAN_DEC_STRUCT pOldHD){ int i; // First allocate memory to hold the array of pointers printf("realloc : lOldSize = %d, lNewSize =%d\n", lOldSize, lNewSize); PPHUFFMAN_DEC_STRUCT pNewHD = (PPHUFFMAN_DEC_STRUCT) malloc (lNewSize * 4); // number of elements * sizeof (int) for (i=0;i<lOldSize;i++) { pNewHD[i] = (PHUFFMAN_DEC_STRUCT) malloc (HUFFMAN_DEC_STRUCT_SIZE); pNewHD[i]->m_c0End = pOldHD[i]->m_c0End; pNewHD[i]->m_c1End = pOldHD[i]->m_c1End; pNewHD[i]->m_l0NextNodeOrSymbol = pOldHD[i]->m_l0NextNodeOrSymbol; pNewHD[i]->m_l1NextNodeOrSymbol = pOldHD[i]->m_l1NextNodeOrSymbol; free (pOldHD[i]); } for (;i<lNewSize;i++) { pNewHD[i] = (PHUFFMAN_DEC_STRUCT) malloc (HUFFMAN_DEC_STRUCT_SIZE); CHuffmanDecoderNode (pNewHD[i]); } return pNewHD;}#endif#if 0~CEntropyDecoderSet(){ delete m_pentrdecDCT; delete m_pentrdecDCTIntra; delete m_pentrdecMV; delete m_pentrdecMCBPCintra; delete m_pentrdecMCBPCinter; delete m_pentrdecCBPY; delete m_pentrdecCBPY1; delete m_pentrdecCBPY2; delete m_pentrdecCBPY3; delete m_pentrdecIntraDCy; delete m_pentrdecIntraDCc; delete m_pentrdecMbTypeBVOP; delete m_pentrdecWrpPnt ; for (UInt iShapeMd = 0; iShapeMd < 7; iShapeMd++) delete m_ppentrdecShapeMode [iShapeMd];//OBSS_SAIT_991015 for (UInt iShapeSSMdInter = 0; iShapeSSMdInter < 4; iShapeSSMdInter++) delete m_ppentrdecShapeSSModeInter [iShapeSSMdInter]; for (UInt iShapeSSMdIntra = 0; iShapeSSMdIntra < 2; iShapeSSMdIntra++) delete m_ppentrdecShapeSSModeIntra [iShapeSSMdIntra];//~OBSS_SAIT_991015 delete m_pentrdecShapeMV1; delete m_pentrdecShapeMV2; // Added for data partitioning mode By Toshiba(1998-1-16:DP+RVLC) delete m_pentrdecDCTRVLC; delete m_pentrdecDCTIntraRVLC; // End Toshiba(1998-1-16:DP+RVLC)}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -