BMP图片转JPEG图片C程序源代码.doc_第1页
BMP图片转JPEG图片C程序源代码.doc_第2页
BMP图片转JPEG图片C程序源代码.doc_第3页
BMP图片转JPEG图片C程序源代码.doc_第4页
BMP图片转JPEG图片C程序源代码.doc_第5页
免费预览已结束,剩余13页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

/ A BMP truecolor to JPEG encoder/ Copyright 1999 Cristian Cuturicu#include #include #include #include jtypes.h#include jglobals.h#include jtables.hvoid write_APP0info()/Nothing to overwrite for APP0infowriteword(APP0info.marker);writeword(APP0info.length);writebyte(J);writebyte(F);writebyte(I);writebyte(F);writebyte(0);writebyte(APP0info.versionhi);writebyte(APP0info.versionlo);writebyte(APP0info.xyunits);writeword(APP0info.xdensity);writeword(APP0info.ydensity);writebyte(APP0info.thumbnwidth);writebyte(APP0info.thumbnheight);void write_SOF0info()/ We should overwrite width and heightwriteword(SOF0info.marker);writeword(SOF0info.length);writebyte(SOF0info.precision);writeword(SOF0info.height);writeword(SOF0info.width);writebyte(SOF0info.nrofcomponents);writebyte(SOF0info.IdY);writebyte(SOF0info.HVY);writebyte(SOF0info.QTY);writebyte(SOF0info.IdCb);writebyte(SOF0info.HVCb);writebyte(SOF0info.QTCb);writebyte(SOF0info.IdCr);writebyte(SOF0info.HVCr);writebyte(SOF0info.QTCr);void write_DQTinfo()BYTE i;writeword(DQTinfo.marker);writeword(DQTinfo.length);writebyte(DQTinfo.QTYinfo);for (i=0; i64; i+) writebyte(DQTinfo.Ytablei);writebyte(DQTinfo.QTCbinfo);for (i=0; i64; i+) writebyte(DQTinfo.Cbtablei);void set_quant_table(BYTE *basic_table, BYTE scale_factor, BYTE *newtable)/ Set quantization table and zigzag reorder itBYTE i;long temp;for (i=0; i64; i+) temp = (long) basic_tablei * scale_factor + 50L) / 100L;/ limit the values to the valid rangeif (temp 255L) temp = 255L; newtablezigzagi = (BYTE) temp;void set_DQTinfo()BYTE scalefactor = 50;/ scalefactor controls the visual quality of the image/ the smaller is the better image well get, and the smaller / compression well achieveDQTinfo.marker = 0xFFDB;DQTinfo.length = 132;DQTinfo.QTYinfo = 0;DQTinfo.QTCbinfo = 1;set_quant_table(std_luminance_qt, scalefactor, DQTinfo.Ytable);set_quant_table(std_chrominance_qt, scalefactor, DQTinfo.Cbtable);void write_DHTinfo()BYTE i;writeword(DHTinfo.marker);writeword(DHTinfo.length);writebyte(DHTinfo.HTYDCinfo);for (i=0; i16; i+) writebyte(DHTinfo.YDC_nrcodesi);for (i=0; i12; i+) writebyte(DHTinfo.YDC_valuesi);writebyte(DHTinfo.HTYACinfo);for (i=0; i16; i+)writebyte(DHTinfo.YAC_nrcodesi);for (i=0; i162; i+) writebyte(DHTinfo.YAC_valuesi);writebyte(DHTinfo.HTCbDCinfo);for (i=0; i16; i+) writebyte(DHTinfo.CbDC_nrcodesi);for (i=0; i12; i+)writebyte(DHTinfo.CbDC_valuesi);writebyte(DHTinfo.HTCbACinfo);for (i=0; i16; i+)writebyte(DHTinfo.CbAC_nrcodesi);for (i=0; i162; i+)writebyte(DHTinfo.CbAC_valuesi);void set_DHTinfo()BYTE i;/ fill the DHTinfo structure get the values from the standard Huffman tablesDHTinfo.marker = 0xFFC4;DHTinfo.length = 0x01A2;DHTinfo.HTYDCinfo = 0;for (i=0; i16; i+)DHTinfo.YDC_nrcodesi = std_dc_luminance_nrcodesi+1;for (i=0; i12; i+)DHTinfo.YDC_valuesi = std_dc_luminance_valuesi;DHTinfo.HTYACinfo = 0x10;for (i=0; i16; i+)DHTinfo.YAC_nrcodesi = std_ac_luminance_nrcodesi+1;for (i=0; i162; i+)DHTinfo.YAC_valuesi = std_ac_luminance_valuesi;DHTinfo.HTCbDCinfo = 1;for (i=0; i16; i+)DHTinfo.CbDC_nrcodesi = std_dc_chrominance_nrcodesi+1;for (i=0; i12; i+)DHTinfo.CbDC_valuesi = std_dc_chrominance_valuesi;DHTinfo.HTCbACinfo = 0x11;for (i=0; i16; i+)DHTinfo.CbAC_nrcodesi = std_ac_chrominance_nrcodesi+1;for (i=0; i162; i+)DHTinfo.CbAC_valuesi = std_ac_chrominance_valuesi;void write_SOSinfo()/Nothing to overwrite for SOSinfowriteword(SOSinfo.marker);writeword(SOSinfo.length);writebyte(SOSinfo.nrofcomponents);writebyte(SOSinfo.IdY);writebyte(SOSinfo.HTY);writebyte(SOSinfo.IdCb);writebyte(SOSinfo.HTCb);writebyte(SOSinfo.IdCr);writebyte(SOSinfo.HTCr);writebyte(SOSinfo.Ss);writebyte(SOSinfo.Se);writebyte(SOSinfo.Bf);void write_comment(BYTE *comment)WORD i, length;writeword(0xFFFE); / The COM markerlength = strlen(const char *)comment);writeword(length + 2);for (i=0; ilength; i+) writebyte(commenti);void writebits(bitstring bs)/ A portable version; it should be done in assemblerWORD value;SBYTE posval;/ bit position in the bitstring we read, should be =0 value = bs.value;posval = bs.length - 1;while (posval = 0)if (value & maskposval) bytenew |= maskbytepos;posval-;bytepos-;if (bytepos 0) / write itif (bytenew = 0xFF) / special casewritebyte(0xFF);writebyte(0);else writebyte(bytenew);/ reinitbytepos = 7;bytenew = 0;void compute_Huffman_table(BYTE *nrcodes, BYTE *std_table, bitstring *HT)BYTE k,j;BYTE pos_in_table;WORD codevalue;codevalue = 0; pos_in_table = 0;for (k=1; k=16; k+)for (j=1; j=nrcodesk; j+) HTstd_tablepos_in_table.value = codevalue;HTstd_tablepos_in_table.length = k;pos_in_table+;codevalue+;codevalue = 1;void init_Huffman_tables()/ Compute the Huffman tables used for encodingcompute_Huffman_table(std_dc_luminance_nrcodes, std_dc_luminance_values, YDC_HT);compute_Huffman_table(std_ac_luminance_nrcodes, std_ac_luminance_values, YAC_HT);compute_Huffman_table(std_dc_chrominance_nrcodes, std_dc_chrominance_values, CbDC_HT);compute_Huffman_table(std_ac_chrominance_nrcodes, std_ac_chrominance_values, CbAC_HT);void exitmessage(char *error_message)printf(%sn,error_message);exit(EXIT_FAILURE);void set_numbers_category_and_bitcode()SDWORD nr;SDWORD nrlower, nrupper;BYTE cat;category_alloc = (BYTE *)malloc(65535*sizeof(BYTE);if (category_alloc = NULL) exitmessage(Not enough memory.);/allow negative subscriptscategory = category_alloc + 32767; bitcode_alloc=(bitstring *)malloc(65535*sizeof(bitstring);if (bitcode_alloc=NULL) exitmessage(Not enough memory.);bitcode = bitcode_alloc + 32767;nrlower = 1;nrupper = 2;for (cat=1; cat=15; cat+) /Positive numbersfor (nr=nrlower; nrnrupper; nr+) categorynr = cat;bitcodenr.length = cat;bitcodenr.value = (WORD)nr;/Negative numbersfor (nr=-(nrupper-1); nr=-nrlower; nr+) categorynr = cat;bitcodenr.length = cat;bitcodenr.value = (WORD)(nrupper-1+nr);nrlower = 1;nrupper = 1;void precalculate_YCbCr_tables()WORD R,G,B;for (R=0; R256; R+) YRtabR = (SDWORD)(65536*0.299+0.5)*R;CbRtabR = (SDWORD)(65536*-0.16874+0.5)*R;CrRtabR = (SDWORD)(32768)*R;for (G=0; G256; G+) YGtabG = (SDWORD)(65536*0.587+0.5)*G;CbGtabG = (SDWORD)(65536*-0.33126+0.5)*G;CrGtabG = (SDWORD)(65536*-0.41869+0.5)*G;for (B=0; B256; B+) YBtabB = (SDWORD)(65536*0.114+0.5)*B;CbBtabB = (SDWORD)(32768)*B;CrBtabB = (SDWORD)(65536*-0.08131+0.5)*B;/ Using a bit modified form of the FDCT routine from IJGs C source:/ Forward DCT routine idea taken from Independent JPEG Groups C source for/ JPEG encoders/decoders/* For float AA&N IDCT method, divisors are equal to quantization coefficients scaled by scalefactorrow*scalefactorcol, where scalefactor0 = 1 scalefactork = cos(k*PI/16) * sqrt(2) for k=1.7 We apply a further scale factor of 8. Whats actually stored is 1/divisor so that the inner loop can use a multiplication rather than a division. */void prepare_quant_tables()double aanscalefactor8 = 1.0, 1.387039845, 1.306562965, 1.175875602,1.0, 0.785694958, 0.541196100, 0.275899379;BYTE row, col;BYTE i = 0;for (row = 0; row 8; row+)for (col = 0; col 8; col+)fdtbl_Yi = (float) (1.0 / (double) DQTinfo.Ytablezigzagi *aanscalefactorrow * aanscalefactorcol * 8.0);fdtbl_Cbi = (float) (1.0 / (double) DQTinfo.Cbtablezigzagi *aanscalefactorrow * aanscalefactorcol * 8.0);i+;void fdct_and_quantization(SBYTE *data, float *fdtbl, SWORD *outdata)float tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;float tmp10, tmp11, tmp12, tmp13;float z1, z2, z3, z4, z5, z11, z13;float *dataptr;float datafloat64;float temp;SBYTE ctr;BYTE i;for (i=0; i= 0; ctr-) tmp0 = dataptr0 + dataptr7;tmp7 = dataptr0 - dataptr7;tmp1 = dataptr1 + dataptr6;tmp6 = dataptr1 - dataptr6;tmp2 = dataptr2 + dataptr5;tmp5 = dataptr2 - dataptr5;tmp3 = dataptr3 + dataptr4;tmp4 = dataptr3 - dataptr4;/* Even part */tmp10 = tmp0 + tmp3;/* phase 2 */tmp13 = tmp0 - tmp3;tmp11 = tmp1 + tmp2;tmp12 = tmp1 - tmp2;dataptr0 = tmp10 + tmp11; /* phase 3 */dataptr4 = tmp10 - tmp11;z1 = (tmp12 + tmp13) * (float) 0.707106781); /* c4 */dataptr2 = tmp13 + z1;/* phase 5 */dataptr6 = tmp13 - z1;/* Odd part */tmp10 = tmp4 + tmp5;/* phase 2 */tmp11 = tmp5 + tmp6;tmp12 = tmp6 + tmp7;/* The rotator is modified from fig 4-8 to avoid extra negations. */z5 = (tmp10 - tmp12) * (float) 0.382683433); /* c6 */z2 = (float) 0.541196100) * tmp10 + z5; /* c2-c6 */z4 = (float) 1.306562965) * tmp12 + z5; /* c2+c6 */z3 = tmp11 * (float) 0.707106781); /* c4 */z11 = tmp7 + z3;/* phase 5 */z13 = tmp7 - z3;dataptr5 = z13 + z2;/* phase 6 */dataptr3 = z13 - z2;dataptr1 = z11 + z4;dataptr7 = z11 - z4;dataptr += 8;/* advance pointer to next row */ /* Pass 2: process columns. */dataptr = datafloat;for (ctr = 7; ctr = 0; ctr-) tmp0 = dataptr0 + dataptr56;tmp7 = dataptr0 - dataptr56;tmp1 = dataptr8 + dataptr48;tmp6 = dataptr8 - dataptr48;tmp2 = dataptr16 + dataptr40;tmp5 = dataptr16 - dataptr40;tmp3 = dataptr24 + dataptr32;tmp4 = dataptr24 - dataptr32;/* Even part */tmp10 = tmp0 + tmp3;/* phase 2 */tmp13 = tmp0 - tmp3;tmp11 = tmp1 + tmp2;tmp12 = tmp1 - tmp2;dataptr0 = tmp10 + tmp11; /* phase 3 */dataptr32 = tmp10 - tmp11;z1 = (tmp12 + tmp13) * (float) 0.707106781); /* c4 */dataptr16 = tmp13 + z1; /* phase 5 */dataptr48 = tmp13 - z1;/* Odd part */tmp10 = tmp4 + tmp5;/* phase 2 */tmp11 = tmp5 + tmp6;tmp12 = tmp6 + tmp7;/* The rotator is modified from fig 4-8 to avoid extra negations. */z5 = (tmp10 - tmp12) * (float) 0.382683433); /* c6 */z2 = (float) 0.541196100) * tmp10 + z5; /* c2-c6 */z4 = (float) 1.306562965) * tmp12 + z5; /* c2+c6 */z3 = tmp11 * (float) 0.707106781); /* c4 */z11 = tmp7 + z3;/* phase 5 */z13 = tmp7 - z3;dataptr40 = z13 + z2; /* phase 6 */dataptr24 = z13 - z2;dataptr8 = z11 + z4;dataptr56 = z11 - z4;dataptr+;/* advance pointer to next column */* Quantize/descale the coefficients, and store into output array */for (i = 0; i 64; i+) /* Apply the quantization and scaling factor */temp = datafloati * fdtbli;/* Round to nearest integer. Since C does not specify the direction of rounding for negative quotients, we have to force the dividend positive for portability. The maximum coefficient size is +-16K (for 12-bit data), so this code should work for either 16-bit or 32-bit ints. */outdatai = (SWORD) (SWORD)(temp + 16384.5) - 16384);void process_DU(SBYTE *ComponentDU,float *fdtbl,SWORD *DC, bitstring *HTDC,bitstring *HTAC)bitstring EOB = HTAC0x00;bitstring M16zeroes = HTAC0xF0;BYTE i;BYTE startpos;BYTE end0pos;BYTE nrzeroes;BYTE nrmarker;SWORD Diff;fdct_and_quantization(ComponentDU, fdtbl, DU_DCT);/ zigzag reorderfor (i=0; i0)&(DUend0pos=0); end0pos-) ;/end0pos = first element in reverse order != 0i = 1;while (i = end0pos)startpos = i;for (; (DUi=0) & (i= 16) for (nrmarker=1; nrmarker=nrzeroes/16; nrmarker+) writebits(M16zeroes);nrzeroes = nrzeroes%16;writebits(HTACnrzeroes*16+categoryDUi);writebits(bitcodeDUi);i+;if (end0pos != 63) writebits(EOB);void load_data_units_from_RGB_buffer(WORD xpos, WORD ypos)BYTE x, y;BYTE pos = 0;DWORD location;BYTE R, G, B;location = ypos * width + xpos;for (y=0; y8; y+)for (x=0; x8; x+)R = RGB_bufferlocation.R;G = RGB_bufferlocation.G;B = RGB_bufferlocation.B;/ convert to YCbCrYDUpos = Y(R,G,B);CbDUpos = Cb(R,G,B);CrDUpos = Cr(R,G,B);location+;pos+;location += width - 8;void main_encoder()SWORD DCY = 0, DCCb = 0, DCCr = 0; /DC coefficients used for differential encodingWORD xpos, ypos;for (ypos=0; yposheight; ypos+=8)for (xpos=0; xposwidth; xpos+=8)load_data_units_from_RGB_buffer(xpos, ypos);process_DU(YDU, fdtbl_Y, &DCY, YDC_HT, YAC_HT);process_DU(CbDU, fdtbl_Cb, &DCCb, CbDC_HT, CbAC_HT);process_DU(CrDU, fdtbl_Cb, &DCCr, CbDC_HT, CbAC_HT);void load_bitmap(char *bitmap_name, WORD *width_original, WORD *height_original)WORD widthDiv8, heightDiv8; / closest multiple of 8 ceilBYTE nr_fillingbytes;/The number of the filling bytes in the BMP file / (the dimension in bytes of a BMP line on the disk is divisible by 4)colorRGB lastcolor;WORD column;BYTE TMPBUF256;WORD nrline_up, nrline_dn, nrline;WORD dimline;colorRGB *tmpline;FILE *fp_bitmap = fopen(bitmap_name,rb);if (fp_bitmap=NULL) exitmessage(Cannot open bitmap file.File not found ?);if (fread(TMPBUF, 1, 54, fp_bitmap) != 54)exitmessage(Need a truecolor BMP to encode.);if (TMPBUF0!=B)|(TMPBUF1!=M)|(TMPBUF28!=24)exitmessage(Need a truecolor BMP to encode.);width = (WORD)TMPBUF19*256+TMPBUF18;height = (WORD)TMPBUF23*256+TMPBUF22;/ Keep the old dimensions of the image*width_original = width;*height_original = height; if (width%8 != 0) widthDiv8 = (width/8)*8+8;else widthDiv8 = width;if (height%8 != 0) heightDiv8 = (height/8)*8+8;else heightDiv8 = height;/ The image we encode shall be filled with the last line and the last column/ from the original bitmap, until width and height are divisible by 8/ Load BMP image from disk and complete XRGB_buffer = (colorRGB *)(malloc(3*widthDiv8*heightDiv8);if (RGB_buffer = NULL) exitmessage(Not enough memory for the bitmap image.);if ( (width*3)%4 != 0) nr_fillingbytes = 4 - ( (width*3)%4);else nr_fillingbytes = 0;for (nrline=0; nrlineheight; nrline+)fread(RGB_buffer + nrline*widthDiv8, 1, width*3, fp_bitmap);fread(TMPBUF, 1, nr_fillingbytes, fp_bitmap);/ complete Xmemcpy(&lastcolor, RGB_buffer + nrline*widthDiv8 + width-1, 3);for (column=width; columnnrline_dn; nrline_up-,nrline_dn+)memcpy(tmpline, RGB_buffer+nrline_up*width, dimline);memcpy(RGB_buffer+nrline_up*width, RGB_buffer+nrline_dn*width, dimline);memcpy(RGB_buffer+nrline_dn*width, tmpline, dimline);/ Y completion:memcpy(tmpline, RGB_buffer+(height-1)*width, dimline);for (nrline=height; nrline1) strcpy(BMP_filename,argv1);if (argc2) strcpy(JPG_filename,argv2);else / replace .bmp with .jpgstrcpy(JPG_filename, BMP_filename);len_filename=strlen(BMP_filename);strcpy(JPG_filename+(len_filename-3),jpg);else exitmessage(Syntax: enc fis.bmp fis.jpg);load_bitmap(BMP_filename, &width_original, &height_original);fp_jpeg_stream = fopen(JPG_filename,wb);init_all();SOF0info.width = width_original;SOF0info.height = height_original;writeword(0xFFD8); / SOIwrite_APP0info();/ write_comment(Cris made this JPEG with his own encoder);write_DQTinfo();write_SOF0info();write_DHTinf

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论