📄 jpeg.c
字号:
typedef enum { /* JPEG marker codes */
M_SOF0 = 0xc0,
M_SOF1 = 0xc1,
M_SOF2 = 0xc2,
M_SOF3 = 0xc3,
M_SOF5 = 0xc5,
M_SOF6 = 0xc6,
M_SOF7 = 0xc7,
M_JPG = 0xc8,
M_SOF9 = 0xc9,
M_SOF10 = 0xca,
M_SOF11 = 0xcb,
M_SOF13 = 0xcd,
M_SOF14 = 0xce,
M_SOF15 = 0xcf,
M_DHT = 0xc4,
M_DAC = 0xcc,
M_RST0 = 0xd0,
M_RST1 = 0xd1,
M_RST2 = 0xd2,
M_RST3 = 0xd3,
M_RST4 = 0xd4,
M_RST5 = 0xd5,
M_RST6 = 0xd6,
M_RST7 = 0xd7,
M_SOI = 0xd8,
M_EOI = 0xd9,
M_SOS = 0xda,
M_DQT = 0xdb,
M_DNL = 0xdc,
M_DRI = 0xdd,
M_DHP = 0xde,
M_EXP = 0xdf,
M_APP0 = 0xe0,
M_APP1 = 0xe1,
M_APP2 = 0xe2,
M_APP3 = 0xe3,
M_APP4 = 0xe4,
M_APP5 = 0xe5,
M_APP6 = 0xe6,
M_APP7 = 0xe7,
M_APP8 = 0xe8,
M_APP9 = 0xe9,
M_APP10 = 0xea,
M_APP11 = 0xeb,
M_APP12 = 0xec,
M_APP13 = 0xed,
M_APP14 = 0xee,
M_APP15 = 0xef,
M_JPG0 = 0xf0,
M_JPG13 = 0xfd,
M_COM = 0xfe,
M_TEM = 0x01,
M_ERROR = 0x100
} JPEG_MARKER;
static int Zig_Zag[8][8]={{0,1,5,6,14,15,27,28},
{2,4,7,13,16,26,29,42},
{3,8,12,17,25,30,41,43},
{9,11,18,24,37,40,44,53},
{10,19,23,32,39,45,52,54},
{20,22,33,38,46,51,55,60},
{21,34,37,47,50,56,59,61},
{35,36,48,49,57,58,62,63}
};
#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
#define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int InitTag(void);
int Decode(void);
int DecodeMCUBlock(void);
int DecodeElement(void);
void StoreBuffer(void);
unsigned char ReadByte(void);
void Initialize_Fast_IDCT(void);
int *RateTable = NULL;
U16 RateTable_len;
/////////////////////////////////////////////////////////////////
void InitTable(void)
{
short i,j;
sizei=sizej=0;
ImgWidth=ImgHeight=0;
rrun=vvalue=0;
BitPos=0;
CurByte=0;
IntervalFlag=FALSE;
restart_jpg=0;
for(i=0;i<3;i++)
for(j=0;j<64;j++)
qt_table[i][j]=0;
comp_num=0;
HufTabIndex=0;
for(i=0;i<3;i++)
comp_index[i]=0;
for(i=0;i<4;i++)
for(j=0;j<16;j++){
code_len_table[i][j]=0;
code_pos_table[i][j]=0;
huf_max_value[i][j]=0;
huf_min_value[i][j]=0;
}
for(i=0;i<4;i++)
for(j=0;j<256;j++)
code_value_table[i][j]=0;
for(i=0;i<10*64;i++){
MCUBuffer[i]=0;
QtZzMCUBuffer[i]=0;
}
for(i=0;i<64;i++){
Y[i]=0;
U[i]=0;
V[i]=0;
BlockBuffer[i]=0;
}
ycoef=ucoef=vcoef=0;
}
BOOL LoadJpeg (const unsigned char* JpegData, int s_x,int s_y, int max_w, int max_h,BOOL bMenSelBack/*, unsigned long size*/)
{
void* hJpegBuf=NULL;
int funcret;
BOOL bSaveData = FALSE;
needzoom=0;
rate=1.0;
MmiTrace(" loadjpg");
lpJpegBuf=(unsigned char*)(JpegData);
memset(G_JpgDecData,0,sizeof(G_JpgDecData));
InitTable();// :table初始化
if((funcret=InitTag())!=FUNC_OK) //初始化Tag
{
return FALSE;
}
lpPtr=(char *)(&G_JpgDecData[2]);// add
if((SampRate_Y_H==0)||(SampRate_Y_V==0)) // :根据inittag的结果来判断
{
return FALSE ;
}
// add to avoid overflow
if(0==max_w || 0== max_h) // : no input size limitation, use MAX_WIDTH and MAX_HEIGHT
{
if((ImgWidth>MAX_WIDTH)||(ImgHeight>MAX_HEIGHT))
{
double factor_w = 1.0, factor_h=1.0;
char tmp[100];
factor_w=MAX_WIDTH/(double)ImgWidth;
factor_h=MAX_HEIGHT/(double)ImgHeight;
if((factor_w-factor_h)>0.0000)
factor_w=factor_h;
rate=factor_w;
needzoom=1;
}
else
{
rate =1.0;
needzoom=0;
}
}
else if((ImgWidth>max_w)||(ImgHeight>max_h))
{
double factor_w = 1.0, factor_h=1.0;
char tmp[100];
factor_w=max_w/(double)ImgWidth;
factor_h=max_h/(double)ImgHeight;
if((factor_w-factor_h)>0.0000)
factor_w=factor_h;
rate=factor_w;
needzoom=1;
}
else
{
rate=1.0;
needzoom=0;
}
if(needzoom)
{
int i;
int former=0;
int cur=0;
double temp=0.0;
G_JpgDecData[0]=(unsigned char)(ImgWidth*rate);
G_JpgDecData[1]=(unsigned char)(ImgHeight*rate);// add,the 1st 2 for height and width
RateTable_len = (ImgWidth>ImgHeight)?ImgWidth:ImgHeight;
RateTable = (int*)Alloc(RateTable_len*sizeof(int));
if(RateTable == NULL)
{
return FALSE;
}
for(i=0; i<RateTable_len; i++)
{
temp=i*rate+0.5005;
cur=(int)(temp);
former=(int)(temp+rate);
if(cur==former) //discard this line;
RateTable[i] = -1;
else
RateTable[i]= cur;
}
}
else
{
G_JpgDecData[0]=(unsigned char)ImgWidth;
G_JpgDecData[1]=(unsigned char)ImgHeight;// add,the 1st 2 for height and width
}
LineBytes=(unsigned short)G_JpgDecData[0]*2;// changed this ,is it right?
funcret=Decode();
if(funcret==FUNC_OK)
{
//display here
if(RateTable != NULL)
{
Free(RateTable, (U16)(sizeof(int)*RateTable_len));
RateTable = NULL;
RateTable_len = 0;
}
return TRUE;
}
else
{
if(RateTable != NULL)
{
Free(RateTable, (U16)(sizeof(int)*RateTable_len));
RateTable = NULL;
RateTable_len = 0;
}
return FALSE;
}
}
BOOL WbmpDecode(UBYTE *oldImage, U8* pBuf, UINT16 oldWidth, UINT16 oldHeight,
UINT16 newWidth, UINT16 newHeight)
{
USHORT byteWidth;
USHORT scrByteWidth;
int i, j, k, w = 0;
UBYTE *pOld = oldImage;
USHORT *pNew = (USHORT *)pBuf;
/* Work out the width of the original image in bytes */
byteWidth = oldWidth/8;
if (oldWidth % 8)
byteWidth++;
/* Work out the width of the scaled image in bytes */
scrByteWidth = newWidth/8;
if (newWidth % 8)
scrByteWidth++;
/* If there's no scaling to do, copy the image and that's it! */
if(NULL == pBuf)
{
return FALSE;
}
if(NULL == oldImage)
{
return FALSE;
}
if (newWidth == oldWidth && newHeight == oldHeight)
{
for(j = 0; j < oldHeight; j++)
{
for(i = 0; i < byteWidth; i++)
{
for(k = 0; k < 8; k++)
{
if(0 != ((*pOld) & (1 << (7-k))))
{
*pNew = 0xFFFF;
}
else
{
*pNew = 0;
}
pNew++;
w++;
if(w == oldWidth)
{
w = 0;
break;
}
}
pOld++;
}
}
}
else
{
return FALSE;
}
return TRUE;
}
BOOL showWbmpInWebPage (const unsigned char* WbmpData, U8* pBuf,int width,int height, int max_w, int max_h)
{
UINT16 index = 0;
UINT16 shift;
UINT16 origWidth; /* Original width of image (from image data) */
UINT16 origHeight; /* Original width of image (from image data) */
if((0 != WbmpData[0]) || (0 != WbmpData[1]))
{
return FALSE;
}
/*overleap WBMP type, Fixed header , width, and height*/
index++;
origWidth = 0;
shift = 1;
do
{
index++;
origWidth |= ((WbmpData[index] & 0x7F)*shift);
shift *= 0x80;
}
while (WbmpData[index] & 0x80);
origHeight = 0;
shift = 1;
do
{
index++;
origHeight |= ((WbmpData[index] & 0x7F)*shift);
shift *= 0x80;
}
while (WbmpData[index] & 0x80);
if((0 == origWidth) || (0 == origHeight))
{
return FALSE;
}
if((origWidth > max_w) || (origHeight > max_h))
{
return FALSE;
}
index++;
return WbmpDecode(
(UBYTE *)&WbmpData[index],
pBuf,
origWidth,
origHeight,
(UINT16)width,
(UINT16)height);
}
BOOL showJpgInWebPage (const unsigned char* JpegData, U8* pBuf,int width,int height, int max_w, int max_h)
{
void* hJpegBuf=NULL;
int funcret;
needzoom=0;
rate=1.0;
lpJpegBuf=(unsigned char*)(JpegData);
memset(G_JpgDecData,0,sizeof(G_JpgDecData));
InitTable();// :table初始化
if((funcret=InitTag())!=FUNC_OK) //初始化Tag
{
return FALSE;
}
lpPtr=(char *)(&G_JpgDecData[2]);// add
if((SampRate_Y_H==0)||(SampRate_Y_V==0)) // :根据inittag的结果来判断
{
//TM_EnableWatchdog();// in order to remove rvf_delay in long time consumed jpg decode
return FALSE ;
}
// add to avoid overflow
if(0==max_w || 0== max_h) // : no input size limitation, use MAX_WIDTH and MAX_HEIGHT
{
if((ImgWidth>MAX_WIDTH)||(ImgHeight>MAX_HEIGHT))
{
double factor_w = 1.0, factor_h=1.0;
char tmp[100];
factor_w=MAX_WIDTH/(double)ImgWidth;
factor_h=MAX_HEIGHT/(double)ImgHeight;
if((factor_w-factor_h)>0.0000)
factor_w=factor_h;
rate=factor_w;
needzoom=1;
}
else
{
rate =1.0;
needzoom=0;
}
}
else if((ImgWidth>max_w)||(ImgHeight>max_h))
{
double factor_w = 1.0, factor_h=1.0;
char tmp[100];
factor_w=max_w/(double)ImgWidth;
factor_h=max_h/(double)ImgHeight;
if((factor_w-factor_h)>0.0000)
factor_w=factor_h;
rate=factor_w;
needzoom=1;
}
else
{
rate=1.0;
needzoom=0;
}
if(needzoom)
{
int i;
int former=0;
int cur=0;
double temp=0.0;
G_JpgDecData[0]=(unsigned char)(ImgWidth*rate);
G_JpgDecData[1]=(unsigned char)(ImgHeight*rate);// add,the 1st 2 for height and width
RateTable_len = (ImgWidth>ImgHeight)?ImgWidth:ImgHeight;
RateTable = (int*)Alloc(RateTable_len*sizeof(int));
if(RateTable == NULL)
{
return FALSE;
}
for(i=0; i<RateTable_len; i++)
{
temp=i*rate+0.5005;
cur=(int)(temp);
former=(int)(temp+rate);
if(cur==former) //discard this line;
RateTable[i] = -1;
else
RateTable[i]= cur;
}
}
else
{
G_JpgDecData[0]=(unsigned char)ImgWidth;
G_JpgDecData[1]=(unsigned char)ImgHeight;// add,the 1st 2 for height and width
}
LineBytes=(unsigned short)G_JpgDecData[0]*2;// changed this ,is it right?
funcret=Decode();
if(funcret==FUNC_OK)
{
memcpy(pBuf , (U8*)&G_JpgDecData[2], G_JpgDecData[0] * G_JpgDecData[1] * sizeof(USHORT));
if(RateTable != NULL)
{
Free(RateTable, (U16)(sizeof(int)*RateTable_len));
RateTable = NULL;
RateTable_len = 0;
}
return TRUE;
}
else
{
if(RateTable != NULL)
{
Free(RateTable, (U16)(sizeof(int)*RateTable_len));
RateTable = NULL;
RateTable_len = 0;
}
return FALSE;
}
}
/////////////////////////////////////////////////////////////////////////
int Decode(void)
{
int funcret;
static int count=0;// add to protect from crash 20040804
Y_in_MCU=SampRate_Y_H*SampRate_Y_V;
U_in_MCU=SampRate_U_H*SampRate_U_V;
V_in_MCU=SampRate_V_H*SampRate_V_V;
H_YtoU=SampRate_Y_H/SampRate_U_H;
V_YtoU=SampRate_Y_V/SampRate_U_V;
H_YtoV=SampRate_Y_H/SampRate_V_H;
V_YtoV=SampRate_Y_V/SampRate_V_V;
Initialize_Fast_IDCT();
while((funcret=DecodeMCUBlock())==FUNC_OK){
interval++;
if((restart_jpg)&&(interval % restart_jpg==0))
IntervalFlag=TRUE;
else
IntervalFlag=FALSE;
IQtIZzMCUComponent(0);
IQtIZzMCUComponent(1);
IQtIZzMCUComponent(2);
GetYUV(0);
GetYUV(1);
GetYUV(2);
StoreBuffer();
count++;
if(count==10)
{
rvf_delay(3);
count=0;
}
sizej+=SampRate_Y_H*8;
if(sizej>=ImgWidth){
sizej=0;
sizei+=SampRate_Y_V*8;
}
if ((sizej==0)&&(sizei>=ImgHeight))
break;
}
count=0;
return funcret;
}
/////////////////////////////////////////////////////////////////////////////////////////
void GetYUV(short flag)
{
short H,VV;
short i,j,k,h;
int *buf;
int *pQtZzMCU;
switch(flag){
case 0:
H=SampRate_Y_H;
VV=SampRate_Y_V;
buf=Y;
pQtZzMCU=QtZzMCUBuffer;
break;
case 1:
H=SampRate_U_H;
VV=SampRate_U_V;
buf=U;
pQtZzMCU=QtZzMCUBuffer+Y_in_MCU*64;
break;
case 2:
H=SampRate_V_H;
VV=SampRate_V_V;
buf=V;
pQtZzMCU=QtZzMCUBuffer+(Y_in_MCU+U_in_MCU)*64;
break;
}
for (i=0;i<VV;i++)
for(j=0;j<H;j++)
for(k=0;k<8;k++)
for(h=0;h<8;h++)
buf[(i*8+k)*SampRate_Y_H*8+j*8+h]=*pQtZzMCU++;
}
///////////////////////////////////////////////////////////////////////////////
/*目前的缩放算法由重复,实际上一个象素的保存进行了多次最后一次起作用*/
void StoreBuffer(void)// :只有该函数需要存储数据的buffer的指针,存储数据前偏移头信息的长度,lpPtr,lpImgData
{ //可以在该处作一定的改动,然后用到手机中
short i,j;
unsigned char *lpbmp;
unsigned char R,G,B;
int y,u,v,rr,gg,bb;
int h_former=0;
int h_cur=0;
int w_former=0;
int w_cur=0;
double temp=0.0;
unsigned long pixel_pos=(unsigned long)sizej*2;
if(needzoom)
{
pixel_pos=(unsigned long)(sizej*rate+0.5005)*2;
for(i=0;i<SampRate_Y_V*8;i++)
{
if((sizei+i)<ImgHeight)
{
{
if(RateTable[sizei+i] == -1 && ((sizei+i+1)<ImgHeight))
continue;
if(RateTable[sizei+i] >= G_JpgDecData[1])
return;
}
lpbmp=(unsigned char *)lpPtr+(unsigned long)(RateTable[sizei+i]*LineBytes)+pixel_pos;
for(j=0;j<SampRate_Y_H*8;j++)
{
if((sizej+j)<ImgWidth)
{
// revise zoom out 20040510
//if((sizej+j)!=0)
{
#if 0
temp=(sizej+j)*rate+0.5005;
w_cur=(int)(temp);
w_former=(int)(temp+rate);
if((w_cur==w_former) && ((sizej+j+1)<ImgWidth) ) //discard this line;
continue;
if(w_cur >= G_JpgDecData[0])
break;
#else
if((RateTable[sizej+j] == -1) && ((sizej+j+1)<ImgWidth))
continue;
if(RateTable[sizej+j] >= G_JpgDecData[0])
break;
#endif
}
//end
y=Y[i*8*SampRate_Y_H+j];
u=U[(i/V_YtoU)*8*SampRate_Y_H+j/H_YtoU];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -