jpeg轉bmp實現c程式碼
阿新 • • 發佈:2019-01-06
#include <stdio.h> #include <stdlib.h> #include <time.h> #pragma pack(1) #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 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) */ //************************************************************************************* typedef char CHAR; typedef short SHORT; typedef long LONG; typedef unsigned long DWORD; typedef int BOOL; typedef unsigned char BYTE; typedef unsigned short WORD; typedef int HFILE; typedef CHAR *LPSTR, *PSTR; #define FALSE 0 #define TRUE 1 typedef struct tagBITMAPINFOHEADER{ DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER, *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER; typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER, *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER; /* constants for the biCompression field */ #define BI_RGB 0L #define BI_RLE8 1L #define BI_RLE4 2L #define BI_BITFIELDS 3L typedef struct tagRGBQUAD { BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; } RGBQUAD; typedef RGBQUAD * LPRGBQUAD; #define MAKEWORD(a, b) ((WORD)(((BYTE)(a)) | ((WORD)((BYTE)(b))) << 8)) #define MAKELONG(a, b) ((LONG)(((WORD)(a)) | ((DWORD)((WORD)(b))) << 16)) #define LOWORD(l) ((WORD)(l)) #define HIWORD(l) ((WORD)(((DWORD)(l) >> 16) & 0xFFFF)) #define LOBYTE(w) ((BYTE)(w)) #define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF)) //---yk--- add #include "memory.h" #include "math.h" #include "stdio.h" //macro definition #define WIDTHBYTES(i) ((i+31)/32*4)//?????????? #define PI 3.1415926535 //define return value of function #define FUNC_OK 0 #define FUNC_MEMORY_ERROR 1 #define FUNC_FILE_ERROR 2 #define FUNC_FORMAT_ERROR 3 ////////////////////////////////////////////////// //Jpeg functions BOOL LoadJpegFile(char *BmpFileName); void showerror(int funcret); int InitTag(); void InitTable(); int Decode(); int DecodeMCUBlock(); int HufBlock(BYTE dchufindex, BYTE achufindex); int DecodeElement(); void IQtIZzMCUComponent(short flag); void IQtIZzBlock(short *s, int * d, short flag); void GetYUV(short flag); void StoreBuffer(); BYTE ReadByte(); void Initialize_Fast_IDCT(); void Fast_IDCT(int * block); void idctrow(int * blk); void idctcol(int * blk); ////////////////////////////////////////////////// //global variable declaration BITMAPFILEHEADER bf; BITMAPINFOHEADER bi; //HPALETTE hPalette=NULL; //HBITMAP hBitmap=NULL; char * hImgData = NULL; DWORD NumColors; DWORD LineBytes; DWORD ImgWidth = 0, ImgHeight = 0; char* lpPtr; ////////////////////////////////////////////////// //variables used in jpeg function short SampRate_Y_H, SampRate_Y_V; short SampRate_U_H, SampRate_U_V; short SampRate_V_H, SampRate_V_V; short H_YtoU, V_YtoU, H_YtoV, V_YtoV; short Y_in_MCU, U_in_MCU, V_in_MCU; unsigned char *lpJpegBuf; unsigned char *lp; short qt_table[3][64]; short comp_num; BYTE comp_index[3]; BYTE YDcIndex, YAcIndex, UVDcIndex, UVAcIndex; BYTE HufTabIndex; short *YQtTable, *UQtTable, *VQtTable; BYTE And[9] = { 0, 1, 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 0xff }; short 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]; short BitPos, CurByte; short rrun, vvalue; short MCUBuffer[10 * 64]; int QtZzMCUBuffer[10 * 64]; short BlockBuffer[64]; short ycoef, ucoef, vcoef; BOOL IntervalFlag; short interval = 0; int Y[4 * 64], U[4 * 64], V[4 * 64]; DWORD sizei, sizej; short restart; static long iclip[1024]; static long *iclp; //////////////////////////////////////////////////////////////// BOOL LoadJpegFile(char *JpegFileName) { FILE* hfjpg; DWORD ImgSize; DWORD BufSize, JpegBufSize; FILE* hfbmp; FILE* IMGdata; void * hJpegBuf; int funcret; DWORD i; LPBITMAPINFOHEADER lpImgData; char * hImgData256; fopen_s(&hfjpg, JpegFileName, "rb"); //get jpg file length fseek(hfjpg, 0L, SEEK_END); JpegBufSize = ftell(hfjpg); //rewind to the beginning of the file fseek(hfjpg, 0L, SEEK_SET); if ((hJpegBuf = malloc(JpegBufSize)) == NULL) { fclose(hfjpg); showerror(FUNC_MEMORY_ERROR); return FALSE; } lpJpegBuf = (unsigned char *)hJpegBuf; fread((unsigned char *)hJpegBuf, sizeof(char), JpegBufSize, hfjpg); fclose(hfjpg); InitTable(); if ((funcret = InitTag()) != FUNC_OK) { // GlobalUnlock(hJpegBuf); free(hJpegBuf); showerror(funcret); return FALSE; } //create new bitmapfileheader and bitmapinfoheader memset((char *)&bf, 0, sizeof(BITMAPFILEHEADER)); memset((char *)&bi, 0, sizeof(BITMAPINFOHEADER)); bi.biSize = (DWORD)sizeof(BITMAPINFOHEADER); bi.biWidth = (LONG)(ImgWidth); bi.biHeight = (LONG)(ImgHeight); bi.biPlanes = 1; bi.biBitCount = 24; bi.biClrUsed = 0; bi.biClrImportant = 0; bi.biCompression = BI_RGB; NumColors = 0; printf("bi.biWidth is %ld/n", bi.biWidth); printf("bi.biBitCount is %ld/n", bi.biBitCount); LineBytes = (DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount); printf("LineBytes is %ld/n", LineBytes); ImgSize = (DWORD)LineBytes*bi.biHeight;//??????? printf("size is %ld/n", ImgSize); bf.bfType = 0x4d42; int a = sizeof(BITMAPFILEHEADER); int b = sizeof(BITMAPINFOHEADER); //注意位元組對齊問題!!!!!!!!!!!!!!!!!!!!!!!!1 //如果沒有#pragma pack(1),a是16~~~~~~~ int c = NumColors*sizeof(RGBQUAD); bf.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize; bf.bfOffBits = 54;//(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)); BufSize = bf.bfSize - sizeof(BITMAPFILEHEADER); // printf("size is %ld/n",BufSize); if ((hImgData = (char*)malloc(BufSize)) == NULL) { //GlobalUnlock(hJpegBuf); free(hJpegBuf); showerror(FUNC_MEMORY_ERROR); showerror(FUNC_MEMORY_ERROR); return FALSE; } // lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData); lpImgData = (LPBITMAPINFOHEADER)hImgData; memcpy(lpImgData, (char *)&bi, sizeof(BITMAPINFOHEADER)); lpPtr = (char *)lpImgData + sizeof(BITMAPINFOHEADER); if ((SampRate_Y_H == 0) || (SampRate_Y_V == 0)) { // GlobalUnlock(hJpegBuf); free(hJpegBuf); //GlobalUnlock(hImgData); free(hImgData); hImgData = NULL; showerror(FUNC_FORMAT_ERROR); return FALSE; } funcret = Decode(); if (funcret == FUNC_OK) { fopen_s(&hfbmp, "jpeg2-bmp.bmp", "wb"); fwrite((LPSTR)&bf, sizeof(BITMAPFILEHEADER), 1, hfbmp); fwrite((LPSTR)lpImgData, sizeof(char), BufSize, hfbmp); fopen_s(&IMGdata, "111.txt", "wb"); DWORD xx = ImgWidth*ImgHeight; if ((hImgData256 = (char *)malloc(xx)) == NULL) { //GlobalUnlock(hJpegBuf); free(hImgData256); showerror(FUNC_MEMORY_ERROR); showerror(FUNC_MEMORY_ERROR); showerror(FUNC_MEMORY_ERROR); return FALSE; } char * temp = hImgData256; for (i = 0; i < xx; i++) { i; char t3 = *lpPtr; t3 &= 0xE0; char t1 = *(lpPtr + 1); t1 = t1 >> 3; t1 &= 0x1c; char t2 = *(lpPtr + 2); t2 = t2 >> 6; t2 &= 0x03; char t4 = t3 + t1 + t2; *temp++ = t4; lpPtr = lpPtr + 3; //不能使用temp+=3; } int count = fwrite(hImgData256, sizeof(char), xx, IMGdata); fclose(IMGdata); fclose(hfbmp); free(hJpegBuf); return TRUE; } else { free(hJpegBuf); free(hImgData); hImgData = NULL; showerror(funcret); return FALSE; } } ///////////////////////////////////////////////// void showerror(int funcret) { switch (funcret) { case FUNC_MEMORY_ERROR: printf("Error alloc memory/n!"); break; case FUNC_FILE_ERROR: printf("File not found!/n"); break; case FUNC_FORMAT_ERROR: printf("File format error!/n"); break; } } //////////////////////////////////////////////////////////////////////////////// int InitTag() { BOOL finish = FALSE; BYTE id; short llength; short i, j, k; short huftab1, huftab2; short huftabindex; BYTE hf_table_index; BYTE qt_table_index; BYTE comnum; unsigned char *lptemp; short ccount; lp = lpJpegBuf + 2; while (!finish){ id = *(lp + 1); lp += 2; switch (id){ case M_APP0: llength = MAKEWORD(*(lp + 1), *lp); lp += llength; break; case M_DQT: llength = MAKEWORD(*(lp + 1), *lp); qt_table_index = (*(lp + 2)) & 0x0f; lptemp = lp + 3; if (llength<80){ for (i = 0; i<64; i++) qt_table[qt_table_index][i] = (short)*(lptemp++); } else{ for (i = 0; i<64; i++) qt_table[qt_table_index][i] = (short)*(lptemp++); qt_table_index = (*(lptemp++)) & 0x0f; for (i = 0; i<64; i++) qt_table[qt_table_index][i] = (short)*(lptemp++); } lp += llength; break; case M_SOF0: llength = MAKEWORD(*(lp + 1), *lp); ImgHeight = MAKEWORD(*(lp + 4), *(lp + 3)); ImgWidth = 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 = (short *)qt_table[*(lp + 10)]; comp_index[1] = *(lp + 11); SampRate_U_H = (*(lp + 12)) >> 4; SampRate_U_V = (*(lp + 12)) & 0x0f; UQtTable = (short *)qt_table[*(lp + 13)]; comp_index[2] = *(lp + 14); SampRate_V_H = (*(lp + 15)) >> 4; SampRate_V_V = (*(lp + 15)) & 0x0f; VQtTable = (short *)qt_table[*(lp + 16)]; } else{ comp_index[0] = *(lp + 8); SampRate_Y_H = (*(lp + 9)) >> 4; SampRate_Y_V = (*(lp + 9)) & 0x0f; YQtTable = (short *)qt_table[*(lp + 10)]; comp_index[1] = *(lp + 8); SampRate_U_H = 1; SampRate_U_V = 1; UQtTable = (short *)qt_table[*(lp + 10)]; comp_index[2] = *(lp + 8); SampRate_V_H = 1; SampRate_V_V = 1; VQtTable = (short *)qt_table[*(lp + 10)]; } lp += llength; break; case M_DHT: llength = MAKEWORD(*(lp + 1), *lp); if (llength<0xd0){ huftab1 = (short)(*(lp + 2)) >> 4; //huftab1=0,1 huftab2 = (short)(*(lp + 2)) & 0x0f; //huftab2=0,1 huftabindex = huftab1 * 2 + huftab2; lptemp = lp + 3; for (i = 0; i<16; i++) code_len_table[huftabindex][i] = (short)(*(lptemp++)); 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] = (short)(*(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; 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 += llength; } //if else{ hf_table_index = *(lp + 2); lp += 2; while (hf_table_index != 0xff){ huftab1 = (short)hf_table_index >> 4; //huftab1=0,1 huftab2 = (short)hf_table_index & 0x0f; //huftab2=0,1 huftabindex = huftab1 * 2 + huftab2; lptemp = lp + 1; ccount = 0; for (i = 0; i<16; i++){ code_len_table[huftabindex][i] = (short)(*(lptemp++)); ccount += code_len_table[huftabindex][i]; } 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] = (short)(*(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; 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; } //while } //else 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]){ YDcIndex = (*(lptemp + 1)) >> 4; //Y YAcIndex = ((*(lptemp + 1)) & 0x0f) + 2; } else{ UVDcIndex = (*(lptemp + 1)) >> 4; //U,V UVAcIndex = ((*(lptemp + 1)) & 0x0f) + 2; } lptemp += 2; } lp += llength; finish = TRUE; 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; } //switch } //while return FUNC_OK; } ///////////////////////////////////////////////////////////////// void InitTable() { short i, j; sizei = sizej = 0; ImgWidth = ImgHeight = 0; rrun = vvalue = 0; BitPos = 0; CurByte = 0; IntervalFlag = FALSE; 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<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; } ///////////////////////////////////////////////////////////////////////// int Decode() { int funcret; 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) && (interval % restart == 0)) IntervalFlag = TRUE; else IntervalFlag = FALSE; IQtIZzMCUComponent(0); IQtIZzMCUComponent(1); IQtIZzMCUComponent(2); GetYUV(0); GetYUV(1); GetYUV(2); StoreBuffer(); sizej += SampRate_Y_H * 8; if (sizej >= ImgWidth){ sizej = 0; sizei += SampRate_Y_V * 8; } if ((sizej == 0) && (sizei >= ImgHeight)) break; } return funcret; } ///////////////////////////////////////////////////////////////////////////////////////// void GetYUV(short flag) { short H, VV; short i, j, k, h; int *buf; int *pQtZzMCU; buf = Y; pQtZzMCU = QtZzMCUBuffer; 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() { short i, j; unsigned char *lpbmp; unsigned char R, G, B; int y, u, v, rr, gg, bb; for (i = 0; i<SampRate_Y_V * 8; i++){ if ((sizei + i)<ImgHeight){ lpbmp = ((unsigned char *)lpPtr + (DWORD)(ImgHeight - sizei - i - 1)*LineBytes + sizej * 3); for (j = 0; j<SampRate_Y_H * 8; j++){ if ((sizej + j)<ImgWidth){ y = Y[i * 8 * SampRate_Y_H + j]; u = U[(i / V_YtoU) * 8 * SampRate_Y_H + j / H_YtoU]; v = V[(i / V_YtoV) * 8 * SampRate_Y_H + j / H_YtoV]; rr = ((y << 8) + 18 * u + 367 * v) >> 8; gg = ((y << 8) - 159 * u - 220 * v) >> 8; bb = ((y << 8) + 411 * u - 29 * v) >> 8; R = (unsigned char)rr; G = (unsigned char)gg; B = (unsigned char)bb; if (rr & 0xffffff00) if (rr>255) R = 255; else if (rr<0) R = 0; if (gg & 0xffffff00) if (gg>255) G = 255; else if (gg<0) G = 0; if (bb & 0xffffff00) if (bb>255) B = 255; else if (bb<0) B = 0; *lpbmp++ = B; *lpbmp++ = G; *lpbmp++ = R; } else break; } } else break; } } /////////////////////////////////////////////////////////////////////////////// int DecodeMCUBlock() { short *lpMCUBuffer; short i, j; int funcret; if (IntervalFlag){ lp += 2; ycoef = ucoef = vcoef = 0; BitPos = 0; CurByte = 0; } switch (comp_num){ case 3: lpMCUBuffer = MCUBuffer; for (i = 0; i<SampRate_Y_H*SampRate_Y_V; i++) //Y { 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<SampRate_U_H*SampRate_U_V; i++) //U { funcret = HufBlock(UVDcIndex, UVAcIndex); if (funcret != FUNC_OK) return funcret; BlockBuffer[0] = BlockBuffer[0] + ucoef; ucoef = BlockBuffer[0]; for (j = 0; j<64; j++) *lpMCUBuffer++ = BlockBuffer[j]; } for (i = 0; i<SampRate_V_H*SampRate_V_V; i++) //V { funcret = HufBlock(UVDcIndex, UVAcIndex); if (funcret != FUNC_OK) return funcret; BlockBuffer[0] = BlockBuffer[0] + vcoef; vcoef = BlockBuffer[0]; for (j = 0; j<64; j++) *lpMCUBuffer++ = BlockBuffer[j]; } break; case 1: 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(BYTE dchufindex, BYTE achufindex) { short count = 0; short i; int funcret; //dc HufTabIndex = dchufindex; funcret = DecodeElement(); if (funcret != FUNC_OK) return funcret; BlockBuffer[count++] = vvalue; //ac HufTabIndex = achufindex; while (count<64){ 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() { int thiscode, tempcode; unsigned short temp, valueex; short codelen; BYTE hufexbyte, runsize, tempsize, sign; BYTE newbyte, lastbyte; if (BitPos >= 1){ BitPos--; thiscode = (BYTE)CurByte >> BitPos; CurByte = CurByte&And[BitPos]; } else{ lastbyte = ReadByte(); BitPos--; newbyte = CurByte&And[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 = (BYTE)CurByte >> BitPos; CurByte = CurByte&And[BitPos]; } else{ lastbyte = ReadByte(); BitPos--; newbyte = CurByte&And[BitPos]; tempcode = (BYTE)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 = (BYTE)code_value_table[HufTabIndex][temp]; rrun = (short)(hufexbyte >> 4); runsize = hufexbyte & 0x0f; if (runsize == 0){ vvalue = 0; return FUNC_OK; } tempsize = runsize; if (BitPos >= runsize){ BitPos -= runsize; valueex = (BYTE)CurByte >> BitPos; CurByte = CurByte&And[BitPos]; } else{ valueex = CurByte; tempsize -= BitPos; while (tempsize>8){ lastbyte = ReadByte(); valueex = (valueex << 8) + (BYTE)lastbyte; tempsize -= 8; } //while lastbyte = ReadByte(); BitPos -= tempsize; valueex = (valueex << tempsize) + (lastbyte >> BitPos); CurByte = lastbyte&And[BitPos]; } //else sign = valueex >> (runsize - 1); if (sign) vvalue = valueex; else{ valueex = valueex ^ 0xffff; temp = 0xffff << runsize; vvalue = -(short)(valueex^temp); } return FUNC_OK; } ///////////////////////////////////////////////////////////////////////////////////// void IQtIZzMCUComponent(short flag) { short H, VV; short i, j; int *pQtZzMCUBuffer; short *pMCUBuffer; pMCUBuffer = MCUBuffer; pQtZzMCUBuffer = QtZzMCUBuffer; switch (flag){ case 0: H = SampRate_Y_H; VV = SampRate_Y_V; pMCUBuffer = MCUBuffer; pQtZzMCUBuffer = QtZzMCUBuffer; break; case 1: H = SampRate_U_H; VV = SampRate_U_V; pMCUBuffer = MCUBuffer + Y_in_MCU * 64; pQtZzMCUBuffer = QtZzMCUBuffer + Y_in_MCU * 64; break; case 2: H = SampRate_V_H; VV = SampRate_V_V; pMCUBuffer = MCUBuffer + (Y_in_MCU + U_in_MCU) * 64; pQtZzMCUBuffer = QtZzMCUBuffer + (Y_in_MCU + U_in_MCU) * 64; break; } for (i = 0; i<VV; i++) for (j = 0; j<H; j++) IQtIZzBlock(pMCUBuffer + (i*H + j) * 64, pQtZzMCUBuffer + (i*H + j) * 64, flag); } ////////////////////////////////////////////////////////////////////////////////////////// void IQtIZzBlock(short *s, int * d, short flag) { short i, j; short tag; short *pQt; int buffer2[8][8]; int *buffer1; short offset; pQt = YQtTable; switch (flag){ case 0: pQt = YQtTable; offset = 128; break; case 1: pQt = UQtTable; offset = 0; break; case 2: pQt = VQtTable; offset = 0; break; } for (i = 0; i<8; i++) for (j = 0; j<8; j++){ tag = Zig_Zag[i][j]; buffer2[i][j] = (int)s[tag] * (int)pQt[tag]; } buffer1 = (int *)buffer2; Fast_IDCT(buffer1); for (i = 0; i<8; i++) for (j = 0; j<8; j++) d[i * 8 + j] = buffer2[i][j] + offset; } /////////////////////////////////////////////////////////////////////////////// void Fast_IDCT(int * block) { short i; for (i = 0; i<8; i++) idctrow(block + 8 * i); for (i = 0; i<8; i++) idctcol(block + i); } /////////////////////////////////////////////////////////////////////////////// BYTE ReadByte() { BYTE i; i = *(lp++); if (i == 0xff) lp++; BitPos = 8; CurByte = i; return i; } /////////////////////////////////////////////////////////////////////// void Initialize_Fast_IDCT() { short i; iclp = iclip + 512; for (i = -512; i<512; i++) iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i); } //////////////////////////////////////////////////////////////////////// void idctrow(int * blk) { int x0, x1, x2, x3, x4, x5, x6, x7, x8; //intcut if (!((x1 = blk[4] << 11) | (x2 = blk[6]) | (x3 = blk[2]) | (x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3]))) { blk[0] = blk[1] = blk[2] = blk[3] = blk[4] = blk[5] = blk[6] = blk[7] = 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 -= x1; x1 = W6*(x3 + x2); x2 = x1 - (W2 + W6)*x2; x3 = x1 + (W2 - W6)*x3; x1 = x4 + x6; x4 -= x6; x6 = x5 + x7; x5 -= x7; //third stage x7 = x8 + x3; x8 -= x3; x3 = x0 + x2; 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; //intcut if (!((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]))) { blk[8 * 0] = blk[8 * 1] = blk[8 * 2] = blk[8 * 3] = blk[8 * 4] = blk[8 * 5] = blk[8 * 6] = blk[8 * 7] = iclp[(blk[8 * 0] + 32) >> 6]; 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 -= x1; x1 = W6*(x3 + x2) + 4; x2 = (x1 - (W2 + W6)*x2) >> 3; x3 = (x1 + (W2 - W6)*x3) >> 3; x1 = x4 + x6; x4 -= x6; x6 = x5 + x7; x5 -= x7; //third stage x7 = x8 + x3; x8 -= x3; x3 = x0 + x2; x0 -= x2; x2 = (181 * (x4 + x5) + 128) >> 8; x4 = (181 * (x4 - x5) + 128) >> 8; //fourth stage blk[8 * 0] = iclp[(x7 + x1) >> 14]; blk[8 * 1] = iclp[(x3 + x2) >> 14]; blk[8 * 2] = iclp[(x0 + x4) >> 14]; blk[8 * 3] = iclp[(x8 + x6) >> 14]; blk[8 * 4] = iclp[(x8 - x6) >> 14]; blk[8 * 5] = iclp[(x0 - x4) >> 14]; blk[8 * 6] = iclp[(x3 - x2) >> 14]; blk[8 * 7] = iclp[(x7 - x1) >> 14]; } int main() { long time = clock(); LoadJpegFile("0.jpg"); printf("%d\n", clock() - time); return 0; }