Simplejpegenc.h
/ * This is a simple JPEG encoding program that supports 1: 1: 1 Sampling Baseline color JPEG, the input can only be 24bit's BMP file code structure only to explain the procedures, do not do special optimization, efficiency general. * /
#ifndef __jenc __ # Define __jenc__
#include
Using namespace std;
Class Jenc {public: // bmfile: Enter file // jpgfile: Output file // q: Q: Quality Void Invoke (String Bmfile, String JPGFILE, long Q) {file * pfile; // Enter file handle
IF ((pfile = fopen (bmfile.c_str (), "RB")) == null) // Opens the file {throw ("Open BMP File Error.");}
/ / Get the BMP data structure required for JPEG encoding, JPEG requires a multiple of the data buffer to 8 or 16 (depending on the sample mode) Bmbufinfo Bmbuffinfo = getBmbuffsize (pfile); imgwidth = bmbuffinfo.imgWidth; // Image width imgHeight = bmBuffInfo.imgHeight; // image of high buffWidth = bmBuffInfo.buffWidth; // buffer buffHeight = bmBuffInfo.buffHeight wide; // buffer high size_t buffSize = buffHeight * buffWidth * 3; // buffer length, because it is 24bits, so * 3 BYTE * BMDATA = New byte [buffsize]; // Apply for memory space getBmdata (Pfile, BMData, Bmbuffinfo); // Get data fclose (pfile); // Close file
/ / ======================================================= // calculate the buffer required by the encoding, RGB signal Do not encode separately, so you need 3 buffers, just 1: 1: 1, it is the same size, size_t yuff, = buffwidth * buffheight; byte * pybuff = new byte [yuvbuffsize]; BYTE * PUBUFF = New Byte [YUVBuffsize] BYTE * pVBuff = new BYTE [yuvBuffSize]; // converts the RGB signals into YUV signals BGR2YUV111 (bmData, pYBuff, pUBuff, pVBuff); // dividing the signal into blocks DivBuff 8x8 (pYBuff, buffWidth, buffHeight, DCTSIZE, DCTSIZE ); DivBuff (pUBuff, buffWidth, buffHeight, DCTSIZE, DCTSIZE); DivBuff (pVBuff, buffWidth, buffHeight, DCTSIZE, DCTSIZE); SetQuantTable (std_Y_QT, YQT, Q); // set the Y quantization table SetQuantTable (std_UV_QT, UVQT, Q ); // Set UV quantization table initQtForaAndct (); // Initialize the quantization table pvlitab = VLI_TAB 2047; // Sets VLI_TAB alias buildvlitable (); // calculate the VLI table
Poutfile = fopen (jpgfile.c_str (), "wb");
// WriteAPP0 (); WriteSOF (); WriteSOS (); WriteSOS ();
// Calculate the Y / UV AC-DC signal components huffman table, standard huffman table used herein, is not calculated, the disadvantage is slightly longer documents, but fast BuildSTDHuffTab (STD_DC_Y_NRCODES, STD_DC_Y_VALUES, STD_DC_Y_HT); BuildSTDHuffTab (STD_AC_Y_NRCODES, STD_AC_Y_VALUES , STD_AC_Y_HT); BuildStdhuffTab (STD_DC_UV_NRCODES, STD_DC_UV_VALUES, STD_DC_UV_HT); BuildStdhuffTab (STD_AV_UV_NRCODES, STD_AC_UV_VALUES, STD_AC_UV_HT);
// Processing unit data ProcessData (Pybuff, Pubuff, PVBUFF); Writeeoi ();
Fclose (poutfile); delete [] bmdata;}
Private:
File * poutfile; int buffwidth; int ingwidth; int image;
// Get BMP file output buffer information BMBUFINFO GetBMBuffSize (FILE * pFile) {BITMAPFILEHEADER bmHead; // file header block BITMAPINFOHEADER bmInfo; // description of the image block BMBUFINFO bmBuffInfo; UINT colSize = 0; UINT rowSize = 0; fseek ( Pfile, 0, seek_set; // points the read-write pointer to the file header Fread (& BMHEAD, SIZEOF (BMHEAD), 1, PFILE); // Read file header information block Fread (& Bminfo, Sizeof (Bminfo), 1, Pfile); // Read bitmap information block
/ / Calculate the number of fills, JPEG encoding requires a multiplication of high and width of 8 or 16 in the buffer (bminfo.biWidth% 8 == 0) {color = bminfo.biwidth;} else {color = bminfo.biwidth 8 - (bminfo.biwidth% 8);
/ / Calculate the number of filling the number IF (bminfo.biheight% 8 == 0) {rowsize = bminfo.biheight;} else {rowsize = bminfo.biheight 8 - (bminfo.biheight% 8);}
bmBuffInfo.BitCount = 24; bmBuffInfo.buffHeight = rowSize; // buffer high bmBuffInfo.buffWidth = colSize; // buffer width bmBuffInfo.imgHeight = bmInfo.biHeight; // image of high bmBuffInfo.imgWidth = bmInfo.biWidth; // Image width
Return Bmbuffinfo;}
// Get image data Void getBmdata (file * pfile, byte * pBuff, bitmapfileHeader bmhead; // file header information block BitmapInfoHeader Bminfo; // Image Description Information Block SIZE_T DATALEN = 0; // File Data Area Length Long AlignBytes = 0; // UINT LINESIZE = 0 for the alignment 4 bytes.
FSeek (Pfile, 0, Seek_set); // directs the read-write pointer to the file header Fread (& BMHEAD, SIZEOF (BMHEAD), 1, PFILE); // Read file header information block Fread (& Bminfo, Sizeof (Bminfo), 1, pfile); // Read bitmap information block
/ / Calculate the number of bytes alignbytes = ((bminfo.biwidth * bminfo.biBitcount) 31) & ~ 31) / 8L - (bminfo.biwidth * bminfo.bibitcount) / 8L; // calculate image file data Segment row speed
/ / Calculate the data buffer length linesize = bminfo.biwidth * 3; // Because BMP file data is inverted, it will read for (int i = bminfo.biheight - 1; I> = 0; --I) {FREAD (& PBuff [Buffinfo.buffWidth * i * 3], Linesize, 1, Pfile; FSeek (Pfile, AlignBytes, Seek_cur); // Skip Align byte}} // Convert Color Space BGR-YUV, 111 Sampling Void bgr2yuv111 (byte * pbuf, byte * pybuff, byte * pubuff, byte * pvbuff) {double tmpy = 0; // temporary variable double tmpu = 0; double tmpv = 0; byte tmpb = 0; byte tmpg = 0; byte TMPR = 0; uint i = 0; size_t elemnum = _msize (pbuf) / 3; // buffer length
For (i = 0; i
// ******************************************************** ******************** // method name: divbuff // last revision date: 2003.5.3 // // Parameter description: // LPBUF: Input buffer, processing The subsequent data is also stored here // width: buffer X direction length // HEIGHT: buffer Y direction length // xlen: x direction cut length // YLEN: Y direction cut length // ********* *********************************************************** ********* VOID DIVBUFF (Byte * Pbuf, Uint Width, Uint Height, uint xlen, uint ylen) {uint xbufs = width / xlen; // x-axis direction cut amount uint YBUFS = Height / Ylen ; // Y-axis direction uint tmpbuflen = Xbufs * xlen * ylen; // calculate temporary buffer length byte * tmpbuf = new byte [TmpBuflen]; // Create a temporary buffer uint i = 0; // Temporary variable uint J = 0; uint k = 0; uint n = 0; uint bufoffset = 0; // cut offset for (i = 0; i // ******************************************************** ******************** / / method name: setQuantTable // // method description: Quantization table // // parameter description according to the required quality setting: // std_qt : Standard quantization table // qt: output quantization table // q: Quality parameters // **************************************** ************************************ / / Depending on the desired quality, quantization table void setQuantTable (Const BYTE * STD_QT, BYTE * QT, INT Q) {INT TMPVAL = 0; // Temporary Variable DWORD I = 0; IF (q <1) q = 1; // Limit Quality Coefficient IF (Q> 100) q = 100 ; // Nonlinear mapping 1-> 5000, 10-> 500, 25-> 200, 50-> 100, 75-> 50, 100-> 0 IF (q <50) {q = 5000 /} else { Q = 200 - q * 2;} For (i = 0; i IF (tmpval <1) // numerical range limit {tmpval = 1L;} if (tmpval> 255) {TMPVAL = 255L;} QT [fzbt [i]] = static_cast / / Initialization Table void initQtForaAndct () {uint i = 0; // temporary variable uint j = 0; UINT K = 0; For (i = 0; i K = 0; for (i = 0; i // Write file start tag Void Writesoi (Void) {FWRITE (& SOITAG, SIZEOF (SITAG), 1, this-> poutfile;} // Write App Rock Void WriteApp0 (Void) {JPEGAPP0 APP0; app0.SEGMENTTAG = 0xE0FF; App0.Length = 0x1000; app0.id [0] = 'J'; app0.id [1] = 'f'; app0.id [2] = 'i'; app0.id [3] = 'f'; APP0.ID [4] = 0; app0.ver = 0x0101; app0.densityUnit = 0x00; app0.DensityX = 0x0100; app0.densityy = 0x0100; app0.thp = 0x00; app0.tvp = 0x00; FWRITE (& app0, sizeof (App0), 1-> poutfile;} // Write DQT segment void writeqt (void) {uint i = 0; jpegdqt_8bits dqt_y; dqt_y.segmentTAG = 0xDBFF; DQT_Y.LENGTH = 0x4300; DQT_Y.TABLEINFO = 0x00 For (i = 0; i DQT_Y.TABLEINFO = 0x01; for (i = 0; i // Write SOF Section Void Writesof (Void) {JPEGSOF0_24BITS SOF; Sof.SegmentTAG = 0xc0ff; Sof.Length = 0x1100; Sof.Precision = 0x08; Sof.Height = Intel2moto (Ushort (this-> imgheight)); SOF. Width = intel2moto; sof.signum = 0x03; sof.iid = 0x01; Sof.Qty = 0x00; SOF.UID = 0x02; Sof.QTU = 0x01; Sof.vid = 0x03; SOF .Qtv = 0x01; SOF.HVU = 0x11; SOF.HVV = 0x11; / * switch (this-> SamplingType) {case 1: sof.hvy = 0x11; Case 2: SOF.HVY = 0x12; Break; Case 3: SOF.HVY = 0x21; Break; Case 4: SOF.HVY = 0x22; Break;} * / Sof.hvy = 0x11; FWRITE (& Sof, sizeof (sof), 1, this-> poutfile);} // Write DHT Segment Void WriteDHT (void) { UINT I = 0; JPEGDHT DHT; DHT.SEGMENTTAG = 0xc4ff; dht.Length = Intel2moto (19 12); dht.tableinfo = 0x00; for (i = 0; i <16; i ) {dht.huffcode [i] = STD_DC_Y_NRCODES [i 1];} FWRITE (& DHT, SIZEOF (DHT), 1, this-> poutfile; for (i = 0; i <= 11; i ) {WritebyTe (std_dc_y_values [i]);} //---- ------------------------------------------ DHT.TABLEINFO = 0x01; For (i = 0; i <16; i ) {dht.huffcode [i] = std_dc_uv_nrcodes [i 1];} fwrite (& DHT, SIZEOF (DHT), 1, THIS-> Poutfile; for (i = 0 ; i <= 11; i ) {WritebyTe (std_dc_uv_values [i]);} // ------------------------------ ---------------------- DHT.LENGTH = Intel2moto (19 162); DHT.TABLEINFO = 0x10; for (i = 0; i <16; i ) {Dht.huffcode [i] = std_ac_y_nrcodes [i 1];} fwrite (& DHT, SIZEOF (DHT), 1, this-> poutfile; for (i = 0; i <= 161; i ) {WritebyTe STD_AC_Y_VALUES [I]);} // --------------------------------------- ------------ DHT.TABLEINFO = 0x11; for (i = 0; i <16; i ) {dht.huffcode [i] = STD_AC_UV_NRCODES [i 1];} FWRITE (& DHT, SIZEOF (DHT), 1, this-> poutfile; for (i = 0; i <= 161; i ) {WritebyTe (std_ac_uv_values [i]);}} // Write SOS section void Writesos (void) {JPEGSOS_24BITS SOS; SOS.SEGMENTTAG = 0xDAFF; sos.length = 0x0c00; sos.signum = 0x03; sos.YID = 0x01; sos.hty = 0x00; sos.uid = 0x02 Sos.htu = 0x11; sos.vid = 0x03; sos.htv = 0x11; sos.SE = 0x3f; sos.ss = 0x00; sos.bf = 0x00; FWRITE (& Sos, Sizeof (SOS), 1, this- > Poutfile;} // Write file end tag VOID WRITEEOI (Void) {FWRITE (& EOITAG, SIITAG), 1, this-> poutfile;} // High 8-bit and low 8-digit exchange USHORT Intel2moto Ushort Val) {byte highbits = byte (VAL / 256); byte lowbits = byte (Val% 256); Return lowbits * 256 highbits; // Write 1 byte to file void writebyte (byte Val) {FWRITE (& Val, SizeOf (Val), 1, this-> poutfile;} // Generate a standard HufFMAN table void buildstdhufftab (byte * nrcodes, byte * stdtab, huffcode * huffcode) {byte i = 0; // Temporary variable Byte j = 0; byte k = 0; ushort code = 0; For (i = 1; i <= 16; i ) {for (j = 1; j <= nrcodes [i]; j ) {huffcode [stdtab [k]]. code = code; huffcode [stdtab [k]] .length = i; k; code;} code * = 2; For (i = 0; i // Process DU (data unit) Void Processdu (Float * LPBUF, FLOAT * QUATITTAB, HuffCode * DchuffTab, HuffCode * Achuff, Short * DC) {byte i = 0; // Temporary Variable Uint J = 0; Short DiffVal = 0 ; // DC difference value BYTE ACLEN = 0; // Entropy encoding the number of AC intermediate symbols short sigbuf [dctblocksize]; // Quantified Signal buffer ACSYM ACSYM [DCTBLOCKSIZE]; // AC intermediate symbol buffer FDCT (LPBUF); // Discrete Cosine Transform For (i = 0; i // ******************************************************** ******************** / / method name: processData // // Method Description: Processing image data fdct-quant-huffman // // parameter description: // LPYBUF: Brightness Y signal input buffer // lpubuf: color difference U signal input buffer // LPVBUF: color difference V signal input buffer // *********************** **************************************************** VOID ProcessData (byte * LPYBUF, BYTE * LPUBUF, BYTE * LPVBUF) {size_t ybuflen = _msize (lpybuf); // Brightness y buffer length size_t ubuflen = _msize (lpubuf); // color difference U buffer length size_t vbufflen = _msize (lpvbuf); // color difference V buffer length float dctybuf [dctblocksize]; // Y signal FDCT encoding temporary buffer float dctubuf [dctblocksize]; // U signal FDCT encoding temporary buffer float dctvbuf [dctblocksize]; // v signal FDCT encoding temporary buffer uint mcunum = 0; / / Store the number of MCUs short YDC = 0; // Y signal's current block of the DC Short UDC = 0; // U signal's current block of the DC Short VDC = 0; // v signal of the current block of the current block of the DC BYTE YCOUNTER = 0; // YUV signals respective write counters Byte ucounter = 0; Byte vCOUNTER = 0; uint i = 0; // Temporary variable uint J = 0; uint k = 0; uint p = 0; uint m = 0; uint n = 0; uint s = 0; mcunum = (this-> buffheight * this-> buffwidth * 3) / (DCTBLOCKSIZE * 3); / / Calculate the number of MCUs For (p = 0; p For (; i / * The first part, calculates * / dataptr = lpbuff; for (CTR = DCTSIZE-1; CTR> = 0; CTR -) {TMP0 = DataPtr [0] DataPtr [7]; TMP7 = DataPtr [0 ] - DataPtr [7]; TMP1 = DataPtr [1] DataPtr [6]; TMP6 = DataPtr [1] - DataPTR [6]; TMP2 = DataPtr [2] DataPtr [5]; tmp5 = dataptr [2] - DataPTR [5]; TMP3 = DataPtr [3] DataPtr [4]; TMP4 = DataPtr [3] - DataPtr [4]; / * Convection of the even item * / TMP10 = TMP0 TMP3; / * Phase 2 * / TMP13 = TMP0 - TMP3; TMP11 = TMP1 TMP2; TMP12 = TMP1 - TMP2; DataPTR [0] = TMP10 TMP11; / * Phase 3 * / DataPtr [4] = TMP10 - TMP11; Z1 = (TMP12 TMP13) * (0.707106781); / * C4 * / dataPTR [2] = TMP13 Z1; / * Phase 5 * / dataptr [6] = TMP13 - Z1; / * Calculate odd item * / TMP10 = TMP4 TMP5; / * PHASE 2 * / TMP11 = TMP5 TMP6; TMP12 = TMP6 TMP7; Z5 = (TMP10 - TMP12) * (0.382683433); / * C6 * / z2 = (0.541196100) * TMP10 Z5; / * C2-C6 * / z4 = (1.306562965) * TMP12 Z5; / * C2 C6 * / Z3 = tmp11 * (0.707106781); / * C4 * / Z11 = TMP7 Z3; / * PHASE 5 * / Z13 = TMP7 - Z3; DataPTR [5] = Z13 Z2; / * Phase 6 * / DataPtr [3] = Z13 - Z2; DataPtr [1] = Z11 Z4; DataPtr [7] = Z11 - Z4; DataPtr = DCTSIZE; / * will point the pointer to the next line * /} / * Part 2, calculate the column * / dataPtr = lpbuff; for (CTR = DCTSIZE-1; CTR> = 0; CTR -) {TMP0 = DataPtr [DCTSIZE * 0] DataPtr [DCTSIZE * 7]; TMP7 = DataPtr [DCTSIZE * 0] - DataPtr [DCTSIZE * 7]; TMP1 = DataPtr [DCTSIZE * 1] DataPtr [DCTSIZE * 6]; TMP6 = DataPtr [DCTSIZE * 1] - DataPtr [DCTSIZE * 6]; TMP2 = DataPtr [DCTSIZE * 2] DataPtr [DCTSIZE * 5]; TMP5 = DataPtr [DCTSIZE * 2] - DataPtr [DCTSIZE * 5]; TMP3 = DataPtr [DCTSIZE * 3] DataPtr [DCTSIZE * 4]; TMP4 = DataPtr [ DCTSIZE * 3] - DATAPTR [DCTSIZE * 4]; / * Convection of the even item * / TMP10 = TMP0 TMP3; / * PHASE 2 * / TMP13 = TMP0 - TMP3; TMP11 = TMP1 TMP2; TMP12 = TMP1 - TMP2 ; DataPTR [DCTSIZE * 0] = TMP10 TMP11; / * Phase 3 * / DataPtr [DCTSIZE * 4] = TMP10 - TMP11; Z1 = (TMP12 TMP13) * (0.707106781); / * c4 * / dataptr [DCTSIZE * 2] = TMP13 Z1; / * PHASE 5 * / DataPtr [DCTSIZE * 6] = TMP13 - Z1; / * Calculate odd item * / TMP10 = TMP4 TMP5; / * PHASE 2 * / TMP11 = TMP5 TMP6; TMP12 = TMP6 TMP7; Z5 = (TMP10 - TMP12) * (0.382683433); / * C6 * / z2 = (0.541196100) * TMP10 Z5; / * C2-C6 * / z4 = (1.306562965) * TMP12 Z5; / * C2 C6 * / Z3 = tmp11 * (0.707106781); / * C4 * / Z11 = TMP7 Z3; / * PHASE 5 * / Z13 = TMP7 - Z3; DataPTR [DCTSIZE * 5] = Z13 Z2; / * Phase 6 * / DataPtr [DCTSIZE * 3] = Z13 - Z2; Dataptr [DCTSIZE * 1] = Z11 Z4; DataPtr [DCTSIZE * 7] = Z11 - Z4; DataPtr; / * Take the pointer down one list * /}} // ******************************************************** ******************* // method name: writebits // // method description: Write binary stream // // Parameter Description: // Value: AC / The amplitude of DC signal /// ***************************************************** ************************ VOID WRITEBITS (HUFFCODE HUFFCODE) {WriteBitsStream (HuffCode.code, HuffCode.Length);} Void WriteBits (SYM2 SYM) { WriteBitsStream (sym.amplitude, sym.codelen;} // **************************************************************************************************************************************************************************************************************************************************************************** **************************************** // method name: WriteBitsStream // // Method Description: Write binary flow / / / / Parameter Description: // Value: Value Need to write // Codelen: binary length // *********************************** ************************************************** VOID WRITEBITSSTREAM (Ushort Value, Byte Codelen) {Char Posval; // Bit Position in The Bitstring We Read, Should Be <= 15 and> = 0 POSVAL = Codelen-1; While (POSVAL> = 0) {if (Value & Mask [POSval]) {bytenew | = Mask [bytepos];} posval -; bytepos - {if (bytenew == 0xFF) {WritebyTe (0xFF); WritebyTe (0);} else {WritebyTe (bytenew);} BY Tepos = 7; Bytenew = 0;}}} // ******************************************************** ******************* / / method name: rlecomp // // Method Description: Use the RLE algorithm to compress the AC, assume the input data 1, 0, 0 3, 0, 5 // Output is (0, 1) (3, 3) (1, 5), the left border indicates the number of right // left bonds in the left border 4BITS, 0 of the number exceeds The scope is indicated to (15, 0) // The remaining 0 data is indicated in the next symbol. // // Parameter Description: // LPBUF: Input buffer, 8x8 transform signal buffer // LPOUF: Output buffer, structure array, Structure information seeing head file // Resultlen: Output buffer length, the number of symbols encoded /// ************************************ ********************************************************* VOID RLECOMP (Short * LPBUF, ACSYM * LPOUTBUF, BYTE & RESUM = 0; // 0 stroke counter uint eobpos = 0; // EOB appearance location const byte maxzerolen = 15; // maximum 0 stroke uint i = 0; // Temporary variable uint j = 0; eobpos = DCTBLOCKSIZE - 1; // Set the start position, starting for for for (i = eobpos; i> 0; i - //) from the last signal {IF (lpbuf [i] == 0) // Determine if the data is 0 {--EOBPOS; // forward one} else // encountered non-0, jump out {Break;}}} For (i = 1; i <= eobpos; i ) // from the second signal, that is, the AC signal starts encoded {IF (LPBUF [I] == 0 && Zeronum // ******************************************************** ******************** / / method name: buildsym2 // // method Description: Encode the amplitude VLI of the signal, return to the encoding length and the signal amplitude of the signal amplitude / /// Parameter Description: // Value: Ampline of AC / DC signal // ****************************************** ********************************************** SYM2 BUILDSYM2 {SYM2 SYMBOL; SYMBOL.CODELEN = Computevli (Value); // Get encoding length symbol.amplitude = 0; if (value> = 0) {symbol.amplitude = value;} else {symbol.amplitude = short (Pow (2, Symbol.codelen) -1) value; / / calculate the reverse code} Return Symbol; // Return the length of the symbol byte computevli (short val) {byte binstrlen = 0; val = ABS (VAL); // Get binary code length IF (VAL == 1) {binstrlen = 1;} else if (Val> = 2 && val <= 3) {binstrlen = 2;} else if (val> = 4 && var <= 7) {binstrlen = 3;} else if (val> = 8 && var <= 15) {binstrlen = 4; } Else if (val> = 16 && val <= 31) {binstrlen = 5;} else if (val> = 32 && val <= 63) {binstrlen = 6;} else if (val> = 64 && val <= 127) {binstrlen = 7;} else if (val> = 128 && val <= 255) {binstrlen = 8;} else if (val> = 256 && val <= 511) {binstrlen = 9;} else if (VAL) > = 512 && val <= 1023) {binstrlen = 10;} else if (val> = 1024 && var <= 2047) {binstrlen = 11; Return binstrlen; // ******************************************************** ******************** // method name: buildvlitable // // method description: Generate VLI table // // Parameter Description: // ***** *********************************************************** ************* VOID BUILDVLITABLE (Void) {INT i = 0; for (i = 0; i For (i = dc_min_quanted; i <0; i) {pvlitab [i] = computevli (i);}}}; #endif // __jenc__ JPEG.H Typedef struct tagbmbufinfo {uint imgwidth; uint imgheight; uint buffwidth; uint buffheight; word bitcount; Byte Padsize;} Bmbufinfo; // DCT conversion size static const byte DCTSIZE = 8; // DCT conversion block length static const byte dctblocksize = 64; // Huffman code structure type {Word code; // huffman code word byte length; // encoding length word val; // codeword correspondence} HuffCode; // AC signal intermediate symbol structure typef struct tagacsym {byte Zerolen ; // 0 stroke Byte Codelen; // amplitude encoding length short amplitude; // amplitude} ACSYM; // DC / AC Intermediate Symbol 2 Description Structure TypeDef Struct Tagsym2 {Short Amplitude; // Amplitude BYTE CODELEN; // Amplitude Length (bits of the amplitude data of binary form)} SYM2; / / Store VLI table byte vli_tab [4096]; byte * pvlitab; // vli_tab alias, make the subscript in -2048-2048 / / 2 quantization table Byte YQT [DCTBLOCKSIZE]; BYTE UVQT [DCTBLOCKSIZE]; // Store 2 FDCT Transform Requirements Format Quantization Table float yqt_dct [DCTBLOCKSIZE]; float uvqt_dct [dctblocksize]; // Store 4 huffman tables HuffCode STD_DC_Y_HT [12]; HuffCode STD_DC_UV_HT [12]; HuffCode STD_AC_Y_HT [256]; HuffCode STD_AV_UV_HT [256]; Static Byte Bytenew = 0; // The byte That Will Be Written in The JPG FileStatic Char Bytepos = 7; // Bit Position In The byte We Write (Bytenew) // Should Be <= 7 and> = 0static Ushort Mask [16 ] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768}; Static Const Double AanscaleFactor [8] = {1.0, 1.387039845, 1.75875602, 1.0, 0.785694958, 0.54119694958, 0.541196100, 0.275899379}; // After quantization, DC range between -2 ^ 11 - 2 ^ 11 - 1, quantified After AC range In -2 ^ 10 - 2 ^ 10 - 1 STATIC const Int ac_max_quanted = 1023; // Quantified AC's maximum static const INT AC_MIN_QUANTED = -1024; // Quantified AC minimum Static const INT DC_MAX_QUANTED = 2047 ; // quantified DC max Static const INT DC_MIN_QUANTED = -2048; / / The minimum value of DC after quantization // Standard brightness signal quantization template const static Byte STD_Y_QT [64] = {16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99}; // Standard color difference signal quantization template const static Byte std_uv_qt [64] = {17, 18, 24, 47, 99, 99, 99, 99, 99, 99, 99, 24, 26, 56, 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}; 正 向 8x8 z transform table const static byte fzbt [64] = {0, 1, 5, 6, 4, 7, 13, 16, 26, 29, 42, 3 , 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 10, 31, 40, 44, 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}; // Color space coefficient constant, in turn, the coefficient of 411, 111, 211 sampling, 2 ways of 211 sampling the same static const float color colorspacecoef [4] [3] = {{1, 0.25, 0.25}, {1, 1, 1} , {1, 0.5, 0.5}, {1, 0.5, 0.5}; // MCU Each model component appears static const byte mcuindex [4] [3] = {4, 1, 1}, {1 , 1, 1}, {2, 1, 1}, {2, 1, 1}}; // Standard Huffman Table (CF. JPEG Standard Section K.3) Static Byte STD_DC_Y_NRCODES [17] = {0,0,1,5, 1, 1, 1, 1, 1, 1, 0, 0, 0 , 0, 0, 0}; Static Byte STD_DC_Y_VALUES [12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; Static Byte STD_DC_UV_NRCODES [17] = {0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0}; static byte std_dc_uv_values [12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; static Byte std_ac_y_nrcodes [17] = {0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d}; static byte std_ac_y_values [162] = {0x01, 0x02, 0x03, 0x00, 0x12, 0x11, 0x31, 0x41, 0x06 , 0x13, 0x51, 0x61, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0x24, 0x2, 0x15, 0x52, 0x33, 0x62, 0x72, 0x82 0x09, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78 , 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7 , 0xA8, 0xA9, 0XAA, 0XB2, 0XB3, 0XB4, 0XB5, 0XB6, 0XB7, 0XB8, 0X B9, 0XBA, 0XC2, 0XC3, 0XC4, 0XC5, 0XC6, 0XC7, 0XC8, 0XC9, 0XCA, 0XD2, 0XD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA}; Static Byte STD_AC_UV_NRCODES [17] = {0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0X77}; static byte std_ac_uv_values [162] = {0x00, 0x01, 0x02, 0x03, 0x11, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1 , 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0x72, 0x24, 0x0a, 0x16, 0x24, 0x34, 0x1, 0x25, 0x1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28 0x29, 0x2a, 0x35, 0x36, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63 , 0x64, 0x65, 0x66, 0x67, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92 , 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xa8, 0xa9, 0xaa, 0x, 0x, 0xB3, 0xB4, 0XB5, 0XB6, 0XB7, 0XB8, 0XB9 , 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd 9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0XE9, 0XEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xfa}; JPEGFORMAT.H // File start, start tagging as 0xffd8const static word soitag = 0xD8FF; // The file is over, the end is marked as 0xffd9const static Word EOITAG = 0xD9FF; // jfif app0 section Structure #pragma Pack (Push, 1) TypeDef struct tagjpegapp0 {Word segmenttag; // App0 segment mark, must be ffe0 word length; // segment length, generally 16, if there is no thumbnail char ID [5 ]; // File tag "JFIF" "/ 0" word ver; // file version, general 0101 or 0102 Byte DensityUnit; // density unit, 0 = no unit 1 = points / inch 2 = point / cm Word DensityX; // x-axis direction density, usually write 1 word DensityY; // Y-axis direction density, usually write 1 Byte THP; // thumbnail horizontal pixel, write 0 Byte TVP; // Thumbnail vertical pixels, write 0} JPEGAPP0; // = {0xE0FF, 16, 'J', 'F', 'I', 'F', 0, 0x0101, 0, 1, 1, 0, 0}; # prgma Pack (POP) / / Jfif appn section structure #pragma pack (push, 1) type {Word segmenttag; // Appn segment mark, from FFE0 - ffef n = 0-f Word length; // segment length} jpegappn; #pragma Pack (POP ) // jfif DQT segment structure (8 BITS quantization table) #pragma pack (push, 1) TypedEf struct tagjpegdqt_8bits {Word segmenttag; // DQT segment mark, must be 0xffdb Word Length; // Segment length, here is 0x4300 Byte TableInfo; // Quantization table information BYTE TABLE [64]; // Quantization Table (8 Bits)} JPEGDQT_8BITS; #pragma Pack (POP) // JFIF DQT Structure (8 BITS Quantization Table) #pragma Pack (Push, 1) Typedef struct tagjpegdqt_16bits {Word segmenttag; // DQT segment mark, must be 0xffdb Word Length; // Segment length, here is 0x8300 Byte TableInfo; // Quantization Table Information Word Table [64]; // Quantization Table (16 Bits)} JPEGDQT_16Bits; #pragma Pack (POP) // jfif Sof0 Structure (True color), the rest of Sof1-Soff # Pragma Pack (Push, 1) Typedef struct tagjpegsof0_24bits {Word segmenttag; // SOF segment mark, must be 0xffc0 Word Length; // Segment length, true Color map is 17, gray graph is 11 Byte precision; // accuracy, the number of bits used in each signal component, the basic system is 0x08 Word Height; // Image height Word Width; // Image Width Byte Signum; // Signal Quantity, true color JPEG should be 3, grayscale 1 byte yid; // signal number, brightness y byte hvy; // sampling mode, 0-3 bits are vertical sampling, 4-7 bits are horizontal sampling BYTE Qty; / / Corresponding quantization top number BYTE UID; // signal number, color difference u byte hvu; // sampling method, 0-3 bits are vertical sampling, 4-7 bits are horizontal sampling Byte QTU; // correspondence quantization top number Byte VID; // Signal number, color difference V byte hvv; // sampling method, 0-3 bits are vertical sampling, 4-7 bits are horizontal sampling byte qtv; // correspondence quantization table number} JPEGSOF0_24BITS; / / = {0xc0ff, 0x0011, 8, 0, 0, 3, 1, 0x11, 0, 2, 0x11, 1, 3, 0x11, 1}; # prgma pack (POP) // JFIF SOF0 Structure (grayscale), and Sof1-Soff #pragma pack (push, 1) TypedEf struct tagjpegsof0_8bits {Word segmenttag; // SOF segment mark, must be 0xffc0 word length; // segment length, true color map 17, gray graph is 11 Byte precision; // accuracy, The number of bits used in each signal component, the basic system is 0x08 Word Height; // Image Height Word Width; // Image Width Byte Signum; // Signal Number, True Color JPEG should be 3, grayscale 1 Byte YID; / / Signal number, brightness y byte hvy; // sampling method, 0-3 bits are vertical sampling, 4-7 bits are horizontal sampling BYT E qty; // correspondence quantization table number} JPEGSOF0_8BITS; / / = {0xc0FF, 0x000B, 8, 0, 0, 1, 1, 0x11, 0}; # prgma pack (POP) // jfif DHT section structure #pragma pack (push, 1) Typedef struct tagjpegdht {Word segmenttag; // DHT segment mark, must be 0xffc4 Word length; // segment length byte TableInfo; // table information, basic system Bit0- 3 is the number of huffman tables, bit4 is 0 refers to the HUFFMAN table of DC. 1 means AC's Huffman table, Bit5-7 is reserved, must be 0 byte huffcode [16]; // 1-16 bits of Huffman code words, Store in array [1-16] // byte * huffval; // to store values corresponding to each codeword} JPEGDHT; #pragma Pack (POP) // JFIF SOS section structure (True color) #pragma Pack (Push, 1) Typedef struct tagjpegsos_24bits {Word segmenttag; // SOS segment mark, must be 0xffda Word length; // segment length, here is 12 Byte Signum; // Number of signal components, true color map is 0x03, gray graph is 0x01 byte yid; // brightness Y signal ID, here is a table number, BIT0-3 is a table of DC signals, Bit4-7 is The table Byte UID; // Brightness Y signal ID, here is 2 Byte HTU; Byte VID; // Brightness Y signal ID, here is 3 Byte HTV; Byte SS; // Basic system is 0 BYTE SE; / / Basic system is 63 BYTE BF; // Basic system is 0} JPEGSOS_24BITS; / / = {0xDAFF, 0x000c, 3, 1, 0, 2, 0x11, 3, 0x11, 0, 0x3F, 0}; # Pragma Pack (POP) // JFIF SOS Structure (Gray) #pragma Pack (Push, 1) Typedef struct tagjpegsos_8bits {Word segmenttag; // SOS segment mark, must be 0xffda Word length; // segment length, here is 8 Byte Signum; // signal component, true color map is 0x03, gray graph is 0x01 byte yid; // Brightness Y signal ID, here is a table number, BIT0-3 is a table of DC signals, Bit4-7 is a table of AC signals byte ss; // Basic system is 0 BYTE SE; / / Basic system is 63 BYTE BF; // Basic system is 0} jpegsos_8bits; // = {0xDAFF, 0x0008, 1 , 1, 0, 0, 0x3F, 0}; # prgma pack (POP) // jfif COM segment #Pragma Pack (Push, 1) Typedef struct tagjpegcom {Word segmenttag; // COM segment mark, must be 0xffe Word length; // Note length} JPEGCOM; #pragma pack (POP) Main.cpp #include Using namespace std; INT Main (int Argc, char * argv []) {if (argc <= 1) {cout << "please input bmp filename." << endl; return 0;} String filename = String (argv [1]); string outfile = filename.substr (0, filename.find_last_of ('.')); outfile = outfile ".jpg"; JENC ENC; ENC.INVOKE (FileName, Outfile, 100); cout << outfile << endl; getchar (); return 0;}