www.pudn.com > dip_1_1_bmp2jpeg.rar > Jpeg.cpp
// Jpeg.cpp: implementation of the CJpeg class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Jpeg.h" #include#ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CJpeg::CJpeg() { int i; m_pData = NULL; for(i=0; i<20; i++) TbH[i].Flag = FALSE; } CJpeg::~CJpeg() { int i; if(m_pData != NULL) delete [] m_pData; for(i=0; i<20; i++) if(TbH[i].Flag) { delete [] TbH[i].HUFFCODE; delete [] TbH[i].HUFFSIZE; delete [] TbH[i].HUFFVAL; } } void CJpeg::LoadJPG(LPSTR FileName) { // File Open & Load Entire Contents // HFILE hFile = _lopen(FileName, OF_READWRITE); int FileSize = GetFileSize((HANDLE)hFile, NULL); m_pBuf = new BYTE[FileSize]; _lread(hFile, m_pBuf, FileSize); _lclose(hFile); m_Index = 0; int Count=0; FindSOI(); pByte = &m_pBuf[m_Index]; while(TRUE) { FindETC(); // DRI(Define Restart Interval) FindDHT(); // Huffman Table Loading FindDQT(); // Quantization Table Loading FindSOF(); // Frame Header Loading FindSOS(); // Scan Header Loading & Decoding if( (*pByte == 0xff) && (*(pByte+1) == 0xd9) ) break; Count++; if(Count > 50) // Loop break; } delete [] m_pBuf; } void CJpeg::FindSOI() { while(!((m_pBuf[m_Index] == 0xff)&&(m_pBuf[m_Index+1] == 0xd8))) m_Index++; m_Index = m_Index + 2; } void CJpeg::FindDHT() { if( (m_pBuf[m_Index] == 0xff) && (m_pBuf[m_Index+1] == 0xc4) ) { WORD SegSize = m_pBuf[m_Index+2]*256 + m_pBuf[m_Index+3]; BYTE *p = &m_pBuf[m_Index+4]; do { int i, j, k, LASTK; int Num = 0; BYTE BITS[17]; BYTE Th = *p; // Table Number memcpy(BITS, p, 17); p = p + 17; for(i=1; i<17; i++) Num = Num + BITS[i]; TbH[Th].Flag = TRUE; TbH[Th].HUFFCODE = new WORD[Num+1]; TbH[Th].HUFFSIZE = new BYTE[Num+1]; TbH[Th].HUFFVAL = new BYTE[Num+1]; //Huffman Value memcpy(TbH[Th].HUFFVAL, p, Num); //p p = p + Num; // Generation of table of Huffman code sizes // i=1; j=1; k=0; while(i<=16) { while(j<=BITS[i]) { TbH[Th].HUFFSIZE[k] = (BYTE)i; k++; j++; } i++; j=1; } TbH[Th].HUFFSIZE[k] = 0; LASTK = k; // Generation of table of Huffman codes k=0; WORD CODE = 0; BYTE SI = TbH[Th].HUFFSIZE[0]; while(TRUE) { do { TbH[Th].HUFFCODE[k] = CODE; CODE++; k++; }while(TbH[Th].HUFFSIZE[k] == SI); if(TbH[Th].HUFFSIZE[k] == 0) break; do { CODE = CODE << 1; SI++; }while(TbH[Th].HUFFSIZE[k] != SI); } // Decoder table generation // i=0; j=0; while(TRUE) { do { i++; if(i>16) break; if(BITS[i] == 0) TbH[Th].MAXCODE[i] = -1; }while(BITS[i] == 0); if(i>16) break; TbH[Th].VALPTR[i] = j; TbH[Th].MINCODE[i] = TbH[Th].HUFFCODE[j]; j = j + BITS[i] - 1; TbH[Th].MAXCODE[i] = TbH[Th].HUFFCODE[j]; j++; } TbH[Th].Num = Num; }while(*p != 0xff); m_Index = m_Index + SegSize + 2; } } void CJpeg::FindDQT() { if( (m_pBuf[m_Index] == 0xff) && (m_pBuf[m_Index+1] == 0xdb) ) { WORD SegSize = m_pBuf[m_Index+2]*256 + m_pBuf[m_Index+3]; BYTE *p = &m_pBuf[m_Index+4]; do { BYTE Tq = *(p++) & 0x0f; // Table Number memcpy(TbQ[Tq].Q, &m_pBuf[m_Index+5], 64); p = p + 64; }while(*p != 0xff); m_Index = m_Index + SegSize + 2; } } void CJpeg::FindSOF() { if((m_pBuf[m_Index] == 0xff)&&(m_pBuf[m_Index + 1] == 0xc0)) { int i; WORD SegSize = m_pBuf[m_Index + 2] * 256 + m_pBuf[m_Index + 3]; FrameHeader.Y = m_pBuf[m_Index + 5] * 256 + m_pBuf[m_Index + 6]; FrameHeader.X = m_pBuf[m_Index + 7] * 256 + m_pBuf[m_Index + 8]; FrameHeader.Nf = m_pBuf[m_Index + 9]; for(i=0; i > 4; FrameHeader.V[i] = m_pBuf[m_Index + 11 + 3*i] & 0x0f; FrameHeader.Tq[i] = m_pBuf[m_Index + 12 + 3*i]; } m_Index = m_Index + SegSize + 2; } } void CJpeg::FindETC() { if((m_pBuf[m_Index] == 0xff)&& (( (m_pBuf[m_Index + 1] & 0xf0) == 0xe0) || (m_pBuf[m_Index + 1] & 0xf0) == 0xf0)) { WORD SegSize = m_pBuf[m_Index + 2] * 256 + m_pBuf[m_Index + 3]; m_Index = m_Index + SegSize + 2; } // DRI(Define Restart Interval // if((m_pBuf[m_Index] == 0xff) && (m_pBuf[m_Index+1] == 0xdd)) { WORD Lr = m_pBuf[m_Index+2]*256+m_pBuf[m_Index+3]; Ri = m_pBuf[m_Index+4]*256+m_pBuf[m_Index+5]; m_Index = m_Index + 6; } } void CJpeg::FindSOS() { if((m_pBuf[m_Index] == 0xff)&&(m_pBuf[m_Index + 1] == 0xda)) { int i; WORD SegSize = m_pBuf[m_Index + 2] * 256 + m_pBuf[m_Index + 3]; ScanHeader.Ns = m_pBuf[m_Index + 4]; for(i=0; i > 4; ScanHeader.Ta[i] = m_pBuf[m_Index + 6 + i*2] & 0x0f; } ScanHeader.Ss = m_pBuf[m_Index + 5 + 2 * ScanHeader.Ns]; ScanHeader.Se = m_pBuf[m_Index + 6 + 2 * ScanHeader.Ns]; ScanHeader.Ah = m_pBuf[m_Index + 7 + 2 * ScanHeader.Ns] >> 4; ScanHeader.Al = m_pBuf[m_Index + 7 + 2 * ScanHeader.Ns] & 0x0f; m_Index = m_Index + SegSize + 2; // Sampling Factor // Hmax = Vmax = 0; for(i=0; i Hmax) Hmax = FrameHeader.H[i]; if(FrameHeader.V[i] > Vmax) Vmax = FrameHeader.V[i]; } // // m_rWidth = FrameHeader.X; m_rHeight = FrameHeader.Y; // // if(FrameHeader.X % (8 * Hmax) != 0) FrameHeader.X = (FrameHeader.X / (8*Hmax) + 1)*(8*Hmax); if(FrameHeader.Y % (8 * Vmax) != 0) FrameHeader.Y = (FrameHeader.Y / (8*Vmax) + 1)*(8*Vmax); Decode(); } } WORD CJpeg::NextBit() { WORD Bit; BYTE B2; static BYTE B; while(cnt == 0) { B = NextByte(); cnt = 8; if(B == 0xff) { B2 = NextByte(); } } Bit = B >> 7; cnt--; B = B << 1; return Bit; } BYTE CJpeg::NextByte() { return *(pByte++); } BYTE CJpeg::hDecode(int Th) { int i = 1, j; WORD CODE = NextBit(); BYTE Value; while((CODE > TbH[Th].MAXCODE[i])||(TbH[Th].MAXCODE[i] == 65535)) { i++; CODE = (CODE << 1) + NextBit(); } j = TbH[Th].VALPTR[i]; j = j + CODE - TbH[Th].MINCODE[i]; Value = TbH[Th].HUFFVAL[j]; return Value; } WORD CJpeg::Receive(BYTE SSSS) { BYTE i=0; WORD V = 0; while(i != SSSS) { i++; V = (V << 1) + NextBit(); } return V; } short CJpeg::Extend(WORD V, BYTE T) { WORD Vt = 1 << (T-1); if( V < Vt ) { Vt = (-1 << T) + 1; V = V + Vt; } return (short)V; } void CJpeg::DecodeDC(int Th) { BYTE T = hDecode(Th); ZZ[0] = Extend(Receive(T), T); } void CJpeg::DecodeAC(int Th) { int k = 1; memset((LPSTR)&ZZ[1], 0, 63 * sizeof(short)); BYTE RS, SSSS, RRRR, R; // RRRR : // SSSS : (category) while(TRUE) { RS = hDecode(Th); SSSS = RS % 16; RRRR = RS >> 4; R = RRRR; if(SSSS == 0) { if(R == 15) k = k + 16; else break; } else { k = k + R; ZZ[k] = Extend(Receive(SSSS), SSSS); if(k == 63) break; else k++; } } } void CJpeg::DecodeDU(int N) // N = Component ID 0/1/2 { int i; short *pos; DecodeDC(ScanHeader.Td[N]); DecodeAC(ScanHeader.Ta[N] + 16); // Differential DC Restoration// ZZ[0] = ZZ[0] + PrevDC[N]; PrevDC[N] = ZZ[0]; // Dequantization // pos = ZZ; for(i=0; i<64; i++) { *pos = *pos * TbQ[FrameHeader.Tq[N]].Q[i]; pos++; } // Undo Zigzag Order // Zigzag(); // Inverce Discrete Cosine Transform // IDCT(); // Level Shifting & Correct Error // pos = ZZ; for(i=0; i<64; i++) { *pos = *pos + 128; if(*pos < 0) *pos = 0; else if(*pos > 255) *pos = 255; pos++; } } void CJpeg::Zigzag() { int Index[64] = {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}; short Temp[64]; memcpy(Temp, ZZ, 64 * sizeof(short)); int i, j, idx; for(i=0; i<8; i++) for(j=0; j<8; j++) { idx = (i<<3)+j; ZZ[idx] = Temp[Index[idx]]; } } void CJpeg::IDCT() { int x, y, index, coeff, idx; float tmp1[8][8]; float tmp2[8][8]; float dct_coeff[8][8] = { +0.7071f, +0.7071f, +0.7071f, +0.7071f, +0.7071f, +0.7071f, +0.7071f, +0.7071f, +0.9808f, +0.8315f, +0.5556f, +0.1951f, -0.1951f, -0.5556f, -0.8315f, -0.9808f, +0.9239f, +0.3827f, -0.3827f, -0.9239f, -0.9239f, -0.3827f, +0.3827f, +0.9239f, +0.8315f, -0.1951f, -0.9808f, -0.5556f, +0.5556f, +0.9808f, +0.1951f, -0.8315f, +0.7071f, -0.7071f, -0.7071f, +0.7071f, +0.7071f, -0.7071f, -0.7071f, +0.7071f, +0.5556f, -0.9808f, +0.1951f, +0.8315f, -0.8315f, -0.1951f, +0.9808f, -0.5556f, +0.3827f, -0.9239f, +0.9239f, -0.3827f, -0.3827f, +0.9239f, -0.9239f, +0.3827f, +0.1951f, -0.5556f, +0.8315f, -0.9808f, +0.9808f, -0.8315f, +0.5556f, -0.1951f }; for(y=0; y<8; y++) { for(x=0; x<8; x++) { tmp2[y][x] = (float)ZZ[(y<<3)+x]; } } for(x=0; x<8; x++) // 1-D column IDCT { for(coeff=0; coeff<8; coeff++) { tmp1[coeff][x] = 0.; for(index=0; index<8; index++) { tmp1[coeff][x] += tmp2[index][x] * dct_coeff[index][coeff]; } } } for(y=0; y<8; y++) // 1-D row IDCT { for(coeff=0; coeff<8; coeff++) { tmp2[y][coeff] = 0.; for(index=0; index<8; index++) { tmp2[y][coeff] += tmp1[y][index] * dct_coeff[index][coeff]; } idx = (y<<3)+coeff; ZZ[idx] = (short)(tmp2[y][coeff]/4.); } } } void CJpeg::DecodeMCU(int mx, int my) { int i, j, k, l, m, n, o; int Ns = ScanHeader.Ns; int H, V, Rh, Rv; int mWidth = Hmax * 8, mHeight = Vmax * 8; int bWidth = FrameHeader.X * Ns, bHeight = FrameHeader.Y; int idx1, idx2, idx3; for(k=0; k 255) R = 255; if(R<0) R = 0; if(G>255) G = 255; if(G<0) G = 0; if(B>255) B = 255; if(B<0) B = 0; *pTemp = (BYTE)B;pTemp++; *pTemp = (BYTE)G;pTemp++; *pTemp = (BYTE)R;pTemp++; } else if(ScanHeader.Ns == 1) { *pTemp = (BYTE)Y;pTemp++; *pTemp = (BYTE)Y;pTemp++; *pTemp = (BYTE)Y;pTemp++; } } delete [] pBuf; // Clipping Useless Region // int RealBMPWidth = (m_rWidth * 3 + 3)/4 * 4; if((Width != m_rWidth)||(Height != m_rHeight)) { BYTE *pBuf2 = new BYTE [RealBMPWidth * m_rHeight]; for(i=0; i >8; cb = (B - y) + 128; cr = (R - y) + 128;*/ if(y>255.) y = 255.; if(y<0.) y = 0.; if(cb>255.) cb = 255.; if(cb<0.) cb = 0.; if(cr>255.) cr = 255.; if(cr<0.) cr = 0.; *(pos) = (BYTE)y; *(pos+1) = (BYTE)cb; *(pos+2) = (BYTE)cr; pos = pos + 3; } } // Y, Cb, Cr Plane Buffer // Y = new short[bWidth * bHeight]; memset(Y, 0, sizeof(short) * bWidth * bHeight); Cb = new short[bWidth * bHeight]; memset(Cb, 0, sizeof(short) * bWidth * bHeight); Cr = new short[bWidth * bHeight]; memset(Cr, 0, sizeof(short) * bWidth * bHeight); int idx1, idx2; // Level Shifting -128 // for(i=0; i 0; i--) { DC1[i] = DC1[i] - DC1[i-1]; DC2[i] = DC2[i] - DC2[i-1]; DC3[i] = DC3[i] - DC3[i-1]; } idx = 0; for(i=0; i 0; i--) for(j=bWidth; j>0; j--) { idx1 = (bHeight-i)*bWidth*3 + (bWidth-j)*3; m_pData[idx1] = (BYTE)Y[i*bWidth+j]; m_pData[idx1+1] = (BYTE)Cb[i*bWidth+j]; m_pData[idx1+2] = (BYTE)Cr[i*bWidth+j]; } */ delete [] Y; delete [] Cb; delete [] Cr; _lclose(hFile); } void CJpeg::PutSOI(HFILE hFile) { // SOI // WORD Marker = (0xd8 << 8) | 0xff; _lwrite(hFile, (LPSTR)&Marker, 2); } void CJpeg::PutSOF(HFILE hFile, int Width, int Height) { WORD Marker, SegSize, w; BYTE c; int i; Marker = (0xc0 << 8) | 0xff; _lwrite(hFile, (LPSTR)&Marker, 2); SegSize = 17; SegSize = (SegSize << 8) | (SegSize >> 8); _lwrite(hFile, (LPSTR)&SegSize, 2); // Segment Size c = 8; _lwrite(hFile, (LPSTR)&c, 1); // P = 8 w = (WORD)Height; w = (w << 8) | (w >> 8); _lwrite(hFile, (LPSTR)&w, 2); // Number of Y Line w = (WORD)Width; w = (w << 8) | (w >> 8); _lwrite(hFile, (LPSTR)&w, 2); // Number of Y Line c = 3; _lwrite(hFile, (LPSTR)&c, 1); // Nf = 3 for(i=1; i<=3; i++) { c = (BYTE)i; _lwrite(hFile, (LPSTR)&c, 1); // Component Identifier c = 17; _lwrite(hFile, (LPSTR)&c, 1); // HiVi if(i==1) c=0; else c=1; _lwrite(hFile, (LPSTR)&c, 1); // Tqi } } void CJpeg::PutSOS(HFILE hFile) { WORD Marker, SegSize; BYTE c; int i; Marker = (0xda << 8) | 0xff; _lwrite(hFile, (LPSTR)&Marker, 2); SegSize = 12; SegSize = (SegSize << 8) | (SegSize >> 8); _lwrite(hFile, (LPSTR)&SegSize, 2); // Segment Size c = 3; _lwrite(hFile, (LPSTR)&c, 1); // Ns = 3 for(i=1; i<=3; i++) { c = (BYTE)i; _lwrite(hFile, (LPSTR)&c, 1); // Scan Component Selector if(i==1) c=0; else c=0x11; _lwrite(hFile, (LPSTR)&c, 1); // TdTa } c = 0; _lwrite(hFile, (LPSTR)&c, 1); // Ss c = 0x3f; _lwrite(hFile, (LPSTR)&c, 1); // Se c = 0; _lwrite(hFile, (LPSTR)&c, 1); // AhAl } void CJpeg::PutDQT(HFILE hFile) { WORD Marker, SegSize; BYTE c; // Luminance Quantization Table // BYTE Qtb0[64] = {16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40, 26, 24, 22, 22, 24, 49, 36, 37, 29, 40, 58, 51, 61, 60, 57, 51, 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 66, 57, 80, 109, 81, 87, 95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100, 120, 92, 101, 103, 99}; // Chrominance Quantization Table // BYTE Qtb1[64] = {17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99, 99 ,99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }; Marker = (0xdb << 8) | 0xff; _lwrite(hFile, (LPSTR)&Marker, 2); // Marker SegSize = 67; SegSize = (SegSize << 8) | (SegSize >> 8); _lwrite(hFile, (LPSTR)&SegSize, 2); // Segment Size c = 0; _lwrite(hFile, (LPSTR)&c, 1); // PqTq = 0 _lwrite(hFile, (LPSTR)Qtb0, 64); // Q0 ~ Q63 Marker = (0xdb << 8) | 0xff; _lwrite(hFile, (LPSTR)&Marker, 2); // Marker SegSize = 67; SegSize = (SegSize << 8) | (SegSize >> 8); _lwrite(hFile, (LPSTR)&SegSize, 2); // Segment Size c = 1; _lwrite(hFile, (LPSTR)&c, 1); // PqTq = 1 _lwrite(hFile, (LPSTR)Qtb1, 64); // Q0 ~ Q63 } void CJpeg::DCT(short * pos, int bWidth, BOOL Flag, int qp) { // DCT , DCT Zigzag Quantization // BYTE Qtb0[64] ={16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40, 26, 24, 22, 22, 24, 49, 36, 37, 29, 40, 58, 51, 61, 60, 57, 51, 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 66, 57, 80, 109, 81, 87, 95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100, 120, 92, 101, 103, 99}; BYTE Qtb1[64] ={17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99, 99 ,99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }; int i, j; int x, y, u, v; float Cu, Cv; float Sum; float dct_coeff[8][8] = { +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +0.9808f, +0.8315f, +0.5556f, +0.1951f, -0.1951f, -0.5556f, -0.8315f, -0.9808f, +0.9239f, +0.3827f, -0.3827f, -0.9239f, -0.9239f, -0.3827f, +0.3827f, +0.9239f, +0.8315f, -0.1951f, -0.9808f, -0.5556f, +0.5556f, +0.9808f, +0.1951f, -0.8315f, +0.7071f, -0.7071f, -0.7071f, +0.7071f, +0.7071f, -0.7071f, -0.7071f, +0.7071f, +0.5556f, -0.9808f, +0.1951f, +0.8315f, -0.8315f, -0.1951f, +0.9808f, -0.5556f, +0.3827f, -0.9239f, +0.9239f, -0.3827f, -0.3827f, +0.9239f, -0.9239f, +0.3827f, +0.1951f, -0.5556f, +0.8315f, -0.9808f, +0.9808f, -0.8315f, +0.5556f, -0.1951f }; for(int kk=0;kk<64;kk++){ if(Qtb0[kk]%2==0) Qtb0[kk]=Qtb0[kk]+qp; if(Qtb1[kk]%2==0) Qtb1[kk]=Qtb1[kk]+qp; else{ Qtb0[kk]=Qtb0[kk]-qp; Qtb1[kk]=Qtb1[kk]-qp; } } for(v=0; v<8; v++) { for(u=0; u<8; u++) { Sum = 0; for(y=0; y<8; y++) for(x=0; x<8; x++) Sum = Sum + pos[(int)(y*bWidth+x)] * dct_coeff[u][x] * dct_coeff[v][y]; Cu = 1.; if(u == 0) Cu = 0.7071f; Cv = 1.; if(v == 0) Cv = 0.7071f; ZZ[(int)(v*8+u)] = (short)(Cu * Cv * Sum / 4.); } } Zigzag2(); if(Flag) // TRUE : Chrominance, FALSE : Luminance for(i=0; i<64; i++) ZZ[i] = ZZ[i] / Qtb1[i]; else for(i=0; i<64; i++) ZZ[i] = ZZ[i] / Qtb0[i]; for(i=0; i<8; i++) for(j=0; j<8; j++) pos[i*bWidth+j] = ZZ[i*8+j]; } void CJpeg::Zigzag2() { int Index[64] = {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}; short Temp[64]; memcpy(Temp, ZZ, 64 * sizeof(short)); int i, j, idx; for(i=0; i<8; i++) for(j=0; j<8; j++) { idx = (i<<3)+j; ZZ[Index[idx]] = Temp[idx]; } } void CJpeg::PutDHT(HFILE hFile) { /* standard */ // m_pBuf = new BYTE[413]; m_pBuf = new BYTE[421]; /* BYTE HuffTb[421] = {255, 196, 1, 162, 0, 0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0, 2,3,3,3,3,3,4,5,6,7,8,9, 10, 0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,125, 2,2,3,4,4,4,5,5,5,6,6,7,7,7,7,8,8,8, 9,9,9,9,9,10,10,10,10,10,11,11,11,11,12,12,12,12, 15,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16, 1, 0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0, 2,2,2,3,4,5,6,7,8,9,10,11, 12, 0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,119, 2,2,3,4,4,5,5,5,5,6,6,6, 6,7,7,7,8,8,8,8,9,9,9,9, 9,9,9,10,10,10,10,10,11,11,11,11, 12,12,12,12,14,15,15,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16, 16}; */ /* //255, 196, 1, 162, 0, BYTE HuffTb[413] = { 0,1,5,1,1,1,1 ,1,1,0,0,0,0 ,0,0,0, 0,2,3,4,5,6 ,14,30,62,126,254,510 ,0,2,1,3,3,2 ,4,3,5,5,4,4 ,0,0,1,0X7D ,0,1,4,10,11,12 ,26,27,28,58,59,120 ,121,122,123,248,249,250 ,502,503,504,505,506,1014 ,1015,1016,1017,1018,2038,2039 ,2040,2041,4084,4085,4086,4087 ,32704,65410,65411,65412,65413,65414 ,65415,65416,65417,65418,65419,65420 ,65421,65422,65423,65424,65425,65426 ,65427,65428,65429,65430,65431,65432 ,65433,65434,65435,65436,65437,65438 ,65439,65440,65441,65442,65443,65444 ,65445,65446,65447,65448,65449,65450 ,65451,65452,65453,65454,65455,65456 ,65457,65458,65459,65460,65461,65462 ,65463,65464,65465,65466,65467,65468 ,65469,65470,65471,65472,65473,65474 ,65475,65476,65477,65478,65479,65480 ,65481,65482,65483,65484,65485,65486 ,65487,65488,65489,65490,65491,65492 ,65493,65494,65495,65496,65497,65498 ,65499,65500,65501,65502,65503,65504 ,65505,65506,65507,65508,65509,65510 ,65511,65512,65513,65514,65515,65516 ,65517,65518,65519,65520,65521,65522 ,65523,65524,65525,65526,65527,65528 ,65529,65530,65531,65532,65533,65534 ,0,3,1,1,1,1 ,1,1,1,1,1,0 ,0,0,0,0 ,0,1,2,6,14,30 ,62,126,254,510,1022,2046 ,0,2,1,2,4,4 ,3,4,7,5,4,4 ,0,1,2,0X77 ,0,1,4,10,11,24 ,25,26,27,56,57,58 ,59,120,121,122,246,247 ,248,249,500,501,502,503 ,504,505,506,1014,1015,1016 ,1017,1018,2038,2039,2040,2041 ,4084,4085,4086,4087,16352,32706 ,32707,65416,65417,65418,65419,65420 ,65421,65422,65423,65424,65425,65426 ,65427,65428,65429,65430,65431,65432 ,65433,65434,65435,65436,65437,65438 ,65439,65440,65441,65442,65443,65444 ,65445,65446,65447,65448,65449,65450 ,65451,65452,65453,65454,65455,65456 ,65457,65458,65459,65460,65461,65462 ,65463,65464,65465,65466,65467,65468 ,65469,65470,65471,65472,65473,65474 ,65475,65476,65477,65478,65479,65480 ,65481,65482,65483,65484,65485,65486 ,65487,65488,65489,65490,65491,65492 ,65493,65494,65495,65496,65497,65498 ,65499,65500,65501,65502,65503,65504 ,65505,65506,65507,65508,65509,65510 ,65511,65512,65513,65514,65515,65516 ,65517,65518,65519,65520,65521,65522 ,65523,65524,65525,65526,65527,65528 ,65529,65530,65531,65532,65533,65534}; */ ///standard huffman code BYTE HuffTb[421] = {255, 196, 1, 162, 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 16, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125, 1, 2, 3, 0, 4, 17, 5, 18, 33, 49, 65, 6, 19, 81, 97, 7, 34, 113, 20, 50, 129, 145, 161, 8, 35, 66, 177, 193, 21, 82, 209, 240, 36, 51, 98, 114, 130, 9, 10, 22, 23, 24, 25, 26, 37, 38, 39, 40, 41, 42, 52, 53, 54, 55, 56, 57, 58, 67, 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87, 88, 89, 90, 99, 100, 101, 102, 103, 104, 105, 106, 115, 116, 117, 118, 119, 120, 121, 122, 131, 132, 133, 134, 135, 136, 137, 138, 146, 147, 148, 149, 150, 151, 152, 153, 154, 162, 163, 164, 165, 166, 167, 168, 169, 170, 178, 179, 180, 181, 182, 183, 184, 185, 186, 194, 195, 196, 197, 198, 199, 200, 201, 202, 210, 211, 212, 213, 214, 215, 216, 217, 218, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 1, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 17, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119, 0, 1, 2, 3, 17, 4, 5, 33, 49, 6, 18, 65, 81, 7, 97, 113, 19, 34, 50, 129, 8, 20, 66, 145, 161, 177, 193, 9, 35, 51, 82, 240, 21, 98, 114, 209, 10, 22, 36, 52, 225, 37, 241, 23, 24, 25, 26, 38, 39, 40, 41, 42, 53, 54, 55, 56, 57, 58, 67, 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87, 88, 89, 90, 99, 100, 101, 102, 103, 104, 105, 106, 115, 116, 117, 118, 119, 120, 121, 122, 130, 131, 132, 133, 134, 135, 136, 137, 138, 146, 147, 148, 149, 150, 151, 152, 153, 154, 162, 163, 164, 165, 166, 167, 168, 169, 170, 178, 179, 180, 181, 182, 183, 184, 185, 186, 194, 195, 196, 197, 198, 199, 200, 201, 202, 210, 211, 212, 213, 214, 215, 216, 217, 218, 226, 227, 228, 229, 230, 231, 232, 233, 234, 242, 243, 244, 245, 246, 247, 248, 249, 250, 255}; /* int i1,i2,i3,i4,i5,i6,i7,i8; //Y for (i1=0;i1<16;i1++) *(m_pBuf+i1) = STD_Y_DC_NR[i1]; for (i2=0;i2<12;i2++) *(m_pBuf+i1+i2) = VLCTAB_DC_Y[i2]; for (i3=0;i3<16;i3++) *(m_pBuf+i1+i2+i3) = STD_Y_AC_NR[i3]; for (i4=0;i4<162;i4++) *(m_pBuf+i1+i2+i3+i4) = VLCTAB_AC_Y[i4]; //UV for (i5=0;i5<16;i5++) *(m_pBuf+i1+i2+i3+i4+i5) = STD_UV_DC_NR[i5]; for (i6=0;i6<12;i6++) *(m_pBuf+i1+i2+i3+i4+i5+i6) = VLCTAB_DC_UV[i6]; for (i7=0;i7<16;i7++) *(m_pBuf+i1+i2+i3+i4+i5+i6+i7) = STD_UV_AC_NR[i7]; for (i8=0;i8<162;i8++) *(m_pBuf+i1+i2+i3+i4+i5+i6+i7+i8) = VLCTAB_AC_UV[i8]; */ //int i1,i2,i3,i4,i5,i6,i7,i8,k; /* //Y for (i1=0;i1<16;i1++) *(m_pBuf+i1) = STD_Y_DC_NR[i1]; for (i2=0;i2<12;i2++) for(k=0;k<3;k++) *(m_pBuf+i1+i2+k) = VLCTAB_DC_Y[i2][k]; for (i3=0;i3<16;i3++) *(m_pBuf+i1+i2*3+i3) = STD_Y_AC_NR[i3]; for (i4=0;i4<162;i4++) for(k=0;k<3;k++) *(m_pBuf+i1+i2*3+i3+i4+k) = VLCTAB_AC_Y[i4][k]; //UV for (i5=0;i5<16;i5++) *(m_pBuf+i1+i2*3+i3+i4*3+i5) = STD_UV_DC_NR[i5]; for (i6=0;i6<12;i6++) for(k=0;k<3;k++) *(m_pBuf+i1+i2*3+i3+i4*3+i5+i6+k) = VLCTAB_DC_UV[i6][k]; for (i7=0;i7<16;i7++) *(m_pBuf+i1+i2*3+i3+i4*3+i5+i6*3+i7) = STD_UV_AC_NR[i7]; for (i8=0;i8<162;i8++) for(k=0;k<3;k++) *(m_pBuf+i1+i2*3+i3+i4*3+i5+i6*3+i7+i8+k) = VLCTAB_AC_UV[i8]; */ memcpy(m_pBuf, HuffTb, 421); // memcpy(m_pBuf, HuffTb, 413); /* for(i1=0;i1>16;i1++) memcpy(m_pBuf, &STD_Y_DC_NR[i1], 1); for(i1=0;i1>12;i1++) memcpy(m_pBuf, &VLCTAB_DC_Y[i1], 1); for(i1=0;i1>16;i1++) memcpy(m_pBuf, &STD_Y_AC_NR[i1], 1); for(i1=0;i1>162;i1++) memcpy(m_pBuf, &VLCTAB_AC_Y[i1], 1); for(i1=0;i1>16;i1++) memcpy(m_pBuf, &STD_UV_DC_NR[i1], 1); for(i1=0;i1>12;i1++) memcpy(m_pBuf, &VLCTAB_DC_UV[i1], 1); for(i1=0;i1>16;i1++) memcpy(m_pBuf, &STD_UV_AC_NR[i1], 1); for(i1=0;i1>12;i1++) memcpy(m_pBuf, &VLCTAB_AC_UV[i1], 1); */ m_Index = 0; // Huffman Table Index Reset FindDHT(); _lwrite(hFile, (LPSTR)m_pBuf, 420); // _lwrite(hFile, (LPSTR)m_pBuf, 412); delete [] m_pBuf; } BYTE CJpeg::GetCategory(short V) { BYTE Num = 0; if(V < 0) V = -V; while(V != 0) { V = V >> 1; Num++; } return Num; } void CJpeg::hEncode(int bWidth, int bHeight) { int i, j; for(i=0; i 15) { Rs = 0xf0; Code = TbH[ThAC].HUFFCODE[TbH[ThAC].PT[Rs]]; Size = TbH[ThAC].HUFFSIZE[TbH[ThAC].PT[Rs]]; ChargeCode((WORD)Code, Size); R = R - 16; } SSSS = GetCategory(XX[k]); //Rs = (R << 4) | SSSS; Rs = (R * 16) + SSSS; Code = TbH[ThAC].HUFFCODE[TbH[ThAC].PT[Rs]]; Size = TbH[ThAC].HUFFSIZE[TbH[ThAC].PT[Rs]]; ChargeCode((WORD)Code, Size); DIFF = XX[k]; if(DIFF < 0) DIFF = DIFF - 1; ChargeCode((WORD)DIFF, SSSS); R = 0; if(k==63) break; } } } void CJpeg::ChargeCode(WORD Code, int Size) { int i; BYTE Bit; for(i=0; i > (Size - 1 - i)) & 0x01; ShotBit(Bit); } } void CJpeg::ShotBit(BYTE Bit) { static BYTE Bullet = 0; Bit = Bit << (7-cnt); Bullet = Bullet | Bit; cnt++; if(cnt == 8) { cnt = 0; m_pBuf[m_Index] = Bullet; m_Index++; if(Bullet == 0xff) // 0xff 0x00 Byte Stuffing!! { m_pBuf[m_Index] = 0x00; m_Index++; } Bullet = 0; } } void CJpeg::PutEOI(HFILE hFile) { // EOI // WORD Marker = (0xd9 << 8) | 0xff; _lwrite(hFile, (LPSTR)&Marker, 2); }