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;}
- jpeg 解码成bmp格式
- 用CxImage将BMP位图转换成JPEG格式
- RGB数据转bmp、jpeg格式
- BMP、JPEG、PNG、GIF格式总结
- 将PNG、JPG、JPEG、BMP格式的图档转化成eps格式的图档
- BMP格式知识之三:bmp格式的编解码
- C语言实现的BMP和JPEG图片的解码
- VC中JPEG格式到BMP格式的转换
- libjpeg-turbo使用实例(编解码jpeg、jpg转bmp、bmp转jpg代码)
- BMP、PCX、PNG、JPEG、GIF图形格式区别
- Android 获取图片资源格式(png、jpeg、gif、bmp、...)
- Android实现BMP和PNG转换为JPEG格式
- JPEG解码
- jpeg解码
- JPEG解码
- JPEG解码
- jpeg解码
- Jpeg文件格式转换成bmp文件格式
- Oracle 冷备份
- Eclipse 快捷键
- 关于 AIX 特定 文件 系统 下 , 没有权限 执行 (已解决)
- Linux系统控制文件 /etc/sysctl.conf
- android之android:paddingLeft和android:layout_marginLeft区别:
- jpeg 解码成bmp格式
- 使用javascript对table动态的添加、删除
- android获取设备屏幕大小的方法
- c++的拷贝构造函数的思考(当返回对象时,发生什么)
- PGP加密原理
- 浅谈当前电信检测宽带共享的机制
- jsp生成静态html页面
- Mongoose使用小结
- tpch