⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpeghuffmandec.c

📁 jpeg图像文件软件解码器的arm版本的源代码程序
💻 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 + -