📄 jpegsegments.c
字号:
stringPtr += 3;
}
if (stringPtr > segmentLength)
{
return JPEG_ERR_SCAN_HEADER;
}
else
{
return JPEG_OK;
}
}
/////////////////////////////////////////////////////////////////////////////
// NAME
// JPEGReadScanHeader
//
// DESCRIPTION
// Read the header information of the current scan.
// There could be multiple scans in the file. so this function can be
// accessed in other modules.
//
// INPUTS
// segmentString - string buffer containing the segment header
// segmentLength - length of the segment header
// scanHeader - pointer to structure storing the scan header
//
// OUTPUTS
// scanHeader - stores scan header information in this structure
//
// RETURN VALUE
// Returns JPEG_OK if successful, returns an error code otherwise.
//
/////////////////////////////////////////////////////////////////////////////
int JPEGReadScanHeader
(
OP_UINT8 *segmentString,
int segmentLength,
JPEGScanHeader *scanHeader
)
{
int stringPtr;
int compIdx;
stringPtr = 0;
scanHeader->numComponents = segmentString[stringPtr];
stringPtr ++;
// read the component description
for (compIdx = 0; compIdx < scanHeader->numComponents; compIdx ++)
{
JPEGScanCompBlock *thisCompBlock;
thisCompBlock = scanHeader->scanCompBlocks + compIdx;
thisCompBlock->componentID = segmentString[stringPtr];
thisCompBlock->entropyTableIDs = segmentString[stringPtr + 1];
stringPtr += 2;
}
scanHeader->spectralStart = segmentString[stringPtr];
scanHeader->spectralEnd = segmentString[stringPtr + 1];
scanHeader->saBitPosition = segmentString[stringPtr + 2];
stringPtr += 3;
if (stringPtr > segmentLength)
{
return JPEG_ERR_SCAN_HEADER;
}
else
{
return JPEG_OK;
}
}
/////////////////////////////////////////////////////////////////////////////
// NAME
// JPEGSegmentsConstruct
//
// DESCRIPTION
// Construct a JPEGSegments struture. Set all the variables to
// un-initialized values.
//
// INPUTS
// jpegSegments - pointer to structure storing the segment information
//
// OUTPUTS
// jpegSegments - initializes fields in this structure
//
// RETURN VALUE
// Always return JPEG_OK
//
/////////////////////////////////////////////////////////////////////////////
int JPEGSegmentsConstruct
(
JPEGSegments *jpegSegments
)
{
int i;
jpegSegments->numQuantTables = 0;
jpegSegments->numHuffTables = 0;
jpegSegments->restartInterval = 0;
for(i = 0; i < 4; i++)
{
jpegSegments->huffTables[i].huffCodes = 0;
jpegSegments->huffTables[i].huffBits = 0;
jpegSegments->huffTables[i].symbols = 0;
}
return JPEG_OK;
}
/////////////////////////////////////////////////////////////////////////////
// NAME
// JPEGSegmentsConfig
//
// DESCRIPTION
// Read all the header information until finishing reading the first scan
// header.
//
// INPUTS
// byteBuffer - a buffer contains the JPEG bitstream
// jpegSegments - pointer to structure storing the segment information
// fieldIdx - pointer to field index
// AllocateMemory - function pointer for memory allocation
// Deallocate - function pointer for memory deallocation
//
// OUTPUTS
// jpegSegments - stores segment information in this structure
// fieldIdx - returns field index
//
// RETURN VALUE
// Returns JPEG_OK if successful, returns an error code otherwise.
//
/////////////////////////////////////////////////////////////////////////////
int JPEGSegmentsConfig
(
ByteBuffer *byteBuffer,
JPEGSegments *jpegSegments,
int *fieldIdx,
GetMemoryFunction AllocateMemory,
FreeMemoryFunction Deallocate)
{
int currentChar;
int lastMarker;
int segmentLength;
int returnStatus;
int prevBufPtr;
OP_UINT8 *segmentString;
prevBufPtr = byteBuffer->bufPtr;
lastMarker = NON_MARKER;
*fieldIdx = 0; // non-interlacing frame
returnStatus = JPEG_OK;
// process all header information until SOS marker segment is processed
while ((lastMarker != JPEG_MARKER_SOS) && (returnStatus == JPEG_OK))
{
OP_UINT8 byte0;
OP_UINT8 byte1;
currentChar = 0;
while (currentChar != 0xFF)
{
currentChar = byteBuffer->dataBuf[byteBuffer->bufPtr ++];
// until the next character is not 0xFF
while ((byteBuffer->bufPtr < byteBuffer->bufLength) &&
(byteBuffer->dataBuf[byteBuffer->bufPtr] == 0xFF))
{
byteBuffer->bufPtr ++;
}
if (byteBuffer->bufPtr == byteBuffer->bufLength)
{
return JPEG_ERR_UNSUPPORTED_FORMAT;
}
}
// read a marker
lastMarker = byteBuffer->dataBuf[byteBuffer->bufPtr ++];
if (lastMarker == JPEG_MARKER_SOI)
{
continue;
}
// SOF markers other than JPEG_MARKER_SOF0 are not supported
if ((lastMarker >= JPEG_MARKER_SOF1) && (lastMarker <= JPEG_MARKER_SOF15) &&
(lastMarker != JPEG_MARKER_DHT))
{
return JPEG_ERR_UNSUPPORTED_SOF_MARKER;
}
// read the section following the marker
byte0 = byteBuffer->dataBuf[byteBuffer->bufPtr ++];
byte1 = byteBuffer->dataBuf[byteBuffer->bufPtr ++];
segmentLength = (byte0 << 8) + byte1 - 2;
if ((byteBuffer->bufPtr + segmentLength) >= byteBuffer->bufLength)
{
return ((lastMarker << 16) | JPEG_ERR_SEGMENT_LENGTH);
}
segmentString = byteBuffer->dataBuf + byteBuffer->bufPtr;
// process the marker segment
switch (lastMarker)
{
case JPEG_MARKER_APP0:
break;
case JPEG_MARKER_SOF0:
returnStatus = JPEGReadFrameHeader(segmentString, segmentLength,
&(jpegSegments->frameHeader));
break;
case JPEG_MARKER_SOS:
returnStatus = JPEGReadScanHeader(segmentString, segmentLength,
&(jpegSegments->scanHeader));
break;
case JPEG_MARKER_DQT:
returnStatus = JPEGReadQuantTable(segmentString, segmentLength,
jpegSegments, aanscales, jpegNaturalOrder);
break;
case JPEG_MARKER_DHT:
returnStatus = JPEGReadHuffTable(segmentString, segmentLength,
jpegSegments, AllocateMemory, Deallocate);
// construct Huffman table that will be used in decoding
JPEGPrepareHuffTables(jpegSegments, AllocateMemory, Deallocate);
break;
case JPEG_MARKER_DRI:
jpegSegments->restartInterval = BigEndianWord(segmentString);
break;
// other markers not processed
default:
break;
}
byteBuffer->bufPtr += segmentLength;
}
// perform additional checking whether the decoder can handle this frame
if (jpegSegments->scanHeader.numComponents != jpegSegments->frameHeader.numComponents)
{
returnStatus = JPEG_ERR_SOF_SOS_MISMATCH;
}
// error checking
return returnStatus;
}
/////////////////////////////////////////////////////////////////////////////
// NAME
// JPEGSegmentsRelease
//
// DESCRIPTION
// Release a JPEGSegments struture. Free all dynamic memory
// buffers.
//
// INPUTS
// jpegSegments - pointer to structure storing the segment information
// Deallocate - function pointer for memory deallocation
//
// OUTPUTS
// none.
//
// RETURN VALUE
// Always return JPEG_OK
//
/////////////////////////////////////////////////////////////////////////////
int JPEGSegmentsRelease
(
JPEGSegments *jpegSegments,
FreeMemoryFunction Deallocate
)
{
int tableIdx;
// release the buffers allocated in JPEGHuffTable structures
for (tableIdx = 0; tableIdx < jpegSegments->numHuffTables; tableIdx ++)
{
JPEGHuffTable *thisHuffTable;
thisHuffTable = &(jpegSegments->huffTables[tableIdx]);
if (thisHuffTable->symbols)
{
Deallocate(thisHuffTable->symbols);
thisHuffTable->symbols = 0;
}
if (thisHuffTable->huffCodes)
{
Deallocate(thisHuffTable->huffCodes);
thisHuffTable->huffCodes = 0;
}
if (thisHuffTable->huffBits)
{
Deallocate(thisHuffTable->huffBits);
thisHuffTable->huffBits = 0;
}
}
return JPEG_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -