📄 jpegdecoder.c
字号:
return JPEG_ERR_FATAL;
}
}
return JPEG_OK;
}
/////////////////////////////////////////////////////////////////////////////
// NAME
// JPEGDecodeFrame
//
// DESCRIPTION
// This function is called to decode one JPEG frame. This function can
// decode a standard JPEG frame.
//
// INPUTS
// jpegDecoder - pointer to JPEGDecoder structure
// findJPEGSaveMCU - function pointer for storing MCU to image buffer
// func - callback function to determine if we should continue
// frmBufSize - size of frame buffer
// numBits - number of bits per pixel
// sizex - width of output image
// sizey - height of output image
// jpegFrmBuf - pointer to JPEG frame buffer
// decodedFormat - output image format
// decodedFrmBuf - pointer to decoded frame buffer
// xDst - x location of image in output buffer
// yDst - y location of image in output buffer
//
// OUTPUTS
// decodedFrmBuf - stores output image in this buffer
//
// RETURN VALUE
// Returns JPEG_OK if successful, returns an error code otherwise.
//
/////////////////////////////////////////////////////////////////////////////
int JPEGDecodeFrame
(
JPEGDecoder *jpegDecoder,
FindJPEGSaveMCU findJPEGSaveMCU,
OP_BOOLEAN func(OP_UINT16 x, OP_UINT16 y),
int frmBufSize,
int numBits,
int sizex,
int sizey,
void *jpegFrmBuf,
int decodedFormat,
void *decodedFrmBuf,
int xDst,
int yDst
)
{
int errCode;
int firstFieldIdx;
/* int secondFieldIdx; */
ByteBuffer byteBuffer;
OP_UINT8 *frameBuffer;
// use a ByteBuffer structure to control the input
byteBuffer.dataBuf = (OP_UINT8 *) jpegFrmBuf;
byteBuffer.bufLength = frmBufSize;
byteBuffer.bufPtr = 0;
errCode = JPEGSegmentsConfig(&byteBuffer, &jpegDecoder->jpegSegments, &firstFieldIdx,
jpegDecoder->AllocateMemory, jpegDecoder->Deallocate);
if (errCode != JPEG_OK)
{
return errCode;
}
errCode = FirstFrameInitialize(jpegDecoder, decodedFormat, numBits, sizex, sizey,
(firstFieldIdx != 0));
if (errCode != JPEG_OK)
{
return errCode;
}
frameBuffer = decodedFrmBuf;
JPEGFieldDecInitialize(&jpegDecoder->decodedImage, firstFieldIdx, frameBuffer, xDst, yDst);
jpegDecoder->SaveMCUFunction = findJPEGSaveMCU(&jpegDecoder->decodedImage);
errCode = JPEGFieldDecode(&byteBuffer, jpegDecoder, func);
/* if ((firstFieldIdx != 0) && (errCode == JPEG_OK))
{
// we need to decode the other field
// the other field data is complete, decode the other field
errCode = JPEGSegmentsConfig
(&byteBuffer, jpegDecoder.jpegSegments, &secondFieldIdx);
// we have only one field in the frame
if (secondFieldIdx == firstFieldIdx)
errCode = JPEG_WARN_ONE_FIELD;
if (errCode == JPEG_OK)
{
// check the image size to see if it is supported
JPEGFrameHeader *frameHeader =
&(jpegDecoder.jpegSegments->frameHeader);
JPEGFieldDecInitialize
(jpegDecoder.decodedImage, secondFieldIdx, frameBuffer, xDst, yDst);
errCode = JPEGFieldDecode(&byteBuffer, jpegDecoder);
}
else
{
// decode the first filed again
byteBuffer.dataBuf = (OP_UINT8 *) jpegFrmBuf;
byteBuffer.bufLength = frmBufSize;
byteBuffer.bufPtr = 0;
// we need to decode the other field
// the other field data is complete, decode the other field
errCode = JPEGSegmentsConfig
(&byteBuffer, jpegDecoder.jpegSegments, &secondFieldIdx);
// stored in the other field
if (secondFieldIdx == 1)
secondFieldIdx = 2;
else
secondFieldIdx = 1;
JPEGFieldDecInitialize
(jpegDecoder.decodedImage, secondFieldIdx, frameBuffer, xDst, yDst);
errCode = JPEGFieldDecode(&byteBuffer, jpegDecoder);
}
} */
return errCode;
}
/////////////////////////////////////////////////////////////////////////////
// NAME
// JPEGGetJPEGFrameSize
//
// DESCRIPTION
// Get the size of the frame size of the JPEG image. It also performs
// some basic format checking.
//
// INPUTS
// jpegBuf - pointer to input bitstream
// frameWidth - pointer to frame width
// frameHeight - pointer to frame height
//
// OUTPUTS
// frameWidth - returns frame width
// frameHeight - returns frame height
//
// RETURN VALUE
// Returns 0 if successful, returns a nonzero value otherwise.
//
/////////////////////////////////////////////////////////////////////////////
int JPEGGetJPEGFrameSize
(
OP_UINT8 *jpegBuf,
OP_UINT16 *frameWidth,
OP_UINT16 *frameHeight
)
{
OP_UINT8 ch1;
OP_UINT8 ch2;
OP_UINT32 ind;
ind = 0;
// check the first marker to make sure this is an JPEG image
ch1 = jpegBuf[ind++];
ch2 = jpegBuf[ind++];
if ((ch1 != 0xFF) || (ch2 != JPEG_MARKER_SOI))
{
return 1;
}
// search for SOF marker, may not be very reliable!
ch2 = 0;
while (ch2 != JPEG_MARKER_SOF0)
{
ch1 = 0;
while (ch1 != 0xFF)
{
ch1 = jpegBuf[ind++];
}
ch2 = jpegBuf[ind++];
if (ch2 == JPEG_MARKER_SOF0)
{
int segmentLength = (jpegBuf[ind++] << 8);
segmentLength = segmentLength + jpegBuf[ind++];
// either can not handle more than 3 components, or find a
// JPEG_SOF_MARKER by mistake, continue searching
if (segmentLength != 17)
{
ch2 = 0;
}
else
{
// read the frameWidth and frameHeight
int precision = jpegBuf[ind++];
if (precision != 8)
{
return 1; // could not handle this
}
*frameHeight = ((OP_UINT16)jpegBuf[ind++] << 8);
*frameHeight = *frameHeight + jpegBuf[ind++];
*frameWidth = ((OP_UINT16)jpegBuf[ind++] << 8);
*frameWidth = *frameWidth + jpegBuf[ind++];
}
}
else
{
if ((ch2 > JPEG_MARKER_SOF0) && (ch2 <= JPEG_MARKER_SOF15) && (ch2 != JPEG_MARKER_DHT))
{
return 1;
}
if (ch2 != JPEG_MARKER_SOI)
{
// only SOI does not define a segment
int segmentLength = jpegBuf[ind++] << 8;
segmentLength = segmentLength + jpegBuf[ind++];
ind = ind + segmentLength - 2;
}
}
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// NAME
// JPEGGetThumbnailInfo
//
// DESCRIPTION
// Get information about the thumbnail image
// (size, type, data)
//
// INPUTS
// jpegBuf - pointer to input bitstream
// info - pointer to thumbnail info structure
//
// OUTPUTS
// info - returns thumbnaiil info
//
// RETURN VALUE
// Returns 0 if successful, returns a nonzero value otherwise.
//
/////////////////////////////////////////////////////////////////////////////
int JPEGGetThumbnailInfo
(
OP_UINT8 *jpegBuf,
ThumbnailInfo *info
)
{
OP_UINT8 ch1;
OP_UINT8 ch2;
OP_UINT16 flag;
OP_UINT32 ind;
flag = 1;
ind = 0;
// check the first marker to make sure this is an JPEG image
ch1 = jpegBuf[ind++];
ch2 = jpegBuf[ind++];
if ((ch1 != 0xFF) || (ch2 != JPEG_MARKER_SOI))
{
return flag;
}
// search for APP0 marker, may not be very reliable!
ch2 = 0;
while (ch2 != JPEG_MARKER_APP0)
{
ch1 = 0;
while (ch1 != 0xFF)
{
ch1 = jpegBuf[ind++];
}
ch2 = jpegBuf[ind++];
if (ch2 == JPEG_MARKER_APP0)
{
int segmentLength = (jpegBuf[ind++] << 8);
segmentLength += jpegBuf[ind++];
// check if JFIF extension
if(jpegBuf[ind] == 'J' && jpegBuf[ind + 1] == 'F' &&
jpegBuf[ind + 2] == 'I' && jpegBuf[ind + 3] == 'F')
{
flag = 0;
// get thumbnail size
info->thumbnailWidth = (OP_UINT16)jpegBuf[ind + 12];
info->thumbnailHeight = (OP_UINT16)jpegBuf[ind + 13];
info->thumbnailType = THUMBNAIL_RGB;
info->thumbnailData = (OP_UINT8 *)(&(jpegBuf[14]));
}
// check if JFXX extension
else if(jpegBuf[ind] == 'J' && jpegBuf[ind + 1] == 'F' &&
jpegBuf[ind + 2] == 'X' && jpegBuf[ind + 3] == 'X')
{
flag = 0;
// get thumbnail size
if(jpegBuf[ind + 5] == 0x10)
{
info->thumbnailType = THUMBNAIL_JPEG;
info->thumbnailData = (OP_UINT8 *)(&(jpegBuf[6]));
if(JPEGGetJPEGFrameSize(info->thumbnailData,
&info->thumbnailWidth, &info->thumbnailHeight))
{
flag = 1;
}
}
else if(jpegBuf[ind + 5] == 0x11)
{
info->thumbnailType = THUMBNAIL_INDEX;
info->thumbnailData = (OP_UINT8 *)(&(jpegBuf[8]));
info->thumbnailWidth = (OP_UINT16)jpegBuf[ind + 6];
info->thumbnailHeight = (OP_UINT16)jpegBuf[ind + 7];
}
else if(jpegBuf[ind + 5] == 0x13)
{
info->thumbnailType = THUMBNAIL_RGB;
info->thumbnailData = (OP_UINT8 *)(&(jpegBuf[8]));
info->thumbnailWidth = (OP_UINT16)jpegBuf[ind + 6];
info->thumbnailHeight = (OP_UINT16)jpegBuf[ind + 7];
}
}
ind += segmentLength - 2;
}
else
{
if ((ch2 > JPEG_MARKER_SOF0) && (ch2 <= JPEG_MARKER_SOF15) && (ch2 != JPEG_MARKER_DHT))
{
break;
}
if (ch2 != JPEG_MARKER_SOI)
{
// only SOI does not define a segment
int segmentLength = jpegBuf[ind++] << 8;
segmentLength += jpegBuf[ind++];
ind += segmentLength - 2;
}
}
}
if(info->thumbnailWidth == 0 && info->thumbnailHeight == 0)
{
flag = 1;
}
return flag;
}
/////////////////////////////////////////////////////////////////////////////
// NAME
// JPEGDecodeThumbnail
//
// DESCRIPTION
// Decode the thumbnail image (RGB or index type)
// And save the output in the modified RGB32 format
//
// INPUTS
// info - pointer to thumbnail info structure
// outbuf - pointer to output image buffer
//
// OUTPUTS
// outbuf - returns output image
//
// RETURN VALUE
// Returns 0 if successful, returns a nonzero value otherwise.
//
/////////////////////////////////////////////////////////////////////////////
int JPEGDecodeThumbnail
(
ThumbnailInfo *info,
JPEGOutputType *outbuf
)
{
OP_UINT8 *inptr;
OP_UINT16 i;
OP_UINT16 numpixels;
// compute the number of pixels in thumbnail
numpixels = info->thumbnailWidth * info->thumbnailHeight;
// set input pointer
inptr = info->thumbnailData;
// check thumbnail type
if(info->thumbnailType == THUMBNAIL_RGB)
{
OP_UINT8 *outptr;
// set output pointer
outptr = (OP_UINT8 *)outbuf;
// decode the thumbnail
for(i = 0; i < numpixels; i++)
{
*outptr++ = *inptr++;
*outptr++ = *inptr++;
*outptr++ = *inptr++;
*outptr++ = DEFAULT_ALPHA_VALUE;
}
}
else if(info->thumbnailType == THUMBNAIL_INDEX)
{
JPEGOutputType colortable[256];
JPEGOutputType *outptr;
// set output pointer
outptr = outbuf;
// get color table
for(i = 0; i < 256; i++)
{
colortable[i].red = *inptr++;
colortable[i].green = *inptr++;
colortable[i].blue = *inptr++;
colortable[i].alpha = DEFAULT_ALPHA_VALUE;
}
// then decode the thumbnail
for(i = 0; i < numpixels; i++)
{
*outptr++ = colortable[*inptr++];
}
}
else
{
return 1;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -