#include typedef unsigned int UINT32; typedef unsigned char UINT8; typedef unsigned short UINT16; #define MAKEWORD(a, b) ((UINT16)((unsigned char)(a)) | ((UINT16)((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} }; const int unzig_zag[80] = { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ 63, 63, 63, 63, 63, 63, 63, 63 }; #define MAX2(x,y) ( (x)>(y) ? (x):(y) ) #define OK 0 #define ERROR 1 int InitTag(void); void InitTable(void); int Decode(void); int DecodeMCUBlock(void); int HufBlock(UINT8 dchufindex,UINT8 achufindex); int DecodeElement(void); void IQtIZzMCUComponent(int flag); void IQtIZzBlock(int *s,int *d,int flag); void GetYUV(int flag); void StoreBuffer(void); UINT8 ReadByte(void); void Initialize_Fast_IDCT(void); void Fast_IDCT(int * block); void idctrow(int * blk); void idctcol(int * blk); UINT32 jpeg_w = 0,jpeg_h = 0; UINT32 jpeg_p; 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; UINT8 *lpJpegBuf,*lp,*lpPtr; int qt_table[3][64]; int comp_num; UINT8 comp_index[3]; UINT8 YDcIndex,YAcIndex,UVDcIndex,UVAcIndex,HufTabIndex; int *YQtTable,*UQtTable,*VQtTable; UINT8 MyAnd[9]={0,1,3,7,0x0f,0x1f,0x3f,0x7f,0xff}; int code_pos_table[4][16]; int code_len_table[4][16]; UINT16 code_value_table[4][256]; UINT16 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 value_type; unsigned int jpeg_decode_sw(void *jpg, void *y, void *uv) { UINT32 funcret; lpJpegBuf = jpg; InitTable(); funcret = InitTag(); if(funcret != FUNC_OK) { printf("JPEG: init tag ERROR.\n"); return ERROR; } lpPtr = y; if((SampRate_Y_H == 0) || (SampRate_Y_V == 0)) { return ERROR; } int mod = jpeg_w%8; if (mod != 0) { jpeg_p = (jpeg_w + (8-mod)) * 2; } else { jpeg_p = jpeg_w * 2; } funcret = Decode(); printf("JPEG: width=%d height=%d pitch=%d\n", jpeg_w, jpeg_h, jpeg_p); if(funcret == FUNC_OK) { printf("JPEG: decode OK.\n"); return OK; } else { printf("JPEG: decode FAILED.\n"); return ERROR; } } int InitTag(void) { UINT32 finish; UINT8 id; int llength,i,j,k,huftab1,huftab2,huftabindex,ccount; UINT8 hf_table_index,qt_table_index,comnum; UINT8 *lptemp; int temp2; finish = ERROR; lp = lpJpegBuf + 2; /* SOI */ while(finish != OK) { id = *(lp + 1); lp += 2; switch(id) { case M_APP0: llength = MAKEWORD(*(lp + 1),*lp); lp += llength; /* Skip JFIF segment marker */ break; case M_DQT: temp2 = 2; llength = MAKEWORD(*(lp + 1), *lp); if (llength > 256) { printf("M_DQT len %d is out of range!\n", llength); return FUNC_FORMAT_ERROR; } qt_table_index = *(lp + 2) & 0x0f; if (qt_table_index >= 3) { printf("qt_table_index err %d\n", qt_table_index); return FUNC_FORMAT_ERROR; } lptemp = lp + 3; if (llength < 80) { for(i = 0;i < 64;i++) { qt_table[qt_table_index][i] = (int)(*(lptemp++)); } } else { while(temp2 < llength) { for(i = 0;i < 64;i++) { //qt_table[qt_table_index][**(Zig_Zag)] = (int)(*(lptemp++)); qt_table[qt_table_index][*(unzig_zag+i)] = (int)(*(lptemp++)); } qt_table_index = (*(lptemp++)) & 0x0f; if(qt_table_index > 3) { break; } temp2 += 65; } } lp += llength; break; case M_SOF0: llength = MAKEWORD(*(lp + 1),*lp); jpeg_h = MAKEWORD(*(lp + 4),*(lp + 3)); jpeg_w = MAKEWORD(*(lp + 6),*(lp + 5)); comp_num = *(lp + 7); if((comp_num != 1) && (comp_num != 3)) { return FUNC_FORMAT_ERROR; } if(comp_num == 3) { comp_index[0] = *(lp + 8); 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)]; } if (comp_num == 1) { if (SampRate_Y_H==SampRate_Y_V) { value_type = 0; SampRate_Y_H = 1; SampRate_Y_V = 1; SampRate_U_H = 0; SampRate_U_V = 0; SampRate_V_H = 0; SampRate_V_V = 0; } } else if ((comp_num == 3) && (SampRate_U_H==SampRate_V_H) && (SampRate_U_V==SampRate_V_V)) { if (SampRate_Y_H==(SampRate_U_H<<1)) { if (SampRate_Y_V==(SampRate_U_V<<1)) { value_type= 3; } else if (SampRate_Y_V==SampRate_U_V) { value_type = 4; } } else if (SampRate_Y_H==SampRate_U_H) { if (SampRate_Y_V==(SampRate_U_V<<1)) { value_type = 5; } else if (SampRate_Y_V==SampRate_U_V) { value_type = 6; } } } lp += llength; break; case M_DHT: /* Huffman Table(0xFF,0xC4) */ llength = MAKEWORD(*(lp + 1),*lp); { 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: llength = MAKEWORD(*(lp + 1),*lp); comnum = *(lp + 2); if(comnum != comp_num) { 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; YAcIndex = ((*(lptemp + 1)) & 0x0f) + 2; } else { UVDcIndex = (*(lptemp + 1)) >> 4; /* U,V */ UVAcIndex = ((*(lptemp + 1)) & 0x0f) + 2; } lptemp += 2; } lp += llength; finish = OK; 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; jpeg_w = 0; jpeg_h = 0; rrun = 0; vvalue = 0; BitPos = 0; CurByte = 0; IntervalFlag = ERROR; 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; 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< 640;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 = 0; ucoef = 0; vcoef = 0; } /************************************************************************* Initialize_Fast_IDCT():Init DecodeMCUBlock() Huffman Decode IQtIZzMCUComponent() GetYUV() Get Y U V StoreBuffer() YUV to RGB *************************************************************************/ int Decode(void) { int funcret; Y_in_MCU = SampRate_Y_H * SampRate_Y_V; /* YDU YDU YDU YDU */ U_in_MCU = SampRate_U_H * SampRate_U_V; /* cRDU */ V_in_MCU = SampRate_V_H * SampRate_V_V; /* cBDU */ 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(); funcret = DecodeMCUBlock(); while(funcret == FUNC_OK) { /* After Call DecodeMCUBUBlock() */ interval++; /* The Digital has been Huffman Decoded and */ if((restart != 0) && ((interval % restart) == 0)) { /* be stored in MCUBuffer(YDU,YDU,YDU,YDU */ IntervalFlag = OK; /* UDU,VDU) Every DU := 8*8 */ } else { IntervalFlag = ERROR; } IQtIZzMCUComponent(0); IQtIZzMCUComponent(1); IQtIZzMCUComponent(2); GetYUV(0); GetYUV(1); GetYUV(2); StoreBuffer(); /* To RGB */ sizej = sizej + (UINT32)(SampRate_Y_H << 3); if(sizej >= jpeg_w) { sizej = 0; sizei = sizei + (UINT32)(SampRate_Y_V << 3); } if ((sizej == 0) && (sizei >= jpeg_h)) { break; } funcret = DecodeMCUBlock(); } return funcret; } /********************************************************************** In: QtZzMCUBuffer Out: Y[] U[] V[] **********************************************************************/ void GetYUV(int flag) { int H,VV,i,j,k,hk; int temp; int *buf,*tempbuf,*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; pQtZzMCU = pQtZzMCU + (Y_in_MCU << 6); break; case 2: H = SampRate_V_H; VV = SampRate_V_V; buf = V; pQtZzMCU = QtZzMCUBuffer; pQtZzMCU = pQtZzMCU + ((Y_in_MCU + U_in_MCU) << 6); break; default: H = 0; VV = 0; buf = NULL; pQtZzMCU = NULL; break; } for(i = 0;i < VV;i++) { for(j = 0;j < H;j++) { for(k = 0;k < 8;k++) { for(hk = 0;hk < 8;hk++) { temp = ((((i << 3) + k) * SampRate_Y_H) << 3) + (j << 3) + hk; tempbuf = buf; tempbuf = tempbuf + temp; *tempbuf = (int)(*(pQtZzMCU++)); } } } } } void StoreBuffer(void) { int i,j; UINT8 *lprgb; UINT8 R,G,B; int yy,uu,vv,rr,gg,bb; int TempSamp1,TempSamp2; TempSamp1 = SampRate_Y_V << 3; TempSamp2 = SampRate_Y_H << 3; int *pY; int *pU; int *pV; for(i = 0;i < TempSamp1;i++) { if((sizei + i) < jpeg_h) { lprgb = lpPtr + ( (sizei + i) * jpeg_p + (sizej << 1) ); pY=Y+i*TempSamp2;// (i << 3) * SampRate_Y_H; pU=U+(i / V_YtoU)*TempSamp2;// << 3) * SampRate_Y_H; pV=V+(i / V_YtoV)*TempSamp2;// << 3) * SampRate_Y_H; for(j = 0;j < TempSamp2;j++) { if((sizej + j) < jpeg_w) { yy = *pY++; uu = pU[ j/H_YtoU]; vv = pV[ j/H_YtoV]; rr = ((yy << 8) + 18 * uu + 367 * vv) >> 8; gg = ((yy << 8) - 159 * uu - 220 * vv) >> 8; bb = ((yy << 8) + 411 * uu - 29 * vv) >> 8; R = (UINT8)(rr); G = (UINT8)(gg); B = (UINT8)(bb); if((rr & 0xffffff00) != 0) { if (rr > 255) { R = 255; } else { if(rr < 0) { R = 0; } } } if((gg & 0xffffff00) != 0) { if(gg > 255) { G = 255; } else { if(gg < 0) { G = 0; } } } if((bb & 0xffffff00) != 0) { if(bb > 255) { B = 255; } else { if(bb < 0) { B = 0; } } } *lprgb++ = (UINT8)(B >> 3) + (UINT8)((G << 2) & 0xe0); *lprgb++ = (UINT8)(G >> 6) + (UINT8)((R >> 1) & 0x7c); } else { break; } } } else { break; } } } /****************************************************************************** Huffman Decode Out:MCU MCUBuffer In:Blockbuffer[ ] *******************************************************************************/ int DecodeMCUBlock(void) { int *lpMCUBuffer; int i,j; int funcret=0; int tempX; if(IntervalFlag == OK) { lp += 2; ycoef = 0; ucoef = 0; vcoef = 0; BitPos = 0; CurByte = 0; } switch(comp_num) { /* comp_num*/ case 3: lpMCUBuffer = MCUBuffer; tempX = SampRate_Y_H * SampRate_Y_V; for(i = 0;i < tempX;i++){ /* Y */ funcret = HufBlock(YDcIndex,YAcIndex); if(funcret != FUNC_OK) { printf("funcret1 = %x\n", funcret); return funcret; } BlockBuffer[0] = BlockBuffer[0] + ycoef; ycoef = BlockBuffer[0]; for(j = 0;j < 64;j++) { *lpMCUBuffer++ = BlockBuffer[j]; } } tempX = SampRate_U_H * SampRate_U_V; for(i = 0;i < tempX;i++) { /* U */ funcret = HufBlock(UVDcIndex,UVAcIndex); if(funcret != FUNC_OK) { printf("funcret2 = %x\n", funcret); return funcret; } BlockBuffer[0] = BlockBuffer[0] + ucoef; ucoef = BlockBuffer[0]; for(j = 0;j < 64;j++) { *lpMCUBuffer++ = BlockBuffer[j]; } } tempX = SampRate_V_H * SampRate_V_V; for(i = 0;i < tempX;i++) { /* V */ funcret = HufBlock(UVDcIndex,UVAcIndex); if(funcret != FUNC_OK) { printf("funcret3 = %x\n", funcret); return funcret; } BlockBuffer[0] = BlockBuffer[0] + vcoef; vcoef = BlockBuffer[0]; for(j = 0;j < 64;j++) { *lpMCUBuffer++ = BlockBuffer[j]; } } break; case 1: /* Gray Picture */ lpMCUBuffer = MCUBuffer; funcret = HufBlock(YDcIndex,YAcIndex); if(funcret != FUNC_OK) { return funcret; } BlockBuffer[0] = BlockBuffer[0] + ycoef; ycoef = BlockBuffer[0]; for(j = 0;j < 64;j++) { *lpMCUBuffer++ = BlockBuffer[j]; } for(i = 0;i < 128;i++) { *lpMCUBuffer++ = 0; } break; default: return FUNC_FORMAT_ERROR; } return FUNC_OK; } int HufBlock(UINT8 dchufindex,UINT8 achufindex) { int count,i; int funcret; count = 0; /* dc */ HufTabIndex = dchufindex; funcret = DecodeElement(); /* Read Byte Dc */ if(funcret != FUNC_OK) { return funcret; } BlockBuffer[count++] = vvalue; /* ac */ HufTabIndex = achufindex; while(count < 64) { /* 63 Bytes AC */ funcret = DecodeElement(); if(funcret != FUNC_OK) { return funcret; } if((rrun == 0) && (vvalue == 0)) { for(i = count;i < 64;i++) { BlockBuffer[i] = 0; } count = 64; } else { for(i = 0;i < rrun;i++) { BlockBuffer[count++] = 0; } BlockBuffer[count++] = vvalue; } } return FUNC_OK; } int DecodeElement(void) { int thiscode,tempcode; UINT16 temp,valueex; int codelen; UINT8 hufexbyte,runsize,tempsize,sign; UINT8 newbyte,lastbyte; if(BitPos >= 1) { BitPos--; thiscode = (UINT8)CurByte >> BitPos; CurByte = CurByte & MyAnd[BitPos]; } else { lastbyte = ReadByte(); BitPos--; /* and[]:=0x0,0x1,0x3,0x7,0xf,0x1f,0x2f,0x3f,0x4f */ newbyte = CurByte & MyAnd[BitPos]; // thiscode = lastbyte >> 7; CurByte = newbyte; } codelen = 1; while((thiscode < huf_min_value[HufTabIndex][codelen - 1]) || (code_len_table[HufTabIndex][codelen - 1] == 0) || (thiscode > huf_max_value[HufTabIndex][codelen - 1])) { if(BitPos >= 1) { BitPos--; tempcode = (UINT8)CurByte >> BitPos; CurByte = CurByte & MyAnd[BitPos]; } else { lastbyte = ReadByte(); BitPos--; newbyte = CurByte & MyAnd[BitPos]; tempcode = (UINT8)lastbyte >> 7; CurByte = newbyte; } thiscode = (thiscode << 1) + tempcode; codelen++; if(codelen > 16) { return FUNC_FORMAT_ERROR; } } //while temp = thiscode - huf_min_value[HufTabIndex][codelen - 1] + code_pos_table[HufTabIndex][codelen - 1]; hufexbyte = (UINT8)code_value_table[HufTabIndex][temp]; rrun = (int)(hufexbyte >> 4); runsize = hufexbyte & 0x0f; if(runsize == 0) { vvalue = 0; return FUNC_OK; } tempsize = runsize; if(BitPos >= runsize) { BitPos = BitPos - runsize; valueex = (UINT8)CurByte >> BitPos; CurByte = CurByte & MyAnd[BitPos]; } else { valueex = CurByte; tempsize = tempsize - BitPos; while(tempsize > 8) { lastbyte = ReadByte(); valueex = (valueex << 8) + (UINT8)lastbyte; tempsize = tempsize - 8; } //while lastbyte = ReadByte(); BitPos = BitPos - tempsize; valueex = (valueex << tempsize) + (lastbyte >> BitPos); CurByte = lastbyte & MyAnd[BitPos]; } sign = valueex >> (runsize - 1); if(sign != 0) { vvalue = valueex; } else { valueex = valueex ^ 0xffff; temp = 0xffff << runsize; vvalue = -(int)(valueex ^ temp); } return FUNC_OK; } void IQtIZzMCUComponent(int flag) { int H,VV,i,j; int *pQtZzMCUBuffer,*tempbuf1; int *pMCUBuffer,*tempbuf2; switch(flag) { case 0: H = SampRate_Y_H; VV = SampRate_Y_V; pMCUBuffer = MCUBuffer; /* Huffman Decoded */ pQtZzMCUBuffer = QtZzMCUBuffer; break; case 1: H = SampRate_U_H; VV = SampRate_U_V; pMCUBuffer = MCUBuffer; pMCUBuffer += Y_in_MCU << 6; pQtZzMCUBuffer = QtZzMCUBuffer; pQtZzMCUBuffer += Y_in_MCU << 6; break; case 2: H = SampRate_V_H; VV = SampRate_V_V; pMCUBuffer = MCUBuffer; pMCUBuffer += (Y_in_MCU + U_in_MCU) << 6; pQtZzMCUBuffer = QtZzMCUBuffer; pQtZzMCUBuffer += (Y_in_MCU + U_in_MCU) << 6; break; default: H = 0; pQtZzMCUBuffer = NULL; pMCUBuffer = NULL; VV = 0; break; } for(i = 0;i < VV;i++) { for(j = 0;j < H;j++) { tempbuf2 = pMCUBuffer; tempbuf2 += (i * H + j) << 6; tempbuf1 = pQtZzMCUBuffer; tempbuf1 += (i * H + j) << 6; IQtIZzBlock(tempbuf2,tempbuf1,flag); /* 8*8DU */ } } } void IQtIZzBlock(int *s,int *d,int flag) { int i,j,tag; int *pQt,*temp1,*temp3; int buffer2[8][8]; int *temp2; int offset; switch(flag) { case 0: pQt = YQtTable; /* ShowMessage(IntTostr(YQtTable^)); */ offset = 128; break; case 1: pQt = UQtTable; offset = 0; break; case 2: pQt = VQtTable; offset = 0; break; default: pQt = NULL; offset = 0; break; } for(i = 0;i < 8;i++) { for(j = 0;j < 8;j++) { tag = Zig_Zag[i][j]; temp1 = s; temp1 = temp1 + tag; temp3 = pQt; temp3 = temp3 + tag; buffer2[i][j] = (int)((*temp1) * (*temp3)); } } Fast_IDCT(&buffer2[0][0]); for(i = 0;i < 8;i++) { for(j = 0;j < 8;j++) { temp2 = d; temp2 = temp2 + (i * 8 +j); *temp2 = buffer2[i][j] + offset; } } } void Fast_IDCT(int *block) { int i; for(i = 0;i < 8;i++) { idctrow(block + 8 * i); } for(i = 0;i < 8;i++) { idctcol(block + i); } } UINT8 ReadByte(void) { UINT8 i; i = *lp; lp = lp + 1; if(i == 0xff) { lp = lp + 1; } BitPos = 8; CurByte = i; return i; } void Initialize_Fast_IDCT(void) { int i; for(i = -512;i < 512;i++) { if(i < -256) { iclip[512 + i] = -256; } if(i > 255) { iclip[512 + i] = 255; } if(( i >= -256) && (i <= 255)) { iclip[512 + i] = i; } } } void idctrow(int *blk) { int x0, x1, x2, x3, x4, x5, x6, x7, x8; //intcut x1 = blk[4] << 11; x2 = blk[6]; x3 = blk[2]; x4 = blk[1]; x5 = blk[7]; x6 = blk[5]; x7 = blk[3]; if ((x1 || x2 || x3 || x4 || x5 || x6 || x7) == 0) { blk[1] = blk[0] << 3; blk[2] = blk[0] << 3; blk[3] = blk[0] << 3; blk[4] = blk[0] << 3; blk[5] = blk[0] << 3; blk[6] = blk[0] << 3; blk[7] = blk[0] << 3; blk[0] = blk[0] << 3; return; } x0 = (blk[0] << 11) + 128; /* for proper rounding in the fourth stage */ /* first stage */ x8 = W7 * (x4 + x5); x4 = x8 + (W1 - W7) * x4; x5 = x8 - (W1 + W7) * x5; x8 = W3 * (x6 + x7); x6 = x8 - (W3 - W5) * x6; x7 = x8 - (W3 + W5) * x7; /* second stage */ x8 = x0 + x1; x0 = x0 - x1; x1 = W6 * (x3 + x2); x2 = x1 - (W2 + W6) * x2; x3 = x1 + (W2 - W6) * x3; x1 = x4 + x6; x4 = x4 - x6; x6 = x5 + x7; x5 = x5 - x7; /* third stage */ x7 = x8 + x3; x8 = x8 - x3; x3 = x0 + x2; x0 = x0 - x2; x2 = (181 * (x4 + x5) + 128) >> 8; x4 = (181 * (x4 - x5) + 128) >> 8; /* fourth stage */ blk[0] = (x7 + x1) >> 8; blk[1] = (x3 + x2) >> 8; blk[2] = (x0 + x4) >> 8; blk[3] = (x8 + x6) >> 8; blk[4] = (x8 - x6) >> 8; blk[5] = (x0 - x4) >> 8; blk[6] = (x3 - x2) >> 8; blk[7] = (x7 - x1) >> 8; } void idctcol(int * blk) { int x0, x1, x2, x3, x4, x5, x6, x7, x8; int Temp; /* intcut */ x1 = blk[8 * 4] << 8; x2 = blk[8 * 6]; x3 = blk[8 * 2]; x4 = blk[8 * 1]; x5 = blk[8 * 7]; x6 = blk[8 * 5]; x7 = blk[8 * 3]; if ((x1 | x2 | x3 | x4 | x5 | x6 | x7) == 0) { Temp = (blk[8 * 0] + 32) >> 6; blk[8 * 1] = iclip[512 + Temp]; blk[8 * 2] = iclip[512 + Temp]; blk[8 * 3] = iclip[512 + Temp]; blk[8 * 4] = iclip[512 + Temp]; blk[8 * 5] = iclip[512 + Temp]; blk[8 * 6] = iclip[512 + Temp]; blk[8 * 7] = iclip[512 + Temp]; blk[8 * 0] = iclip[512 + Temp]; return; } x0 = (blk[8 * 0] << 8) + 8192; /* first stage */ x8 = W7 * (x4 + x5) + 4; x4 = (x8 + (W1 - W7) * x4) >> 3; x5 = (x8 - (W1 + W7) * x5) >> 3; x8 = W3 * (x6 + x7) + 4; x6 = (x8 -(W3 - W5) * x6) >> 3; x7 = (x8 - (W3 + W5) * x7) >> 3; /* second stage */ x8 = x0 + x1; x0 = x0 - x1; x1 = W6 * (x3 + x2) + 4; x2 = (x1 - (W2 + W6) * x2) >> 3; x3 = (x1 + (W2 - W6) * x3) >> 3; x1 = x4 + x6; x4 = x4 - x6; x6 = x5 + x7; x5 = x5 - x7; /* third stage */ x7 = x8 + x3; x8 = x8 - x3; x3 = x0 + x2; x0 = x0 - x2; x2 = (181 * (x4 + x5) + 128) >> 8; x4 = (181 * (x4 - x5) + 128) >> 8; /* fourth stage */ Temp = (x7 + x1) >> 14; blk[0] = iclip[512 + Temp]; Temp = (x3 + x2) >> 14; blk[8] = iclip[512 + Temp]; Temp = (x0 + x4) >> 14; blk[16] = iclip[512 + Temp]; Temp = (x8 + x6) >> 14; blk[24] = iclip[512 + Temp]; Temp = (x8 - x6) >> 14; blk[32] = iclip[512 + Temp]; Temp = (x0 - x4) >> 14; blk[40] = iclip[512 + Temp]; Temp = (x3 - x2) >> 14; blk[48] = iclip[512 + Temp]; Temp = (x7 - x1) >> 14; blk[56] = iclip[512 + Temp]; }