📄 irom_jpegmcudecode_arm.c
字号:
///////////////////////////////////////////////////////////////////////////////
//
// JPEGMCUDec.c
//
// DESCRIPTION
// Handle the image data related structures. This decoder does not
// handle multiple scans in a frame.
//
//
///////////////////////////////////////////////////////////////////////////////
#include "irom_PlatformDefines.h"
#include "irom_jpegheader.h"
#include "irom_JPEGMarkers.h"
#define BUILD_FOR_EROM_ONLY
#ifndef BUILD_FOR_EROM_ONLY
#include "irom_featurelock.h"
#endif // BUILD_FOR_EROM_ONLY
#define EROM_TARGET
#define FillBitsBuffer { \
if (bitsBufPtr >= 16) \
{ \
bitsBufPtr -= 16; \
bitsBuf += NextByteFromBuf_fun(byteBuffer) << (8+bitsBufPtr); \
bitsBuf += NextByteFromBuf_fun(byteBuffer) << bitsBufPtr; \
} \
}
/////////////////////////////////////////////////////////////////////////////
// NAME
// JPEGMCUDecode
//
// DESCRIPTION
// Decode one JPEG MCU.
//
// INPUTS
// byteBuffer - pointer to byte buffer structure
// mcu - pointer to a JPEGMCU structure
// jpegNaturalOrder_tab - pointer to JPEG IDCT coefficient
// order table
// JPEGDecodeRareSymbol_fun - function pointer to the decode
// rare symbol function
// JPEGIDCT_int_fun - function pointer to the integer IDCT
// function
// NextByteFromBuf_fun - function pointer to the read byte
// from byte buffer function
//
// OUTPUTS
// jpegMCU - store results in this structure
//
// RETURN VALUE
// Returns JPEG_OK if successful, returns an error code otherwise.
//
/////////////////////////////////////////////////////////////////////////////
OP_INT32 JPEGMCUDecode
(
ByteBuffer *byteBuffer,
JPEGMCU *mcu,
const OP_UINT8 *jpegNaturalOrder_tab,
JPEGDecodeRareSymbolFunction JPEGDecodeRareSymbol_fun,
JPEGIDCT_int_Function JPEGIDCT_int_fun,
NextByteFromBufFunction NextByteFromBuf_fun
)
{
OP_UINT8 bitsBufPtr;
OP_UINT8 *upperBitsByte; // the highest byte in bitsBuf
OP_UINT8 *imageBlock;
OP_UINT8 currentSymbol;
OP_UINT8 *dcBitsLUT;
OP_UINT8 *acBitsLUT;
OP_UINT8 *dcSymbolLUT;
OP_UINT8 *acSymbolLUT;
int i;
int compIdx;
OP_UINT32 bitsBuf;
OP_INT32 *coeffBlock;
JPEGHuffTable *dcHuffTable;
JPEGHuffTable *acHuffTable;
OP_UINT16 *quantTable;
int tablePtr;
int prevDCValue;
JPEGMCUCompInfo *mcuCompInfo;
#ifndef EROM_TARGET
IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET
bitsBuf = mcu->bitsBuf;
#ifndef EROM_TARGET
IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET
bitsBufPtr = mcu->bitsBufPtr;
#ifndef EROM_TARGET
IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET
upperBitsByte = ((OP_UINT8 *)&bitsBuf) + 3; // little endian
#ifndef EROM_TARGET
IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET
// reset the blocks of one component
coeffBlock = mcu->coeffMCUBuf;
#ifndef EROM_TARGET
IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET
imageBlock = mcu->imageMCUBuf;
#ifndef EROM_TARGET
IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET
mcuCompInfo = mcu->compInfo;
#ifndef EROM_TARGET
IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET
for (compIdx = mcu->numComponents; compIdx > 0; compIdx --)
{
prevDCValue = mcuCompInfo->prevDCValue;
quantTable = mcuCompInfo->quantTable;
dcHuffTable = mcuCompInfo->dcHuffTable;
acHuffTable = mcuCompInfo->acHuffTable;
dcBitsLUT = dcHuffTable->bitsLUT;
dcSymbolLUT = dcHuffTable->symbolLUT;
acBitsLUT = acHuffTable->bitsLUT;
acSymbolLUT = acHuffTable->symbolLUT;
for (i = mcuCompInfo->numCompBlocks; i > 0; i --)
{
int codeLength;
int coeff;
FillBitsBuffer;
// decode DC coefficient size
codeLength = dcBitsLUT[*upperBitsByte];
if (codeLength)
{
// retrieve the symbol from LUT
currentSymbol = dcSymbolLUT[*upperBitsByte];
// left align the remaining bits
bitsBufPtr += codeLength;
bitsBuf <<= codeLength;
// warning! assume, if code length is equal or smaller
// than 8, the total length of the code and the symbol
// does not exceed 16, should be verified
}
else
{
currentSymbol = JPEGDecodeRareSymbol_fun(dcHuffTable, &bitsBuf, &bitsBufPtr);
FillBitsBuffer;
}
// get the DC coefficients
if (currentSymbol)
{
coeff = bitsBuf >> (32 - currentSymbol);
if ((bitsBuf & 0x80000000) == 0) // negative
{
coeff += ((-1) << currentSymbol) + 1;
}
// left align the remaining bits
bitsBufPtr += currentSymbol;
bitsBuf <<= currentSymbol;
prevDCValue += coeff;
}
coeffBlock[0] = (prevDCValue * quantTable[0] + 16) >> 5;
tablePtr = 0;
// until the last coefficient or EOB is encountered
while (tablePtr < (BLOCK_AREA - 1))
{
int acSize;
FillBitsBuffer;
// decode AC coefficient size
codeLength = acBitsLUT[*upperBitsByte];
if (codeLength)
{
// retrieve the symbol from LUT
currentSymbol = acSymbolLUT[*upperBitsByte];
// left align the remaining bits
bitsBufPtr += codeLength;
bitsBuf <<= codeLength;
// warning! assume, if code length is equal or smaller
// than 8, the total length of the code and the symbol
// does not exceed 16, should be verified
}
else
{
currentSymbol = JPEGDecodeRareSymbol_fun(acHuffTable, &bitsBuf, &bitsBufPtr);
FillBitsBuffer;
}
// decode the coefficient itself, if it is not EOB
acSize = (currentSymbol & 0x0F);
if (acSize) // not EOB or ZRL
{
// skip zero run
tablePtr += (currentSymbol >> 4) + 1;
coeff = bitsBuf >> (32 - acSize);
if ((bitsBuf & 0x80000000) == 0) // negative
{
coeff += ((-1) << acSize) + 1;
}
// left align the remaining bits
bitsBufPtr += acSize;
bitsBuf <<= acSize;
// dequantization is applied
coeffBlock[jpegNaturalOrder_tab[tablePtr]] =
(coeff * quantTable[tablePtr] + 16) >> 5;
}
else
{
if (currentSymbol == SYMBOL_EOB)
{
break;
}
else
{
tablePtr += 16;
}
}
} // while (tablePtr < (BLOCK_AREA - 1))
// check for decoding error
if (tablePtr > 63)
{
return JPEG_ERR_HUFFMAN_DECODE;
}
// perform IDCT, buffer coeffBlock is cleaned in this function
JPEGIDCT_int_fun(coeffBlock, imageBlock);
imageBlock += BLOCK_AREA;
}
mcuCompInfo->prevDCValue = prevDCValue;
mcuCompInfo ++;
}
#ifndef EROM_TARGET
IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET
mcu->bitsBuf = bitsBuf;
#ifndef EROM_TARGET
IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET
mcu->bitsBufPtr = bitsBufPtr;
#ifndef EROM_TARGET
IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET
return JPEG_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -