📄 jpgopr.c
字号:
//
// Copyright (c) Samsung Electronics. Co. LTD. All rights reserved.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
*/
#include "JPGMem.h"
#include "JPGMisc.h"
#include "JPGOpr.h"
#include "JPGConf.h"
enum
{
UNKNOWN,
BASELINE = 0xC0,
EXTENDED_SEQ = 0xC1,
PROGRESSIVE = 0xC2
} JPG_SOF_MARKER;
/*----------------------------------------------------------------------------
*Function: decodeJPG
*Parameters: jCTX:
input_buff:
input_size:
output_buff:
output_size
*Return Value:
*Implementation Notes:
-----------------------------------------------------------------------------*/
JPG_RETURN_STATUS decodeJPG(S3C6410_JPG_CTX *jCTX, JPG_DEC_PROC_PARAM *decParam)
{
int ret;
SAMPLE_MODE_T sampleMode;
UINT32 width, height, orgwidth, orgheight;
BOOL headerFixed = FALSE;
printD("DD::decodeJPG\n");
if (jCTX)
resetJPG(jCTX);
else
{
RETAILMSG(1, (TEXT("DD::JPG CTX is NULL\r\n")));
return JPG_FAIL;
}
__try
{
////////////////////////////////////////
// Header Parsing //
////////////////////////////////////////
decodeHeader(jCTX);
ret = waitForIRQ(jCTX);
if(ret != OK_HD_PARSING)
{
RETAILMSG(1, (TEXT("DD::JPG Header Parsing Error(%d)\r\n"), ret));
return JPG_FAIL;
}
sampleMode = getSampleType(jCTX);
printD("DD::sampleMode : %d\n", sampleMode);
if(sampleMode == JPG_SAMPLE_UNKNOWN)
{
RETAILMSG(1, (TEXT("DD::JPG has invalid sampleMode\r\n")));
return JPG_FAIL;
}
decParam->sampleMode = sampleMode;
getXY(jCTX, &width, &height);
printD("DD:: width : 0x%x height : 0x%x\n", width, height);
if(width <= 0 || width > MAX_JPG_WIDTH || height <= 0 || height > MAX_JPG_HEIGHT)
{
RETAILMSG(1, (TEXT("DD::JPG has invalid width/height\n")));
return JPG_FAIL;
}
////////////////////////////////////////
// Header Correction //
////////////////////////////////////////
orgwidth = width;
orgheight = height;
if(!isCorrectHeader(sampleMode, &width, &height))
{
rewriteHeader(jCTX, decParam->fileSize, width, height);
headerFixed = TRUE;
}
////////////////////////////////////////
// Body Decoding //
////////////////////////////////////////
if(headerFixed)
{
resetJPG(jCTX);
decodeHeader(jCTX);
ret = waitForIRQ(jCTX);
if(ret != OK_HD_PARSING)
{
RETAILMSG(1, (TEXT("DD::JPG Header Parsing Error(%d)\r\n"), ret));
return JPG_FAIL;
}
decodeBody(jCTX);
ret = waitForIRQ(jCTX);
if(ret != OK_ENC_OR_DEC)
{
RETAILMSG(1, (TEXT("DD::JPG Body Decoding Error(%d)\n"), ret));
return JPG_FAIL;
}
// for post processor, discard pixel
if(orgwidth % 4 != 0)
orgwidth = (orgwidth/4)*4;
if(orgheight % 2 != 0)
orgheight = (orgheight/2)*2;
printD("DD:: orgwidth : %d orgheight : %d\n", orgwidth, orgheight);
rewriteYUV(jCTX, width, orgwidth, height, orgheight);
// JPEG H/W IP always return YUV422
decParam->dataSize = getYUVSize(JPG_422, orgwidth, orgheight);
decParam->width = orgwidth;
decParam->height = orgheight;
}
else
{
decodeBody(jCTX);
ret = waitForIRQ(jCTX);
if(ret != OK_ENC_OR_DEC)
{
RETAILMSG(1, (TEXT("DD::JPG Body Decoding Error(%d)\n"), ret));
return JPG_FAIL;
}
// JPEG H/W IP always return YUV422
decParam->dataSize = getYUVSize(JPG_422, width, height);
decParam->width = width;
decParam->height = height;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
RETAILMSG(1, (TEXT("decodeJPG::JPG exception\n")));
return JPG_FAIL;
}
return JPG_SUCCESS;
}
/*----------------------------------------------------------------------------
*Function: isCorrectHeader
*Parameters: sampleMode:
width:
height:
*Return Value:
*Implementation Notes:
-----------------------------------------------------------------------------*/
BOOL isCorrectHeader(SAMPLE_MODE_T sampleMode, UINT32 *width, UINT32 *height)
{
BOOL result = FALSE;
switch(sampleMode)
{
case JPG_400 :
case JPG_444 :
if((*width % 8 == 0) && (*height % 8 == 0))
result = TRUE;
if(*width % 8 != 0)
*width += 8 - (*width % 8);
if(*height % 8 != 0)
*height += 8 - (*height % 8);
break;
case JPG_422 :
if((*width % 16 == 0) && (*height % 8 == 0))
result = TRUE;
if(*width % 16 != 0)
*width += 16 - (*width % 16);
if(*height % 8 != 0)
*height += 8 - (*height % 8);
break;
case JPG_420 :
case JPG_411 :
if((*width % 16 == 0) && (*height % 16 == 0))
result = TRUE;
if(*width % 16 != 0)
*width += 16 - (*width % 16);
if(*height % 16 != 0)
*height += 16 - (*height % 16);
break;
}
printD("DD::after error correction : width(%x) height(%x)\n", *width, *height);
return(result);
}
/*----------------------------------------------------------------------------
*Function: rewriteHeader
*Parameters: jCTX:
file_size:
width:
height:
*Return Value:
*Implementation Notes:
-----------------------------------------------------------------------------*/
void rewriteHeader(S3C6410_JPG_CTX *jCTX, UINT32 file_size, UINT32 width, UINT32 height)
{
UINT32 i;
UINT8 *ptr = (UINT8 *)jCTX->v_pJPGData_Buff + file_size;
UINT8 *ptr2;
UINT8 *SOF1 = NULL, *SOF2 = NULL;
UINT8 *header = NULL;
printD("DD::Header is not multiple of MCU\n");
for(i=0; i < file_size; i++)
{
ptr--;
if(*ptr == 0xFF)
{
ptr2 = ptr+1;
if((*ptr2 == BASELINE) || (*ptr2 == EXTENDED_SEQ) || (*ptr2 == PROGRESSIVE))
{
printD("DD::match FFC0(i : %d)\n", i);
SOF1 = ptr2+1;
break;
}
}
}
printD("DD::start header correction\n");
if(i <= file_size)
{
header = SOF1;
header += 3; //length(2) + sampling bit(1)
*header = (height>>8) & 0xFF;
*header++;
*header = height & 0xFF;
*header++;
*header = (width>>8) & 0xFF;
*header++;
*header = width & 0xFF;
}
}
/*----------------------------------------------------------------------------
*Function: resetJPG
*Parameters: jCTX:
*Return Value:
*Implementation Notes:
-----------------------------------------------------------------------------*/
void resetJPG(S3C6410_JPG_CTX *jCTX)
{
printD("DD::resetJPG\n");
jCTX->v_pJPG_REG->JPGSoftReset = 0; //ENABLE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -