jpeg 解码成bmp格式

来源:互联网 发布:spss 数据全部成问好 编辑:程序博客网 时间:2024/05/17 21:40

jpeg decode

/***************************************************************************//*                                                                         *//*  File: loadjpg.cpp                                                      *//*  Author: bkenwright@xbdev.net                                           *//*  Date: 19-01-06                                                         *//*                                                                         *//*  Revised: 26-07-07                                                      *//*                                                                         *//***************************************************************************//*    About:Simplified jpg/jpeg decoder image loader - so we can take a .jpg fileeither from memory or file, and convert it either to a .bmp or directlyto its rgb pixel data information.Simplified, and only deals with basic jpgs, but it covers all theinformation of how the jpg format works :)Can be used to convert a jpg in memory to rgb pixels in memory.Or you can pass it a jpg file name and an output bmp filename, and itloads and writes out a bmp file.i.e.ConvertJpgFile("cross.jpg", "cross.bmp")*//***************************************************************************/#pragma once#include <stdio.h>// sprintf(..), fopen(..)#include <stdarg.h>     // So we can use ... (in dprintf)#include <string.h>// memset(..)#include <math.h>// sqrt(..), cos(..)#include <stdbool.h>//bool datatypeextern void dprintf(const char *fmt, ...);//for c++/*void dprintf(const char *fmt, ...){va_list parms;char buf[256];// Try to print in the allocated space.va_start(parms, fmt);vsprintf (buf, fmt, parms);va_end(parms);// Write the information out to a txt fileFILE *fp = fopen("output.txt", "a+");fprintf(fp, "%s", buf);fclose(fp);}// End dprintf(..)*//*__forceinline void dprintf(const char *fmt, ...) {va_list parms;char buf[256];// Try to print in the allocated space.va_start(parms, fmt);vsprintf (buf, fmt, parms);va_end(parms);// Write the information out to a txt fileFILE *fp = fopen("output.txt", "a+");fprintf(fp, "%s",  buf);fclose(fp);}// End dprintf(..)*//***************************************************************************/#define DQT  0xDB// Define Quantization Table#define SOF  0xC0// Start of Frame (size information)#define DHT  0xC4// Huffman Table#define SOI  0xD8// Start of Image#define SOS  0xDA// Start of Scan#define EOI  0xD9// End of Image, or End of File#define APP0 0xE0#define BYTE_TO_WORD(x) (((x)[0]<<8)|(x)[1])#define HUFFMAN_TABLES4#define COMPONENTS4#define cY1#define cCb2#define cCr3static int ZigZagArray[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,};/***************************************************************************///size = 4 + 4 +2//     = 10typedef struct {     int value;// Decodes to.     int length;// Length in bits.     unsigned short int code;// 2 byte code (variable length)}stBlock;/***************************************************************************///size = 4*17 + 4*257 + 4 + 10*1024//     = 11336typedef struct {unsigned charm_length[17];// 17 values from jpg file, // k =1-16 ; L[k] indicates the number of Huffman codes of length kunsigned charm_hufVal[257];// 256 codes read in from the jpeg fileintm_numBlocks;stBlockm_blocks[1024];}stHuffmanTable;// size = 4 + 4 +4 + 11336 + 11336 + 2 +4//       = 22690typedef struct  {  unsigned intm_hFactor;  unsigned intm_vFactor;  float *m_qTable;// Pointer to the quantisation table to use  stHuffmanTable*m_acTable;  stHuffmanTable*m_dcTable;  short intm_DCT[65];// DCT coef  intm_previousDC;}stComponent;//size of a stJpegData = 4(m_rgb) + 2*4(m_width+m_height) + 4(m_stream) + 4*22690 (m_component_info)//        + 64*4*32 (m_Q_tables) + 2*4*11336 (m_HTDC+m_HTAC) + 4*64*4 (m_Y) + 4*64 (m_Cr) + 4*64(m_Cb)//+ 4 (m_colourspace)//    = 191196typedef struct {unsigned char*m_rgb;// Final Red Green Blue pixel dataunsigned intm_width;// Width of imageunsigned intm_height;// Height of imageconst unsigned char*m_stream;// Pointer to the current streamstComponentm_component_info[COMPONENTS];floatm_Q_tables[COMPONENTS][64];// quantization tablesstHuffmanTablem_HTDC[HUFFMAN_TABLES];// DC huffman tables  stHuffmanTablem_HTAC[HUFFMAN_TABLES];// AC huffman tables// Temp space used after the IDCT to store each componentsunsigned charm_Y[64*4];unsigned charm_Cr[64];unsigned charm_Cb[64];// Internal Pointer use for colorspace conversion, do not modify it !!!unsigned char *m_colourspace;}stJpegData;/***************************************************************************/// //  Returns the size of the file in bytes///***************************************************************************/inline int FileSize(FILE *fp){long pos;fseek(fp, 0, SEEK_END);pos = ftell(fp);fseek(fp, 0, SEEK_SET);return pos;}/***************************************************************************/// Clamp our integer between 0 and 255inline unsigned char Clamp(int i){if (i<0)return 0;else if (i>255)return 255;elsereturn i;}   /***************************************************************************/void GenHuffCodes( int num_codes, stBlock* arr, unsigned char* huffVal ){     int hufcounter = 0;     int codelengthcounter = 1;     int cc;     for(cc=0; cc< num_codes; cc++){ while ( arr[cc].length > codelengthcounter ) {hufcounter = hufcounter << 1;codelengthcounter++; } arr[cc].code = hufcounter; arr[cc].value = huffVal[cc]; hufcounter = hufcounter + 1;}}/***************************************************************************/float C(int u){    if (u == 0)         return (1.0f/sqrtf(2));    else         return 1.0f;}int func(int x, int y, const int block[8][8]){const float PI = 3.14f;    float sum=0;int u,v;    for(  u=0; u<8; u++)    {         for(v=0; v<8; v++)         {             sum += ( C(u) * C(v) ) * block[u][v] * cosf( ((2*x+1) * u * PI) / 16)  * cosf( ((2*y+1) * v * PI) / 16);         }    }             return (int) ((1.0/4.0) * sum);}void PerformIDCT(int outBlock[8][8], const int inBlock[8][8]){int x,y;for(y=0; y<8; y++){for(x=0; x<8; x++){outBlock[x][y]  =  func( x, y, inBlock);}}}/***************************************************************************/void DequantizeBlock( int block[64], const float quantBlock[64] ){int c;for( c=0; c<64; c++){block[c] = (int)(block[c] * quantBlock[c]);}}/***************************************************************************/void DeZigZag(int outBlock[64], const int inBlock[64]){int i;for( i=0; i<64; i++){outBlock[ i ] = inBlock[ZigZagArray[i]];}}/***************************************************************************/void TransformArray(int outArray[8][8], const int inArray[64]){int cc = 0;int x,y;for( y=0; y<8; y++){for(x=0; x<8; x++){outArray[x][y]  =  inArray[cc];cc++;}}}/***************************************************************************/void DumpDecodedBlock(int val[8][8]){int x,y;dprintf("# Decoded 8x8 Block#\n");for( y=0; y<8; y++){for( x=0; x<8; x++){dprintf("%2x ", val[x][y]);}dprintf("\n");}}/***************************************************************************/inline void DecodeSingleBlock(stComponent *comp, unsigned char *outputBuf, int stride){short* inptr    = comp->m_DCT;float* quantptr = comp->m_qTable;int i,x,y;// Create a temp 8x8, i.e. 64 array for the dataint data[64] = {0};// Copy our data into the temp arrayfor (i=0; i<64; i++){data[i] = inptr[i];}// De-QuantizeDequantizeBlock(data, quantptr);// De-Zig-Zagint block[64] = {0};DeZigZag(block, data);// Create an 8x8 arrayint arrayBlock[8][8]={0};TransformArray(arrayBlock, block);// Inverse DCTint val[8][8]={0};PerformIDCT(val, arrayBlock);// Level Shift each element (i.e. add 128), and copy to our// outputunsigned char *outptr = outputBuf;for (y = 0; y < 8; y++) {for (x=0; x<8; x++){val[x][y] += 128;outptr[x] = Clamp(val[x][y]);}outptr += stride;}DumpDecodedBlock(val);}/***************************************************************************//***************************************************************************///// Save a buffer in 24bits Bitmap (.bmp) format ///***************************************************************************/inline void WriteBMP24(const char* szBmpFileName, int Width, int Height, unsigned char* RGB){#pragma pack(1)typedef struct // BitmapFileHeader & BitmapInfoHeader{// BitmapFileHeaderchar         bmtype[2];     // 2 bytes - 'B' 'M'unsigned int iFileSize;     // 4 bytesshort int    reserved1;     // 2 bytesshort int    reserved2;     // 2 bytesunsigned int iOffsetBits;   // 4 bytes// End of stBMFH structure - size of 14 bytes// BitmapInfoHeaderunsigned int iSizeHeader;    // 4 bytes - 40unsigned int iWidth;         // 4 bytesunsigned int iHeight;        // 4 bytesshort int    iPlanes;        // 2 bytesshort int    iBitCount;      // 2 bytesunsigned int Compression;    // 4 bytesunsigned int iSizeImage;     // 4 bytesunsigned int iXPelsPerMeter; // 4 bytesunsigned int iYPelsPerMeter; // 4 bytesunsigned int iClrUsed;       // 4 bytesunsigned int iClrImportant;  // 4 bytes// End of stBMIF structure - size 40 bytes// Total size - 54 bytes}stBMFH ;#pragma pack()int x,y;// Round up the width to the nearest DWORD boundaryint iNumPaddedBytes = 4 - (Width * 3) % 4;iNumPaddedBytes = iNumPaddedBytes % 4;stBMFH bh;memset(&bh, 0, sizeof(bh));bh.bmtype[0]='B';bh.bmtype[1]='M';bh.iFileSize = (Width*Height*3) + (Height*iNumPaddedBytes) + sizeof(bh);bh.iOffsetBits = sizeof(stBMFH);bh.iSizeHeader = 40;bh.iPlanes = 1;bh.iWidth = Width;bh.iHeight = Height;bh.iBitCount = 24;char temp[1024]={0};sprintf(temp, "%s", szBmpFileName);FILE* fp = fopen(temp, "wb");fwrite(&bh, sizeof(bh), 1, fp);for ( y=Height-1; y>=0; y--){for (x=0; x<Width; x++){int i = (x + (Width)*y) * 3;unsigned int rgbpix = (RGB[i]<<16)|(RGB[i+1]<<8)|(RGB[i+2]<<0);fwrite(&rgbpix, 3, 1, fp);}if (iNumPaddedBytes>0){unsigned char pad = 0;fwrite(&pad, iNumPaddedBytes, 1, fp);}}fclose(fp);}/***************************************************************************/// Takes two array of bits, and build the huffman table for size, and code/***************************************************************************/inline void BuildHuffmanTable(const unsigned char *bits, const unsigned char *stream, stHuffmanTable *HT){int i,j;for (j=1; j<=16; j++) {HT->m_length[j] = bits[j];}// Work out the total number of codesint numBlocks = 0;for (i=1; i<=16; i++){numBlocks += HT->m_length[i];}HT->m_numBlocks = numBlocks;// Fill in the data our our blocks, so we know how many bits each// one isint c=0;for (i=1; i<=16; i++){for (j=0; j<HT->m_length[i]; j++){HT->m_blocks[c].length = i;c++;}}GenHuffCodes(HT->m_numBlocks, HT->m_blocks, HT->m_hufVal);}/***************************************************************************/inline void PrintSOF(const unsigned char *stream){int width;int height;int nr_components;int precision;const char *nr_components_to_string[] ={"????","Grayscale","????","YCbCr","CYMK" };precision = stream[2];height = BYTE_TO_WORD(stream+3);width  = BYTE_TO_WORD(stream+5);nr_components = stream[7];dprintf("> SOF marker\n");dprintf("Size:%dx%d nr_components:%d (%s)  precision:%d\n", width, height,nr_components, nr_components_to_string[nr_components],precision);}/***************************************************************************/inline int ParseSOF(stJpegData *jdata, const unsigned char *stream){/*SOF160xffc0Start Of FrameLf163Nf+8Frame header lengthP88Sample precisionY160-65535Number of linesX161-65535Samples per lineNf81-255Number of image components (e.g. Y, U and V).---------Repeats for the number of components (e.g. Nf)-----------------Ci80-255Component identifierHi41-4Horizontal Sampling FactorVi41-4Vertical Sampling FactorTqi80-3Quantization Table Selector.*/PrintSOF(stream);int height = BYTE_TO_WORD(stream+3);int width  = BYTE_TO_WORD(stream+5);int nr_components = stream[7];int i;stream += 8;for (i=0; i<nr_components; i++) {int cid= *stream++;int sampling_factor = *stream++;int Q_table= *stream++;stComponent *c = &jdata->m_component_info[cid];c->m_vFactor = sampling_factor&0xf;c->m_hFactor = sampling_factor>>4;c->m_qTable = jdata->m_Q_tables[Q_table];dprintf("Component:%d  factor:%dx%d  Quantization table:%d\n",cid, c->m_vFactor, c->m_hFactor, Q_table );}jdata->m_width = width;jdata->m_height = height;return 0;}/***************************************************************************/inline void BuildQuantizationTable(float *qtable, const unsigned char *ref_table){int c = 0;int i,j;for (i=0; i<8; i++) {for ( j=0; j<8; j++) {unsigned char val = ref_table[c];qtable[c] = val;c++;}}}/***************************************************************************/inline int ParseDQT(stJpegData *jdata, const unsigned char *stream){int length, qi;float *table;dprintf("> DQT marker\n");length = BYTE_TO_WORD(stream) - 2;stream += 2;// Skip lengthwhile (length>0){qi = *stream++;int qprecision = qi>>4; // upper 4 bits specify the precisionint qindex     = qi&0xf; // index is lower 4 bitsif (qprecision){// precision in this case is either 0 or 1 and indicates the precision // of the quantized values;// 8-bit (baseline) for 0 and  up to 16-bit for 1 dprintf("Error - 16 bits quantization table is not supported\n");}if (qindex>4){dprintf("Error - No more 4 quantization table is supported (got %d)\n", qi);}// The quantization table is the next 64 bytestable = jdata->m_Q_tables[qindex];// the quantization tables are stored in zigzag format, so we// use this functino to read them all in and de-zig zag themBuildQuantizationTable(table, stream);stream += 64;length -= 65;}return 0;}/***************************************************************************/inline int ParseSOS(stJpegData *jdata, const unsigned char *stream){/*SOS160xffd8Start Of ScanLs162Ns + 6Scan header lengthNs81-4Number of image componentsCsj80-255Scan Component SelectorTdj40-1DC Coding Table SelectorTaj40-1AC Coding Table SelectorSs80Start of spectral selectionSe863End of spectral selectionAh40Successive Approximation Bit HighAi40Successive Approximation Bit Low*/unsigned int nr_components = stream[2];unsigned int i;dprintf("> SOS marker\n");if (nr_components != 3){dprintf("Error - We only support YCbCr image\n");}stream += 3;for ( i=0;i<nr_components;i++) {unsigned int cid   = *stream++;unsigned int table = *stream++;if ((table&0xf)>=4){dprintf("Error - We do not support more than 2 AC Huffman table\n");}if ((table>>4)>=4){dprintf("Error - We do not support more than 2 DC Huffman table\n");}dprintf("ComponentId:%d  tableAC:%d tableDC:%d\n", cid, table&0xf, table>>4);jdata->m_component_info[cid].m_acTable = &jdata->m_HTAC[table&0xf];jdata->m_component_info[cid].m_dcTable = &jdata->m_HTDC[table>>4];}jdata->m_stream = stream+3;return 0;}/***************************************************************************/inline int ParseDHT(stJpegData *jdata, const unsigned char *stream){/*u8 0xff u8 0xc4 (type of segment) u16 be length of segment 4-bits class (0 is DC, 1 is AC, more on this later) 4-bits table id array of 16 u8 number of elements for each of 16 depths array of u8 elements, in order of depth */unsigned int count, i;unsigned char huff_bits[17];int length, index;length = BYTE_TO_WORD(stream) - 2;stream += 2;// Skip lengthdprintf("> DHT marker (length=%d)\n", length);while (length>0) {index = *stream++;// We need to calculate the number of bytes 'vals' will takeshuff_bits[0] = 0;count = 0;for (i=1; i<17; i++) {huff_bits[i] = *stream++;count += huff_bits[i];}if (count > 256){dprintf("Error - No more than 1024 bytes is allowed to describe a huffman table");}if ( (index &0xf) >= HUFFMAN_TABLES){dprintf("Error - No mode than %d Huffman tables is supported\n", HUFFMAN_TABLES);}dprintf("Huffman table %s n%d\n", (index&0xf0)?"AC":"DC", index&0xf);dprintf("Length of the table: %d\n", count);if (index & 0xf0 ){unsigned char* huffval = jdata->m_HTAC[index&0xf].m_hufVal;for (i = 0; i < count; i++)huffval[i] = *stream++;BuildHuffmanTable(huff_bits, stream, &jdata->m_HTAC[index&0xf]); // AC}else{unsigned char* huffval = jdata->m_HTDC[index&0xf].m_hufVal;for (i = 0; i < count; i++)huffval[i] = *stream++;BuildHuffmanTable(huff_bits, stream, &jdata->m_HTDC[index&0xf]); // DC}length -= 1;length -= 16;length -= count;}dprintf("< DHT marker\n");return 0;}/***************************************************************************/inline int ParseJFIF(stJpegData *jdata, const unsigned char *stream){int chuck_len;int marker;int sos_marker_found = 0;int dht_marker_found = 0;// Parse markerwhile (!sos_marker_found){if (*stream++ != 0xff){goto bogus_jpeg_format;}// Skip any padding ff byte (this is normal)while (*stream == 0xff){stream++;}marker = *stream++;chuck_len = BYTE_TO_WORD(stream);switch (marker){case SOF:{if (ParseSOF(jdata, stream) < 0)return -1;}break;case DQT:{if (ParseDQT(jdata, stream) < 0)return -1;}break;case SOS:{if (ParseSOS(jdata, stream) < 0)return -1;sos_marker_found = 1;}break;case DHT:{if (ParseDHT(jdata, stream) < 0)return -1;dht_marker_found = 1;}break;// The reason I added these additional skips here, is because for// certain jpg compressions, like swf, it splits the encoding // and image data with SOI & EOI extra tags, so we need to skip// over them here and decode the whole imagecase SOI:case EOI:{chuck_len = 0;break;}break;case 0xDD: //DRI: Restart_markers=1;{dprintf("DRI - Restart_marker\n");}break;case APP0:{dprintf("APP0 Chunk ('txt' information) skipping\n");}break;default:{dprintf("ERROR> Unknown marker %2.2x\n", marker);}break;}stream += chuck_len;}if (!dht_marker_found) {dprintf("ERROR> No Huffman table loaded\n");}return 0;bogus_jpeg_format:dprintf("ERROR> Bogus jpeg format\n");return -1;}/***************************************************************************/inline int JpegParseHeader(stJpegData *jdata, const unsigned char *buf, unsigned int size){// Identify the fileif ((buf[0] != 0xFF) || (buf[1] != SOI)){dprintf("Not a JPG file ?\n");return -1;}const unsigned char* startStream = buf+2;const int fileSize = size-2;dprintf("-|- File thinks its size is: %d bytes\n", fileSize);int ret = ParseJFIF(jdata, startStream);return ret;}/***************************************************************************/inline void JpegGetImageSize(stJpegData *jdata, unsigned int *width, unsigned int *height){*width  = jdata->m_width;*height = jdata->m_height;}/***************************************************************************/unsigned int g_reservoir = 0;unsigned int g_nbits_in_reservoir = 0;inline void FillNBits(const unsigned char** stream, int nbits_wanted){while ((int)g_nbits_in_reservoir<nbits_wanted){const unsigned char c = *(*stream)++;g_reservoir <<= 8;if (c == 0xff && (**stream) == 0x00)(*stream)++;g_reservoir |= c;g_nbits_in_reservoir+=8;}}inline short GetNBits(const unsigned char** stream, int nbits_wanted){FillNBits(stream, nbits_wanted);short result = ((g_reservoir)>>(g_nbits_in_reservoir-(nbits_wanted))); g_nbits_in_reservoir -= (nbits_wanted); g_reservoir &= ((1U<<g_nbits_in_reservoir)-1);/*// Could do the sign conversion here!if (result < (short)(1UL<<((nbits_wanted)-1))){result = result + (short)(0xFFFFFFFFUL<<(nbits_wanted))+1;}*/return result;}inline int LookNBits(const unsigned char** stream, int nbits_wanted){FillNBits(stream, nbits_wanted);int result = ((g_reservoir)>>(g_nbits_in_reservoir-(nbits_wanted)));return result;}inline void SkipNBits(const unsigned char** stream, int nbits_wanted){FillNBits(stream, nbits_wanted);g_nbits_in_reservoir -= (nbits_wanted); g_reservoir &= ((1U<<g_nbits_in_reservoir)-1);}/***************************************************************************/bool IsInHuffmanCodes(int code, int numCodeBits, int numBlocks, stBlock* blocks, int* outValue){int j;for ( j=0; j<numBlocks; j++){int hufhCode= blocks[j].code;int hufCodeLenBits= blocks[j].length;int hufValue= blocks[j].value;// We've got a match!if ((code==hufhCode) && (numCodeBits==hufCodeLenBits)){*outValue = hufValue;return true;}}return false;}/***************************************************************************/int DetermineSign(int val, int nBits){bool negative = val < (1<<(nBits-1));if (negative){// (-1 << (s)), makes the last bit a 1, so we have 1000,0000 for example for 8 bitsval = val + (-1 << (nBits)) + 1; }// Else its unsigned, just returnreturn val;}/***************************************************************************/char g_bigBuf[1024] = {0};char* IntToBinary(int val, int bits){int i;for (i=0; i<32; i++) g_bigBuf[i]='\0';int c = 0;for (i=bits-1; i>=0; i--){bool on = (val & (1<<i)) ? 1 : 0;g_bigBuf[c] = on ? '1' : '0';c++;}return &g_bigBuf[0];}/***************************************************************************/void DumpHufCodes(stHuffmanTable* table){int i;dprintf("HufCodes\n");dprintf("Num: %d\n", table->m_numBlocks);for (i = 0; i<table->m_numBlocks; i++){dprintf("%03d\t [%s]\n", i, IntToBinary(table->m_blocks[i].code, table->m_blocks[i].length));}dprintf("\n");}/***************************************************************************/void DumpDCTValues(short dct[64]){int i;dprintf("\n#Extracted DCT values from SOS#\n");int c = 0;for ( i=0; i<64; i++){dprintf("% 4d  ", dct[c++]);if ( (c>0) && (c%8==0) ) dprintf("\n");}dprintf("\n");}/***************************************************************************/void ProcessHuffmanDataUnit(stJpegData *jdata, int indx){stComponent *c = &jdata->m_component_info[indx];// Start Huffman decoding// We memset it here, as later on we can just skip along, when we have lots// of leading zeros, for our AC run length encoding :)short DCT_tcoeff[64];memset(DCT_tcoeff, 0, sizeof(DCT_tcoeff)); //Initialize DCT_tcoeffbool found = false;int decodedValue = 0;int k,j;//DumpHufCodes(c->m_dcTable);//DumpHufCodes(c->m_acTable);dprintf("\nHuff Block:\n\n");// First thing is get the 1 DC coefficient at the start of our 64 element// blockfor (k=1; k<16; k++){// Keep grabbing one bit at a time till we find one thats a huffman codeint code = LookNBits(&jdata->m_stream, k);// Check if its one of our huffman codesif (IsInHuffmanCodes(code, k,  c->m_dcTable->m_numBlocks, c->m_dcTable->m_blocks, &decodedValue)){// Skip over the rest of the bits now.SkipNBits(&jdata->m_stream, k);found = true;// The decoded value is the number of bits we have to read in nextint numDataBits = decodedValue;// We know the next k bits are for the actual dataif (numDataBits==0){DCT_tcoeff[0] = c->m_previousDC;}else{short data = GetNBits(&jdata->m_stream, numDataBits);data = DetermineSign(data, numDataBits);DCT_tcoeff[0] = data + c->m_previousDC;c->m_previousDC = DCT_tcoeff[0];}// Found so we can exit outbreak;}}if (!found){dprintf("-|- ##ERROR## We have a *serious* error, unable to find huffman code\n");}// Second, the 63 AC coefficientint nr=1; bool EOB_found=false;while ( (nr<=63)&&(!EOB_found) ){k = 0;for (k=1; k<=16; k++){// Keep grabbing one bit at a time till we find one thats a huffman codeint code = LookNBits(&jdata->m_stream, k);// Check if its one of our huffman codesif (IsInHuffmanCodes(code, k,  c->m_acTable->m_numBlocks, c->m_acTable->m_blocks, &decodedValue)){// Skip over k bits, since we found the huffman valueSkipNBits(&jdata->m_stream, k);// Our decoded value is broken down into 2 parts, repeating RLE, and then// the number of bits that make up the actual value nextint valCode = decodedValue;unsigned char size_val = valCode&0xF;// Number of bits for our dataunsigned char count_0  = valCode>>4;// Number RunLengthZerosif (size_val==0) {// RLE if (count_0==0)EOB_found=true;// EOB found, go outelse if (count_0==0xF) nr+=16;  // skip 16 zeros}else{nr+=count_0; //skip count_0 zeroesif (nr > 63){dprintf("-|- ##ERROR## Huffman Decoding\n");}short data = GetNBits(&jdata->m_stream, size_val );data = DetermineSign(data, size_val);DCT_tcoeff[nr++]=data;}break;}}if (k>16){nr++;}}DumpDCTValues(DCT_tcoeff);// We've decoded a block of data, so copy it across to our bufferfor ( j = 0; j < 64; j++){c->m_DCT[j] = DCT_tcoeff[j];}}/***************************************************************************/inline void ConvertYCrCbtoRGB(int y, int cb, int cr,  int* r, int* g, int* b){float red, green, blue;red   = y + 1.402f*(cb-128);green = y-0.34414f*(cr-128)-0.71414f*(cb-128);blue  = y+1.772f*(cr-128);*r = (int) Clamp((int)red);*g = (int) Clamp((int)green);*b = (int) Clamp((int)blue);}/***************************************************************************/inline void YCrCB_to_RGB24_Block8x8(stJpegData *jdata, int w, int h, int imgx, int imgy, int imgw, int imgh){const unsigned char *Y, *Cb, *Cr;unsigned char *pix;int x,y;int r, g, b;Y  = jdata->m_Y;Cb = jdata->m_Cb;Cr = jdata->m_Cr;int olw = 0; // overlapif ( imgx > (imgw-8*w) ){olw = imgw-imgx;}int olh = 0; // overlapif ( imgy > (imgh-8*h) ){olh = imgh-imgy;}//dprintf("***pix***\n\n");for ( y=0; y<(8*h - olh); y++){for ( x=0; x<(8*w - olw); x++){int poff = x*3 + jdata->m_width*3*y;pix = &(jdata->m_colourspace[poff]);int yoff = x + y*(w*8);int coff = (int)(x*(1.0f/w)) + (int)(y*(1.0f/h))*8;int yc =  Y[yoff];int cb = Cb[coff];int cr = Cr[coff];ConvertYCrCbtoRGB(yc,cr,cb,&r,&g,&b);pix[0] = Clamp(r);pix[1] = Clamp(g);pix[2] = Clamp(b);//dprintf("-[%d][%d][%d]-\t", poff, yoff, coff);}//dprintf("\n");}//dprintf("\n\n");}/***************************************************************************/////  Decoding//  .-------.//  | 1 | 2 |//  |---+---|//  | 3 | 4 |//  `-------'///***************************************************************************/inline void DecodeMCU(stJpegData *jdata, int w, int h){int x,y;// Yfor (y=0; y<h; y++){for (x=0; x<w; x++){int stride = w*8;int offset = x*8 + y*64*w;ProcessHuffmanDataUnit(jdata, cY);DecodeSingleBlock(&jdata->m_component_info[cY], &jdata->m_Y[offset], stride);}}// CbProcessHuffmanDataUnit(jdata, cCb);DecodeSingleBlock(&jdata->m_component_info[cCb], jdata->m_Cb, 8);// CrProcessHuffmanDataUnit(jdata, cCr);DecodeSingleBlock(&jdata->m_component_info[cCr], jdata->m_Cr, 8);}/***************************************************************************/inline int JpegDecode(stJpegData *jdata){int x,y;int hFactor = jdata->m_component_info[cY].m_hFactor;int vFactor = jdata->m_component_info[cY].m_vFactor;// RGB24:if (jdata->m_rgb == NULL){int h = jdata->m_height*3;int w = jdata->m_width*3;int height = h + (8*hFactor) - (h%(8*hFactor));int width  = w + (8*vFactor) - (w%(8*vFactor));//of implementation new in c language//no need for c++jdata->m_rgb = malloc(width * height);/////////////////////////////////////in c++//jdata->m_rgb = new unsigned char[width * height];memset(jdata->m_rgb, 0, width*height);}jdata->m_component_info[0].m_previousDC = 0;jdata->m_component_info[1].m_previousDC = 0;jdata->m_component_info[2].m_previousDC = 0;jdata->m_component_info[3].m_previousDC = 0;int xstride_by_mcu = 8*hFactor;int ystride_by_mcu = 8*vFactor;// Don't forget to that block can be either 8 or 16 linesunsigned int bytes_per_blocklines = jdata->m_width*3 * ystride_by_mcu;unsigned int bytes_per_mcu = 3*xstride_by_mcu;// Just the decode the image by 'macroblock' (size is 8x8, 8x16, or 16x16)for (y=0 ; y<(int)jdata->m_height; y+=ystride_by_mcu){for (x=0; x<(int)jdata->m_width; x+=xstride_by_mcu){jdata->m_colourspace = jdata->m_rgb + x*3 + (y *jdata->m_width*3);// Decode MCU PlaneDecodeMCU(jdata, hFactor, vFactor );YCrCB_to_RGB24_Block8x8(jdata, hFactor, vFactor, x, y, jdata->m_width, jdata->m_height);}}return 0;}/***************************************************************************///// Take Jpg data, i.e. jpg file read into memory, and decompress it to an// array of rgb pixel values.//// Note - Memory is allocated for this function, so delete it when finished///***************************************************************************/int DecodeJpgFileData(const unsigned char* buf, // Jpg file in memory  const int sizeBuf,// Size jpg in bytes in memory  unsigned char** rgbpix,// Output rgb pixels  unsigned int* width,// Output image width  unsigned int* height)// Output image height{// Allocate memory for our decoded jpg structure, all our data will be// decompressed and stored in here for the various stages of our jpeg decoding//c++//stJpegData* jdec = new stJpegData();//cstJpegData* jdec = malloc(191196);if (jdec == NULL){dprintf("Not enough memory to alloc the structure need for decompressing\n");return 0;}// Start Parsing.....reading & storing dataif (JpegParseHeader(jdec, buf, sizeBuf)<0){dprintf("ERROR > parsing jpg header\n");}// We've read it all in, now start using it, to decompress and create rgb valuesdprintf("Decoding JPEG image...\n");JpegDecode(jdec);// Get the size of the imageJpegGetImageSize(jdec, width, height);*rgbpix = jdec->m_rgb;// Release the memory for our jpeg decoder structure jdec//c++//delete jdec;// cfree(jdec);return 1;}/***************************************************************************///// Load one jpeg image, and decompress it, and save the result.///***************************************************************************/int ConvertJpgFile(char* szJpgFileInName, char * szBmpFileOutName){FILE *fp;unsigned int lengthOfFile;unsigned char *buf;// Load the Jpeg into memoryfp = fopen(szJpgFileInName, "rb");if (fp == NULL){dprintf("Cannot open jpg file: %s\n", szJpgFileInName);return 0;}lengthOfFile = FileSize(fp);//c++//buf = new unsigned char[lengthOfFile + 4];//cbuf=malloc((unsigned int)(lengthOfFile+4));if (buf == NULL){dprintf("Not enough memory for loading file\n");return 0;}fread(buf, lengthOfFile, 1, fp);fclose(fp);unsigned char* rgbpix = NULL;unsigned int width  = 0;unsigned int height = 0;DecodeJpgFileData(buf, lengthOfFile, &rgbpix, &width, &height);if (rgbpix==NULL){dprintf("Failed to decode jpg\n");return 0;}// Delete our data we read in from the file//c++//delete[] buf;//cfree(buf);// Save itWriteBMP24(szBmpFileOutName, width, height, rgbpix);// Since we don't need the pixel information anymore, we must// release this as well//c++//delete[] rgbpix;//cfree(rgbpix);return 1;}/***************************************************************************/int main(){if (ConvertJpgFile("smiley.jpg","1.bmp"))printf("successful");return 1;}