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

📄 jpegsegments.c

📁 jpeg图像文件软件解码器的arm版本的源代码程序
💻 C
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////
//
//  JPEGSegments.c
//
//     DESCRIPTION
//       This file contains routines to read the definition segments in the file 
//         header of JPEG file.
//
//
//
///////////////////////////////////////////////////////////////////////////////

#include "irom_PlatformDefines.h"
#include "JPEGSegments.h"
#include "JPEGHuffmanDec.h"
#include "irom_JPEGTable.h"

// -------------------------------------------------------------------------
// Macro BigEndianWord
//
//   Form a 2-byte integer using the first two bytes in the string. The
//   number stored in the string is in big endian.
//   Input parameters:
//     OP_UINT8 *string, string containing the number
//   Return:
//     The 2-byte number just formed.
// -------------------------------------------------------------------------
#define BigEndianWord(string)  ((((int)(string)[0] & 0xFF) << 8) + ((int)(string)[1] & 0xFF))


/////////////////////////////////////////////////////////////////////////////
// NAME  
//            JPEGReadQuantTable
//
// DESCRIPTION
//            Read DQT segment. The marker and the length field have been removed.
//           One or multiple quantization tables may be defined in the segment.
//           This function supports re-definition of quantization tables. However,
//           It is not allowed to redefine the tables of different precision.
//
// INPUTS   
//            segmentString - string buffer containing the segment header
//          segmentLength - length of the segment header
//          jpegSegments  - pointer to structure storing the segment information
//          aanscales_tab - pointer to the quatization scale table 
//          jpegNaturalOrder_tab - pointer to IDCT coeffient order table
// 
// OUTPUTS  
//            JPEGSegments - stores quantization table in subfields of this structure        
//
// RETURN VALUE
//          Returns JPEG_OK    if successful, returns an error code otherwise.
//           
/////////////////////////////////////////////////////////////////////////////
int JPEGReadQuantTable
(
    OP_UINT8            *segmentString, 
    int                 segmentLength,
    JPEGSegments        *jpegSegments, 
    const OP_UINT16     *aanscales_tab,
    const OP_UINT8      *jpegNaturalOrder_tab
)
{
    int                 stringPtr;
    int                 tableIdx; 
    int                 entryIdx;
    OP_UINT16           *qfTable;
    JPEGQuantTable      *quantTable;
    
    stringPtr = 0;

    // one or multiple tables may be defined in one segment
    while (stringPtr < segmentLength)
    {
        OP_UINT8    newTableSpec;

        newTableSpec = segmentString[stringPtr ++];

        if (stringPtr > segmentLength)
        {
            return JPEG_ERR_QUANT_TABLE;
        }

        // get the table spec, does a quant table of same ID exist?
        for (tableIdx = 0; tableIdx < jpegSegments->numQuantTables; tableIdx ++)
        {
            OP_UINT8    prevTableSpec;

            prevTableSpec = jpegSegments->quantTables[tableIdx].tableSpec;

            // previous table will be replaced
            if (newTableSpec == prevTableSpec)
            {
                break;
            }
            else if ((newTableSpec & 0x0F)==(jpegSegments->quantTables[tableIdx].tableSpec & 0x0F))
            {
                // same ID but different precision, must be something wrong
                return JPEG_ERR_QUANT_TABLE;
            }
        }

        quantTable = &(jpegSegments->quantTables[tableIdx]);

        quantTable->tableSpec = newTableSpec;
        
        // upper 4 bits are for precision
        if ((newTableSpec >> 4) != 0)
        {
            // 16-bit precision is not supported
            return JPEG_ERR_QUANT_TABLE;
        }

        qfTable = quantTable->table;

        // generate specific table coupled with fast IDCT
        // For AA&N IDCT method, multipliers are equal to quantization
         // coefficients scaled by scalefactor[row]*scalefactor[col], where
        //   scalefactor[0] = 1
        //   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
        // For integer operation, the multiplier table is to be scaled by
        // IFAST_SCALE_BITS.
        for (entryIdx = 0; entryIdx < BLOCK_AREA; entryIdx ++)
        {
            OP_UINT16 qFactor;

            qFactor = segmentString[stringPtr ++];
            if (stringPtr > segmentLength)
            {
                return JPEG_ERR_QUANT_TABLE;
            }

            // this is for floating point implementation
            qfTable[entryIdx] = (qFactor * aanscales_tab[jpegNaturalOrder_tab[entryIdx]] + 64) >> 7;

            // this is for fixed point implementation
//            qfTable[entryIdx] = 
//                (qFactor * aanscales[jpegNaturalOrder_tab[entryIdx]] + 2048) >> 12;
        }
        
        // a new quantization table is installed
        if (tableIdx == jpegSegments->numQuantTables)
        {
            jpegSegments->numQuantTables += 1;
        }
        // else a previous table is replaced
    }

    return JPEG_OK;
}


/////////////////////////////////////////////////////////////////////////////
// NAME  
//            JPEGReadHuffTable
//
// DESCRIPTION 
//           Read Huff tables. One or multiple tables can be defined in one
//           DHT segments.
//           Each Huff table is stored as two parts, the code_bits part, and 
//           huff_val part. The first table records the number of codes of certain 
//           length (the index to this table). The second table records the values 
//           corresponding to these codes. The actual Huff codes are generated 
//           by the decoder following the well-defined rule.
//           This function supports re-definition of some Huff tables. A Huff
//           table is unique identified by its tableSpec (table class + table ID).
//           A DC table can have the same ID as an AC table.
//
// INPUTS   
//            segmentString - string buffer containing the segment header
//          segmentLength - length of the segment header
//          jpegSegments  - pointer to structure storing the segment information
//          AllocateMemory - function pointer for memory allocation 
//          Deallocate - function pointer for memory deallocation
// 
// OUTPUTS  
//            JPEGSegments - stores huffman table in subfields of this structure        
//
// RETURN VALUE
//          Returns JPEG_OK    if successful, returns an error code otherwise.
//           
/////////////////////////////////////////////////////////////////////////////
int JPEGReadHuffTable
(
    OP_UINT8                *segmentString, 
    int                     segmentLength,
    JPEGSegments            *jpegSegments, 
    GetMemoryFunction       AllocateMemory,
    FreeMemoryFunction      Deallocate
)
{
    int                 i;
    int                 stringPtr;
    int                 tableIdx;
    int                 entryIdx; 
    int                 symbolIdx;
    JPEGHuffTable       *huffTable;
    
    stringPtr = 0;

    // one or multiple tables may be defined in one segment
    while (stringPtr < segmentLength)
    {
        OP_UINT8    newTableSpec;
        OP_UINT8    prevTableSpec;

        newTableSpec = segmentString[stringPtr ++];

        if (stringPtr > segmentLength)
        {
            return JPEG_ERR_HUFFMAN_TABLE;
        }

        // get the table spec, does a Huff table of same ID exist?
        for (tableIdx = 0; tableIdx < jpegSegments->numHuffTables; tableIdx ++)
        {
            prevTableSpec = jpegSegments->huffTables[tableIdx].tableSpec;
            if (newTableSpec == prevTableSpec)
            {
                break;
            }
        }

        huffTable = &(jpegSegments->huffTables[tableIdx]);

        huffTable->tableSpec = newTableSpec;
        
        // read the code_bits table
        huffTable->numSymbols = 0;
        for (entryIdx = 1; entryIdx <= 16; entryIdx ++)
        {
            huffTable->numCodes[entryIdx] = segmentString[stringPtr ++];

            if (stringPtr > segmentLength)
            {
                return JPEG_ERR_HUFFMAN_TABLE;
            }

            huffTable->numSymbols += huffTable->numCodes[entryIdx];
        }

        // allocate the huff_val table
        if (huffTable->symbols)
        {
            Deallocate(huffTable->symbols);
            huffTable->symbols = 0;
        }

        huffTable->symbols = (OP_UINT8 *) AllocateMemory(sizeof(OP_UINT8) * huffTable->numSymbols);

        // read the huff_val table
        symbolIdx = 0;

        for (entryIdx = 1; entryIdx <= 16; entryIdx ++)
        {
            for (i = 0; i < huffTable->numCodes[entryIdx]; i ++)
            {
                huffTable->symbols[symbolIdx ++] = segmentString[stringPtr ++];
                if (stringPtr > segmentLength)
                {
                    return JPEG_ERR_HUFFMAN_TABLE;
                }
            }
        }

        // a new table is installed
        if (tableIdx == jpegSegments->numHuffTables)
        {
            jpegSegments->numHuffTables += 1;
        }
    }

    return JPEG_OK;
}


/////////////////////////////////////////////////////////////////////////////
// NAME  
//            JPEGReadFrameHeader
//
// DESCRIPTION 
//            Read JPEG frame header.            
//
// INPUTS   
//            segmentString - string buffer containing the segment header
//          segmentLength - length of the segment header
//          frameHeader   - pointer to structure storing the frame header
// 
// OUTPUTS  
//            frameHeader   - stores frame header information in this structure        
//
// RETURN VALUE
//          Returns JPEG_OK    if successful, returns an error code otherwise.
//           
/////////////////////////////////////////////////////////////////////////////
int JPEGReadFrameHeader
(
    OP_UINT8            *segmentString, 
    int                 segmentLength,
    JPEGFrameHeader     *frameHeader
)
{
    int     stringPtr;
    int     compIdx;

    stringPtr = 0;

    frameHeader->precision = segmentString[stringPtr ++];

    frameHeader->frameHeight = BigEndianWord(segmentString + stringPtr);
    stringPtr += 2;

    frameHeader->frameWidth = BigEndianWord(segmentString + stringPtr);
    stringPtr += 2;

    frameHeader->numComponents = segmentString[stringPtr ++];

    // read the component description
    for (compIdx = 0; compIdx < frameHeader->numComponents; compIdx ++)
    {
        JPEGFrameCompBlock      *thisCompBlock;

        thisCompBlock = frameHeader->frameCompBlocks + compIdx;

        thisCompBlock->componentID  = segmentString[stringPtr];
        thisCompBlock->sampFactor   = segmentString[stringPtr + 1];
        thisCompBlock->quantTableID = segmentString[stringPtr + 2];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -