📄 jpeghuffmandec.c
字号:
///////////////////////////////////////////////////////////////////////////////
//
// JPEGHuffmanDec.c
//
// DESCRIPTION
// Functions related to Huff decoding in JPEG.
// Construct Huff tables, as well as other structures that will be
// used in decoding. Decode entropy coded segments.
// A 256-entry Lookup table is used in Huff decoding. The Huffamn
// codes shorter or equal to 8-bit will be directly found in this table.
// The lookup process is in the MCU decoding module.
// If a code is shorter than 8-bit, same symbol is put in all slots whose
// indices start with that Huff code.
//
//
///////////////////////////////////////////////////////////////////////////////
#include "JPEGHuffmanDec.h"
/////////////////////////////////////////////////////////////////////////////
// NAME
// JPEGPrepareOneHuffTable
//
// DESCRIPTION
// Set up one Huffman lookup table.
//
// INPUTS
// huffTable - pointer to Huffman table structure
// AllocateMemory - function pointer for memory allocation
// Deallocate - function pointer for memory deallocation
//
// OUTPUTS
// huffTable - update tables in this structure
//
// RETURN VALUE
// Always returns JPEG_OK
//
/////////////////////////////////////////////////////////////////////////////
OP_INT32 JPEGPrepareOneHuffTable
(
JPEGHuffTable *huffTable,
GetMemoryFunction AllocateMemory,
FreeMemoryFunction Deallocate
)
{
int i;
int j;
int symbolIdx;
int lengthIdx;
int initialCode;
int lutIdx;
int maxCodeLength;
// allocate the derived tables for Huff decoding
// tables may be allocated, but they must be zero at the very beginning
if (huffTable->huffCodes)
{
Deallocate(huffTable->huffCodes);
huffTable->huffCodes = 0;
}
if (huffTable->huffBits)
{
Deallocate(huffTable->huffBits);
huffTable->huffBits = 0;
}
huffTable->huffCodes = (OP_UINT16 *) AllocateMemory(sizeof(OP_UINT16) * huffTable->numSymbols);
huffTable->huffBits = (OP_UINT8 *) AllocateMemory(sizeof(OP_UINT8) * huffTable->numSymbols);
// derive the Huff codes for all symbols in the table
symbolIdx = 0;
initialCode = 0;
lutIdx = 0;
for (i = 0; i < 18; i ++)
{
huffTable->codeStartAt[i] = 0;
huffTable->firstCodes[i] = 0;
}
for (lengthIdx = 1; lengthIdx <= 16; lengthIdx ++)
{
int numLUTEntries;
// number of entries in LUT to fill, with the same symbol
numLUTEntries = 1 << (8 - lengthIdx);
huffTable->codeStartAt[lengthIdx] = symbolIdx;
if (huffTable->numCodes[lengthIdx])
{
maxCodeLength = lengthIdx;
for (i = huffTable->numCodes[lengthIdx]; i > 0; i --)
{
huffTable->huffCodes[symbolIdx] = initialCode;
huffTable->huffBits[symbolIdx] = lengthIdx;
// construct the lookup table for faster decoding
if (lengthIdx <= 8)
{
OP_UINT8 currentSymbol;
currentSymbol = huffTable->symbols[symbolIdx];
for (j = numLUTEntries; j > 0; j --)
{
huffTable->bitsLUT[lutIdx] = lengthIdx;
huffTable->symbolLUT[lutIdx] = currentSymbol;
lutIdx ++;
}
}
initialCode ++;
symbolIdx ++;
}
}
initialCode <<= 1;
}
// find the first code of each length
for (lengthIdx = 1; lengthIdx <= 17; lengthIdx ++)
{
if (lengthIdx <= maxCodeLength)
{
if (huffTable->numCodes[lengthIdx])
{
huffTable->firstCodes[lengthIdx] =
huffTable->huffCodes[huffTable->codeStartAt[lengthIdx]];
}
else
{
// so this will be bypassed in searching for code length
int firstCode, realLength;
if (huffTable->codeStartAt[lengthIdx] >= huffTable->numSymbols)
{
huffTable->numSymbols = huffTable->numSymbols;
}
firstCode = huffTable->huffCodes[huffTable->codeStartAt[lengthIdx]];
realLength = huffTable->huffBits[huffTable->codeStartAt[lengthIdx]];
huffTable->firstCodes[lengthIdx] = firstCode >> (realLength - lengthIdx);
}
}
else
{
huffTable->firstCodes[lengthIdx] = 0x03FFFF;
}
}
// fill the remaining entries in LUTs with warning information
for ( ; lutIdx < 256; lutIdx++)
{
huffTable->bitsLUT[lutIdx] = 0;
huffTable->symbolLUT[lutIdx] = 0;
}
return JPEG_OK;
}
/////////////////////////////////////////////////////////////////////////////
// NAME
// JPEGPrepareHuffTables
//
// DESCRIPTION
// Set up all Huffman lookup tables.
//
// INPUTS
// jpegSegments - pointer to JPEG segments structure
// AllocateMemory - function pointer for memory allocation
// Deallocate - function pointer for memory deallocation
//
// OUTPUTS
// jpegSegments - update Huffman tables in this structure
//
// RETURN VALUE
// Always returns JPEG_OK
//
/////////////////////////////////////////////////////////////////////////////
OP_INT32 JPEGPrepareHuffTables
(
JPEGSegments *jpegSegments,
GetMemoryFunction AllocateMemory,
FreeMemoryFunction Deallocate
)
{
int tableIdx;
JPEGHuffTable *huffTable;
for (tableIdx = 0; tableIdx < jpegSegments->numHuffTables; tableIdx++)
{
huffTable = &(jpegSegments->huffTables [tableIdx]);
JPEGPrepareOneHuffTable(huffTable, AllocateMemory, Deallocate);
}
return JPEG_OK;
}
/////////////////////////////////////////////////////////////////////////////
// NAME
// JPEGDecodeRareSymbol
//
// DESCRIPTION
// Decode a long code.
//
// INPUTS
// huffTable - pointer to Huffman table structure
// bitsBuf - pointer to bitstream buffer
// bitsBufPtr - pointer to bitstream buffer bit index
//
// OUTPUTS
// none.
//
// RETURN VALUE
// Returns the decoded symbol if successful, returns -1 otherwise.
//
/////////////////////////////////////////////////////////////////////////////
OP_INT32 JPEGDecodeRareSymbol
(
JPEGHuffTable *huffTable,
OP_UINT32 *bitsBuf,
OP_UINT8 *bitsBufPtr
)
{
int code;
int codeLength;
int nextLengthCode;
int firstCode;
int codeTableIdx;
codeLength = 8;
do
{
codeLength ++;
code = *bitsBuf >> (32 - codeLength);
nextLengthCode = huffTable->firstCodes[codeLength + 1];
} while (code >= (nextLengthCode >> 1));
// left align the remaining bits
*bitsBufPtr += codeLength;
*bitsBuf <<= codeLength;
// get the code
firstCode = huffTable->firstCodes[codeLength];
codeTableIdx = huffTable->codeStartAt[codeLength] + code - firstCode;
if (codeTableIdx >= huffTable->numSymbols)
{
return -1;
}
else
{
return huffTable->symbols[codeTableIdx];
}
}
/////////////////////////////////////////////////////////////////////////////
// NAME
// NextByteFromBuf
//
// DESCRIPTION
// Get the next byte from bitstream
//
// INPUTS
// byteBuffer - pointer to byte buffer structure
//
// OUTPUTS
// none.
//
// RETURN VALUE
// Returns the next byte from bitstream buffer
//
/////////////////////////////////////////////////////////////////////////////
OP_INT32 NextByteFromBuf
(
ByteBuffer *byteBuffer
)
{
int nextByte;
// read 2 bytes from the file
nextByte = byteBuffer->dataBuf[byteBuffer->bufPtr];
byteBuffer->bufPtr++;
if (nextByte == 0xFF) // marker or ECS with stuffed zero
{
// skip any following 0xFF
while (byteBuffer->dataBuf[byteBuffer->bufPtr] == 0xFF)
{
byteBuffer->bufPtr++;
}
if (byteBuffer->dataBuf[byteBuffer->bufPtr])
{
// put these two bytes back to the bitstream
byteBuffer->bufPtr--;
nextByte = 0; // append zeros
}
else
{
// skip the stuffed 0
byteBuffer->bufPtr++;
}
}
return nextByte;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -