BMP图片转JPEG图片C程序源代码.docx
《BMP图片转JPEG图片C程序源代码.docx》由会员分享,可在线阅读,更多相关《BMP图片转JPEG图片C程序源代码.docx(34页珍藏版)》请在冰豆网上搜索。
![BMP图片转JPEG图片C程序源代码.docx](https://file1.bdocx.com/fileroot1/2023-2/28/c6b5b5ec-bbae-42fc-9b73-a430d015b1a5/c6b5b5ec-bbae-42fc-9b73-a430d015b1a51.gif)
BMP图片转JPEG图片C程序源代码
//ABMPtruecolortoJPEGencoder
//Copyright1999CristianCuturicu
#include
#include
#include
#include"jtypes.h"
#include"jglobals.h"
#include"jtables.h"
voidwrite_APP0info()
//NothingtooverwriteforAPP0info
{
writeword(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);
}
voidwrite_SOF0info()
//Weshouldoverwritewidthandheight
{
writeword(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);
}
voidwrite_DQTinfo()
{
BYTEi;
writeword(DQTinfo.marker);
writeword(DQTinfo.length);
writebyte(DQTinfo.QTYinfo);
for(i=0;i<64;i++)
writebyte(DQTinfo.Ytable[i]);
writebyte(DQTinfo.QTCbinfo);
for(i=0;i<64;i++)
writebyte(DQTinfo.Cbtable[i]);
}
voidset_quant_table(BYTE*basic_table,BYTEscale_factor,BYTE*newtable)
//Setquantizationtableandzigzagreorderit
{
BYTEi;
longtemp;
for(i=0;i<64;i++)
{
temp=((long)basic_table[i]*scale_factor+50L)/100L;
//limitthevaluestothevalidrange
if(temp<=0L)
temp=1L;
if(temp>255L)
temp=255L;
newtable[zigzag[i]]=(BYTE)temp;
}
}
voidset_DQTinfo()
{
BYTEscalefactor=50;//scalefactorcontrolsthevisualqualityoftheimage
//thesmalleristhebetterimagewe'llget,andthesmaller
//compressionwe'llachieve
DQTinfo.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);
}
voidwrite_DHTinfo()
{
BYTEi;
writeword(DHTinfo.marker);
writeword(DHTinfo.length);
writebyte(DHTinfo.HTYDCinfo);
for(i=0;i<16;i++)
writebyte(DHTinfo.YDC_nrcodes[i]);
for(i=0;i<12;i++)
writebyte(DHTinfo.YDC_values[i]);
writebyte(DHTinfo.HTYACinfo);
for(i=0;i<16;i++)
writebyte(DHTinfo.YAC_nrcodes[i]);
for(i=0;i<162;i++)
writebyte(DHTinfo.YAC_values[i]);
writebyte(DHTinfo.HTCbDCinfo);
for(i=0;i<16;i++)
writebyte(DHTinfo.CbDC_nrcodes[i]);
for(i=0;i<12;i++)
writebyte(DHTinfo.CbDC_values[i]);
writebyte(DHTinfo.HTCbACinfo);
for(i=0;i<16;i++)
writebyte(DHTinfo.CbAC_nrcodes[i]);
for(i=0;i<162;i++)
writebyte(DHTinfo.CbAC_values[i]);
}
voidset_DHTinfo()
{
BYTEi;
//filltheDHTinfostructure[getthevaluesfromthestandardHuffmantables]
DHTinfo.marker=0xFFC4;
DHTinfo.length=0x01A2;
DHTinfo.HTYDCinfo=0;
for(i=0;i<16;i++)
DHTinfo.YDC_nrcodes[i]=std_dc_luminance_nrcodes[i+1];
for(i=0;i<12;i++)
DHTinfo.YDC_values[i]=std_dc_luminance_values[i];
DHTinfo.HTYACinfo=0x10;
for(i=0;i<16;i++)
DHTinfo.YAC_nrcodes[i]=std_ac_luminance_nrcodes[i+1];
for(i=0;i<162;i++)
DHTinfo.YAC_values[i]=std_ac_luminance_values[i];
DHTinfo.HTCbDCinfo=1;
for(i=0;i<16;i++)
DHTinfo.CbDC_nrcodes[i]=std_dc_chrominance_nrcodes[i+1];
for(i=0;i<12;i++)
DHTinfo.CbDC_values[i]=std_dc_chrominance_values[i];
DHTinfo.HTCbACinfo=0x11;
for(i=0;i<16;i++)
DHTinfo.CbAC_nrcodes[i]=std_ac_chrominance_nrcodes[i+1];
for(i=0;i<162;i++)
DHTinfo.CbAC_values[i]=std_ac_chrominance_values[i];
}
voidwrite_SOSinfo()
//NothingtooverwriteforSOSinfo
{
writeword(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);
}
voidwrite_comment(BYTE*comment)
{
WORDi,length;
writeword(0xFFFE);//TheCOMmarker
length=strlen((constchar*)comment);
writeword(length+2);
for(i=0;iwritebyte(comment[i]);
}
voidwritebits(bitstringbs)
//Aportableversion;itshouldbedoneinassembler
{
WORDvalue;
SBYTEposval;//bitpositioninthebitstringweread,shouldbe<=15and>=0
value=bs.value;
posval=bs.length-1;
while(posval>=0)
{
if(value&mask[posval])
bytenew|=mask[bytepos];
posval--;
bytepos--;
if(bytepos<0)
{
//writeit
if(bytenew==0xFF)
{
//specialcase
writebyte(0xFF);
writebyte(0);
}
else
writebyte(bytenew);
//reinit
bytepos=7;
bytenew=0;
}
}
}
voidcompute_Huffman_table(BYTE*nrcodes,BYTE*std_table,bitstring*HT)
{
BYTEk,j;
BYTEpos_in_table;
WORDcodevalue;
codevalue=0;
pos_in_table=0;
for(k=1;k<=16;k++)
{
for(j=1;j<=nrcodes[k];j++)
{
HT[std_table[pos_in_table]].value=codevalue;
HT[std_table[pos_in_table]].length=k;
pos_in_table++;
codevalue++;
}
codevalue<<=1;
}
}
voidinit_Huffman_tables()
{
//ComputetheHuffmantablesusedforencoding
compute_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);
}
voidexitmessage(char*error_message)
{
printf("%s\n",error_message);
exit(EXIT_FAILURE);
}
voidset_numbers_category_and_bitcode()
{
SDWORDnr;
SDWORDnrlower,nrupper;
BYTEcat;
category_alloc=(BYTE*)malloc(65535*sizeof(BYTE));
if(category_alloc==NULL)
exitmessage("Notenoughmemory.");
//allownegativesubscripts
category=category_alloc+32767;
bitcode_alloc=(bitstring*)malloc(65535*sizeof(bitstring));
if(bitcode_alloc==NULL)
exitmessage("Notenoughmemory.");
bitcode=bitcode_alloc+32767;
nrlower=1;
nrupper=2;
for(cat=1;cat<=15;cat++)
{
//Positivenumbers
for(nr=nrlower;nr{
category[nr]=cat;
bitcode[nr].length=cat;
bitcode[nr].value=(WORD)nr;
}
//Negativenumbers
for(nr=-(nrupper-1);nr<=-nrlower;nr++)
{
category[nr]=cat;
bitcode[nr].length=cat;
bitcode[nr].value=(WORD)(nrupper-1+nr);
}
nrlower<<=1;
nrupper<<=1;
}
}
voidprecalculate_YCbCr_tables()
{
WORDR,G,B;
for(R=0;R<256;R++)
{
YRtab[R]=(SDWORD)(65536*0.299+0.5)*R;
CbRtab[R]=(SDWORD)(65536*-0.16874+0.5)*R;
CrRtab[R]=(SDWORD)(32768)*R;
}
for(G=0;G<256;G++)
{
YGtab[G]=(SDWORD)(65536*0.587+0.5)*G;
CbGtab[G]=(SDWORD)(65536*-0.33126+0.5)*G;
CrGtab[G]=(SDWORD)(65536*-0.41869+0.5)*G;
}
for(B=0;B<256;B++)
{
YBtab[B]=(SDWORD)(65536*0.114+0.5)*B;
CbBtab[B]=(SDWORD)(32768)*B;
CrBtab[B]=(SDWORD)(65536*-0.08131+0.5)*B;
}
}
//UsingabitmodifiedformoftheFDCTroutinefromIJG'sCsource:
//ForwardDCTroutineideatakenfromIndependentJPEGGroup'sCsourcefor
//JPEGencoders/decoders
/*ForfloatAA&NIDCTmethod,divisorsareequaltoquantization
coefficientsscaledbyscalefactor[row]*scalefactor[col],where
scalefactor[0]=1
scalefactor[k]=cos(k*PI/16)*sqrt
(2)fork=1..7
Weapplyafurtherscalefactorof8.
What'sactuallystoredis1/divisorsothattheinnerloopcan
useamultiplicationratherthanadivision.*/
voidprepare_quant_tables()
{
doubleaanscalefactor[8]={1.0,1.387039845,1.306562965,1.175875602,
1.0,0.785694958,0.541196100,0.275899379};
BYTErow,col;
BYTEi=0;
for(row=0;row<8;row++)
{
for(col=0;col<8;col++)
{
fdtbl_Y[i]=(float)(1.0/((double)DQTinfo.Ytable[zigzag[i]]*
aanscalefactor[row]*aanscalefactor[col]*8.0));
fdtbl_Cb[i]=(float)(1.0/((double)DQTinfo.Cbtable[zigzag[i]]*
aanscalefactor[row]*aanscalefactor[col]*8.0));
i++;
}
}
}
voidfdct_and_quantization(SBYTE*data,float*fdtbl,SWORD*outdata)
{
floattmp0,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp7;
floattmp10,tmp11,tmp12,tmp13;
floatz1,z2,z3,z4,z5,z11,z13;
float*dataptr;
floatdatafloat[64];
floattemp;
SBYTEctr;
BYTEi;
for(i=0;i<64;i++)
datafloat[i]=data[i];
/*Pass1:
processrows.*/
dataptr=datafloat;
for(ctr=7;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];
/*Evenpart*/
tmp10=tmp0+tmp3;/*phase2*/
tmp13=tmp0-tmp3;
tmp11=tmp1+tmp2;
tmp12=tmp1-tmp2;
dataptr[0]=tmp10+tmp11;/*phase3*/
dataptr[4]=tmp10-tmp11;
z1=(tmp12+tmp13)*((float)0.707106781);/*c4*/
dataptr[2]=tmp13+z1;/*phase5*/
dataptr[6]=tmp13-z1;
/*Oddpart*/
tmp10=tmp4+tmp5;/*phase2*/
tmp11=tmp5+tmp6;
tmp12=tmp6+tmp7;
/*Therotatorismodifiedfromfig4-8toavoidextranegations.*/
z5=(tmp10-tmp12)*((float)0.382683433);/*c6*/
z2=((float)0.541196100)*tmp10+z5;/*c2-c6*/
z4=((float)1.306562965)*tmp12+z5;/*c2+c6*/
z3=