📄 hi_jpegdecode.c
字号:
#include <config.h>#if defined(CONFIG_HI3560_LOGO)#include <common.h>#define MAKEWORD(a, b) ((unsigned short)((unsigned char)(a)) | ((unsigned short)((unsigned char)(b)) << 8))#define FUNC_OK 0#define FUNC_MEMORY_ERROR 1#define FUNC_FILE_ERROR 2#define FUNC_FORMAT_ERROR 3#define M_SOF0 0xc0#define M_DHT 0xc4#define M_EOI 0xd9#define M_SOS 0xda#define M_DQT 0xdb#define M_DRI 0xdd#define M_APP0 0xe0#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) */const 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,31,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} };unsigned int LoadJpegFile(void *pImg, void *logoaddr);int InitTag(void);void InitTable(void);int Decode(void);int DecodeMCUBlock(void);int HufBlock(unsigned char dchufindex,unsigned char achufindex);int DecodeElement(void);void IQtIZzMCUComponent(int flag);void IQtIZzBlock(int *s,int *d,int flag);void GetYUV(int flag);void StoreBuffer(void);unsigned char ReadByte(void);void Initialize_Fast_IDCT(void);void Fast_IDCT(int * block);void idctrow(int * blk);void idctcol(int * blk);unsigned int ImgWidth = 0,ImgHeight = 0; int SampRate_Y_H,SampRate_Y_V,SampRate_U_H,SampRate_U_V,SampRate_V_H,SampRate_V_V;int H_YtoU,V_YtoU,H_YtoV,V_YtoV,Y_in_MCU,U_in_MCU,V_in_MCU;unsigned char *lpJpegBuf,*lp,*lpPtr;int qt_table[3][64];int comp_num;unsigned char comp_index[3];unsigned char YDcIndex,YAcIndex,UVDcIndex,UVAcIndex,HufTabIndex;int *YQtTable,*UQtTable,*VQtTable;unsigned char MyAnd[9]={0,1,3,7,0x0f,0x1f,0x3f,0x7f,0xff};int code_pos_table[4][16],code_len_table[4][16];unsigned short code_value_table[4][256];unsigned short huf_max_value[4][16],huf_min_value[4][16];int BitPos,CurByte,rrun,vvalue;int MCUBuffer[640],BlockBuffer[64];int QtZzMCUBuffer[640];int ycoef,ucoef,vcoef,IntervalFlag,interval = 0;int Y[256],U[256],V[256];int sizei,sizej;int restart;int iclip[1024];int NumTime;int LineBytes;unsigned int LoadJpegFile(void *pImg, void * logoaddr){ unsigned int ImgSize; int funcret; lpJpegBuf = (uchar *)logoaddr; InitTable(); funcret = InitTag(); if(funcret != FUNC_OK) /* 将Jpeg文件读入内存 */ { return 1; } LineBytes = ((ImgWidth * 16 + 31) >> 5) * 4; ImgSize = LineBytes * ImgHeight; /* 变化后的图象空间 */ lpPtr = (uchar *)pImg; /* 分配变换后的存储空间 */ if((SampRate_Y_H == 0) || (SampRate_Y_V == 0)) { return 1; } reset_timer_masked (); funcret = Decode(); NumTime = get_timer_masked(); if(funcret == FUNC_OK) /* 解码成功 */ { pImg = lpPtr; return 0; } else { printf("JPEG Decode ERROR.\n"); return 1; } }int InitTag(void){ unsigned int finish; unsigned char id; int llength,i,j,k,huftab1,huftab2,huftabindex,ccount; unsigned char hf_table_index,qt_table_index,comnum; unsigned char *lptemp; finish = 1; lp = lpJpegBuf + 2; /* 跳过两个字节SOI(0xFF,0xD8 Start of Image) */ while(finish != 0) { id = *(lp + 1); /* 取出低位字节(高位在前,低位在后) */ lp += 2; /* 跳过取出的字节 */ switch(id) { case M_APP0: llength = MAKEWORD(*(lp + 1),*lp); /* MAKEWORD 转换Motorlora 与 intel 数据格式 */ lp += llength; /* Skip JFIF segment marker */ break; case M_DQT: llength = MAKEWORD(*(lp + 1),*lp); /* (量化表长度) */ qt_table_index = *(lp + 2) & 0x0f;/* 量化表信息bit 0..3: QT 号(0..3, 否则错误) */ /* bit 4..7: QT 精度, 0 = 8 bit, 否则 16 bit */ lptemp = lp + 3; /* n 字节的 QT, n = 64*(精度+1) */ if(llength < 80) { for(i = 0;i < 64;i++) { qt_table[qt_table_index][i] = (int)(*(lptemp++)); } } else { for(i = 0;i < 64;i++) { qt_table[qt_table_index][i] = (int)(*(lptemp++)); } qt_table_index = (*(lptemp++)) & 0x0f; for(i = 0;i < 64;i++) { qt_table[qt_table_index][i] = (int)(*(lptemp++)); } } lp += llength; /* 跳过量化表 */ break; case M_SOF0: /* 帧开始 (baseline JPEG 0xFF,0xC0) */ llength = MAKEWORD(*(lp + 1),*lp); /* 长度 (高字节, 低字节), 8+components*3 */ ImgHeight = MAKEWORD(*(lp + 4),*(lp + 3));/* 图片高度 (高字节, 低字节), 如果不支持 DNL 就必须 >0 */ ImgWidth = MAKEWORD(*(lp + 6),*(lp + 5)); /* 图片宽度 (高字节, 低字节), 如果不支持 DNL 就必须 >0 */ comp_num = *(lp + 7); /* components 数量(1 byte), 灰度图是 1, YCbCr/YIQ 彩色图是 3, CMYK 彩色图是 4 */ if((comp_num != 1) && (comp_num != 3)) { return FUNC_FORMAT_ERROR; } if(comp_num == 3) { comp_index[0] = *(lp + 8); /* component id (1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q) */ SampRate_Y_H = (*(lp + 9)) >> 4; /* 水平采样系数 */ SampRate_Y_V = (*(lp + 9)) & 0x0f; /* 水平采样系数 */ YQtTable = (int *)qt_table[*(lp + 10)]; /* 通过量化表号取得量化表地址 */ /* ShowMessage(IntToStr(YQtTable^)); */ comp_index[1] = *(lp + 11); /* component id */ SampRate_U_H = (*(lp + 12)) >> 4; /* 水平采样系数 */ SampRate_U_V = (*(lp + 12)) & 0x0f; /* 水平采样系数 */ UQtTable = (int *)qt_table[*(lp + 13)]; /* 通过量化表号取得量化表地址 */ comp_index[2] = *(lp + 14); /* component id */ SampRate_V_H = (*(lp + 15)) >> 4; /* 水平采样系数 */ SampRate_V_V = (*(lp + 15)) & 0x0f; /* 水平采样系数 */ VQtTable = (int *)qt_table[*(lp + 16)]; /* 通过量化表号取得量化表地址 */ } else { comp_index[0] = *(lp + 8); SampRate_Y_H = (*(lp + 9)) >> 4; SampRate_Y_V = (*(lp + 9)) & 0x0f; YQtTable = (int *)qt_table[*(lp + 10)]; /* 灰度图的量化表都一样 */ comp_index[1] = *(lp + 8); SampRate_U_H = 1; SampRate_U_V = 1; UQtTable = (int *)qt_table[*(lp + 10)]; comp_index[2] = *(lp + 8); SampRate_V_H = 1; SampRate_V_V = 1; VQtTable = (int *)qt_table[*(lp + 10)]; } lp += llength; break; case M_DHT: /* 定义 Huffman Table(0xFF,0xC4) */ llength = MAKEWORD(*(lp + 1),*lp); /* 长度 (高字节, 低字节) */ if (llength < 0xd0) /* Huffman Table信息 (1 byte) */ { huftab1 = (int)(*(lp + 2)) >> 4; /* huftab1=0,1(HT 类型,0 = DC 1 = AC) */ huftab2 = (int)(*(lp + 2)) & 0x0f; /* huftab2=0,1(HT 号 ,0 = Y 1 = UV) */ huftabindex = huftab1 * 2 + huftab2; /* 0 = YDC 1 = UVDC 2 = YAC 3 = UVAC */ lptemp = lp + 3; for(i = 0;i < 16;i++) /* 16 bytes: 长度是 1..16 代码的符号数 */ { code_len_table[huftabindex][i] = (int)(*(lptemp++));/* 码长为 */ /* i的码字个数 */ } j = 0; for(i = 0;i < 16;i++) /* 得出HT的所有码字的对应值 */ { if(code_len_table[huftabindex][i] != 0) { k = 0; while(k < code_len_table[huftabindex][i]) { code_value_table[huftabindex][k + j] = (int)(*(lptemp++)); k++; } j += k; } } i = 0; while(code_len_table[huftabindex][i] == 0) /* 去掉代码的符号数为零 */ { i++; } for(j = 0;j < i;j++) { huf_min_value[huftabindex][j] = 0; /* 码长为j的最小码字 */ huf_max_value[huftabindex][j] = 0; /* 码长为j的最大码字 */ } huf_min_value[huftabindex][i] = 0; huf_max_value[huftabindex][i] = code_len_table[huftabindex][i] - 1; for(j = i + 1;j < 16;j++) { /* 码长为j的最小码字与最大码字 */ huf_min_value[huftabindex][j] = (huf_max_value[huftabindex][j - 1] + 1) << 1; huf_max_value[huftabindex][j] = huf_min_value[huftabindex][j] + code_len_table[huftabindex][j] - 1; } code_pos_table[huftabindex][0] = 0; /* 码起始位置 */ for(j = 1;j < 16;j++) { code_pos_table[huftabindex][j] = code_len_table[huftabindex][j - 1] + code_pos_table[huftabindex][j - 1]; } lp += llength; } else { hf_table_index = *(lp + 2); lp += 2; while(hf_table_index != 0xff) { huftab1 = (int)hf_table_index >> 4; /* huftab1=0,1 */ huftab2 = (int)hf_table_index & 0x0f; /* huftab2=0,1 */ huftabindex = huftab1 * 2 + huftab2; lptemp = lp; lptemp++; ccount = 0; for(i = 0;i < 16;i++) { code_len_table[huftabindex][i] = (int)(*(lptemp++)); ccount = ccount + code_len_table[huftabindex][i]; } ccount = ccount + 17; j = 0; for(i = 0;i < 16;i++) { if(code_len_table[huftabindex][i] != 0) { k = 0; while(k < code_len_table[huftabindex][i]) { code_value_table[huftabindex][k + j] = (int)(*(lptemp++)); k++; } j = j + k; } } i = 0; while(code_len_table[huftabindex][i] == 0) { i++; } for(j = 0;j < i;j++) { huf_min_value[huftabindex][j] = 0; huf_max_value[huftabindex][j] = 0; } huf_min_value[huftabindex][i] = 0; huf_max_value[huftabindex][i] = code_len_table[huftabindex][i] - 1; for(j = i + 1;j < 16;j++) { huf_min_value[huftabindex][j] = (huf_max_value[huftabindex][j - 1] + 1) << 1; huf_max_value[huftabindex][j] = huf_min_value[huftabindex][j] + code_len_table[huftabindex][j] - 1; } code_pos_table[huftabindex][0] = 0; for(j = 1;j < 16;j++) { code_pos_table[huftabindex][j] = code_len_table[huftabindex][j - 1] + code_pos_table[huftabindex][j - 1]; } lp += ccount; hf_table_index = *lp; } } break; case M_DRI: llength = MAKEWORD(*(lp + 1),*lp); restart = MAKEWORD(*(lp + 3),*(lp + 2)); lp += llength; break; case M_SOS: /* 扫描行开始0xff, 0xda (SOS) */ llength = MAKEWORD(*(lp + 1),*lp);/* 长度 (高字节, 低字节), */ comnum = *(lp + 2); /* 扫描行内组件的数量 (1 byte), 必须 >:= 1 , <:=4 (否则是错的) 通常是 3 */ if(comnum != comp_num) /* 必须是 6+2*(扫描行内组件的数量) */ { return FUNC_FORMAT_ERROR; } lptemp = lp + 3; for(i = 0;i < comp_num;i++) { /* 每组件的信息 */ if(*lptemp == comp_index[0]) { /* 1 byte :Component id */ YDcIndex = (*(lptemp + 1)) >> 4; /* Y 使用的 Huffman 表 */ YAcIndex = ((*(lptemp + 1)) & 0x0f) + 2; } else { UVDcIndex = (*(lptemp + 1)) >> 4; /* U,V */ UVAcIndex = ((*(lptemp + 1)) & 0x0f) + 2; } lptemp += 2; } lp += llength; finish = 0; break; case M_EOI: return FUNC_FORMAT_ERROR; break; default: if((id & 0xf0) != 0xd0) { llength = MAKEWORD(*(lp + 1),*lp); lp += llength; } else { lp += 2; } break; } } return FUNC_OK; }void InitTable(void){ int i,j; sizei = 0; sizej = 0; ImgWidth = 0; ImgHeight = 0; rrun = 0; vvalue = 0; BitPos = 0; CurByte = 0; IntervalFlag = 1; restart = 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -