www.pudn.com > jpeg1.zip > AENCODE.C
/*************************************************************/ /* FILENAME : ENCODE.C */ /* FUNCTION : This program is for encoding image file */ /* INPUT FORMAT: DECODE*/ /* <0/1> [Q] */ /* PARAMETERS : */ /* OUTPUT : */ /* COMPILING & | TCC CODE.C (PC Computer: Turbo C 2.0) */ /* AUTHOR : Ai Wei */ /* ADDRESS : Room 248, Dormitory 1 */ /* Tsing Hua University */ /* Beijing 100084, P.R.China */ /* DATE/TIME : 2-17-1993/5:00pm */ /*************************************************************/ #include #include "stdlib.h" #include #include "math.h" #include "errno.h" #include "alloc.h" #include #include #include "jpeg.h" #define PI 3.14159265359 unsigned char ac_ehuffsi[256],dc_ehuffsi[16],dc_huffsize[13],ac_huffsize[165]; unsigned char buffer[2048]; unsigned int ac_ehuffco[256],dc_ehuffco[16],dc_huffcode[13],ac_huffcode[165]; double dct_coe[8][8]; int si_data[8][8]; int result[8][8],bit_last_left=8,code_stream_length=0; long dc_pre,diff,zz[64]; unsigned char far *code_stream; /******************************************************/ /* */ /* Function: Procedure for loading DCT coefficients */ /* */ /* Format: load_dct_coe() */ /* */ /* Parametre: None. */ /* */ /* Return value: None. */ /* */ /******************************************************/ load_dct_coe() { int i,j; for(i=0;i<8;i++) dct_coe[i][0]=0.5/sqrt((double)2.0); for(j=1;j<8;j++) for(i=0;i<8;i++) dct_coe[i][j]=0.5*cos((2.0*(double)i+1.0)*(double)j*PI/16.0); } /******************************************************/ /* */ /* Function: Procedure for calculating FDCT */ /* */ /* Format: dct_tran() */ /* */ /* Parametre: None. */ /* */ /* Return Value: None. */ /* */ /******************************************************/ dct_tran() { double re1[8][8],re2[8][8]; int i,j,k; for(i=0;i<8;i++) for(j=0;j<8;j++) { re1[i][j]=0.0; re2[i][j]=0.0; for(k=0;k<8;k++) re1[i][j]=re1[i][j]+dct_coe[k][j]*(double)(si_data[i][k]); } for(i=0;i<8;i++) for(j=0;j<8;j++) for(k=0;k<8;k++) re2[i][j]=re2[i][j]+dct_coe[k][i]*re1[k][j]; for(i=0;i<8;i++) for(j=0;j<8;j++) result[i][j]=re2[i][j]; } /*********************************************************/ /* */ /* Function: Procedure for getting the real */ /* quantization table. */ /* */ /* Format: get_a_table(int q_value, */ /* unsigned char *table) */ /* */ /* Parametre: q_value---parametre Q for quantization. */ /* table-----pointer of quantization table. */ /* */ /* Return Value: None. */ /* */ /*********************************************************/ void get_q_table(q,table) int q; unsigned char table[8][8]; { unsigned i,j,tmp; for(i=0;i<8;i++) for(j=0;j<8;j++) { tmp=table[i][j]*q; table[i][j]=tmp/50.0+0.5; } } /***************************************************/ /* */ /* Function: Procedure for Quantize the DCT */ /* coefficients */ /* */ /* Format: quant(unsigned char *table) */ /* */ /* Parametre: table---pointer of quantization */ /* table. */ /* */ /* Return value: None. */ /* */ /***************************************************/ quant(table) unsigned char table[8][8]; { int i,j; for(i=0;i<8;i++) for(j=0;j<8;j++) { if(result[i][j]>=0) result[i][j] = result[i][j]/(float)(table[i][j])+0.5; else result[i][j] = result[i][j]/(float)(table[i][j])-0.5; } } /***********************************************************/ /* */ /* Function: Procedure for zigzag scan of the */ /* coefficients */ /* */ /* Format: zigzag() */ /* */ /* Parametre: None. */ /* */ /* Return value: None. */ /* */ /***********************************************************/ zigzag() { int i,j; for(i=0;i<8;i++) for(j=0;j<8;j++) /* ** reorder the coefficients in zigzag sequence */ zz[zz_index[i*8+j]]=result[i][j]; /* reorder the coefficients in zigzag sequence */ } /*****************************************************************/ /* */ /* Function: Procedure for generation of the Huffman */ /* Codes & SIzes. */ /* */ /* Format: loadhuf(unsigned char *DC_bit, */ /* unsigned char *DC_huffval, */ /* unsigned char *AC_bit, */ /* unsigned char *AC_huffval) */ /* */ /* Parametre: DC_bit---------pointer of table used to */ /* generate huffman code size */ /* for DC coefficents. */ /* DC_huffval-----pointer of table used to */ /* generate huffman code */ /* for DC coefficients. */ /* DC_bit---------pointer of table used to */ /* generate huffman code size */ /* for AC coefficents. */ /* DC_huffval-----pointer of table used to */ /* generate huffman code */ /* for AC coefficients. */ /* */ /* Return value: None. */ /* */ /*****************************************************************/ loadhuf(d_bit,d_huffval,a_bit,a_huffval) unsigned char d_bit[16],a_bit[16]; unsigned char d_huffval[12],a_huffval[162]; { unsigned code; int i,j,p,dc_lastp,ac_lastp,si; /* ** Generation of table of Huffman code sizes */ i=0; j=1; p=0; while(i<16) { if(j>d_bit[i]) { i++; j=1; } else { /* ** Generate DC Huffman code sizes */ dc_huffsize[p]=i+1; p++; j++; } } dc_huffsize[p]=0; dc_lastp=p; i=0; j=1; p=0; while(i<16) { if(j>a_bit[i]) { i++; j=1; } else { /* ** Generate AC Huffman code sizes */ ac_huffsize[p]=i+1; p++; j++; } } ac_huffsize[p]=0; ac_lastp=p; /* ** Generation of table of Huffman codes */ p=0; code=0; si=dc_huffsize[0]; y1: do { /* ** Generation of DC Huffman code */ dc_huffcode[p]=code; code++; p++; } while(dc_huffsize[p]==si); if(dc_huffsize[p]!=0) { do { code=code<<1; si++; } while(dc_huffsize[p]!=si); goto y1; } p=0; code=0; si=ac_huffsize[0]; y2: do { /* ** Generation of AC Huffman code */ ac_huffcode[p]=code; code++; p++; } while(ac_huffsize[p]==si); if(ac_huffsize[p]!=0) { do { code=code<<1; si++; } while(ac_huffsize[p]!=si); goto y2; } /* ** Reorder the values in HUFFCODE and HUFFSIZE according ** to the values in HUFFVAL. */ p=0; do { i=d_huffval[p]; /* ** dc code & size reorder */ dc_ehuffco[i]=dc_huffcode[p]; dc_ehuffsi[i]=dc_huffsize[p]; p++; } while(p =0) tmp[j]=tmp1>>k; else tmp[j]=tmp1<<(-k); if((code_stream[code_stream_length]|=tmp[j])==0xff) { code_stream_length++; code_stream[code_stream_length]=0; } if(k>=0) code_stream_length++; code_si-=8; } if(k==0) bit_last_left=8; else /* ** encode category */ bit_last_left= -k; if(i==0) return; if(i<0) { i--; tmp1=0xffff; tmp1>>=16-ssss; tmp1&=i; } else tmp1=i; num_of_byte=(ssss-bit_last_left+15)/8; for(j=0;j =0) tmp[j]=tmp1>>k; else tmp[j]=tmp1<<(-k); if((code_stream[code_stream_length]|=tmp[j])==0xff) { code_stream_length++; code_stream[code_stream_length]=0; } if(k>=0) code_stream_length++; ssss-=8; } if(k==0) bit_last_left=8; else bit_last_left= -k; } /****************************************************************/ /* */ /* Function: Send code of AC coefficient to the code stream */ /* */ /* Format: ac_send(int number,long ac_data) */ /* */ /* Parameter: number-----length of 0 sequence */ /* ac_data----AC data to be encoded into code */ /* stream. */ /* */ /* Return value: None. */ /* */ /****************************************************************/ void ac_send(r,z) int r; long z; { int j,k,ssss,rs,code_si,num_of_byte; unsigned int tmp1; unsigned char tmp[3]; ssss=log_of_int(z); rs=(r<<4)+ssss; code_si=ac_ehuffsi[rs]; tmp1=ac_ehuffco[rs]; num_of_byte=(code_si-bit_last_left+15)/8; for(j=0;j =0) tmp[j]=tmp1>>k; else tmp[j]=tmp1<<(-k); if((code_stream[code_stream_length]|=tmp[j])==0xff) { code_stream_length++; code_stream[code_stream_length]=0; } if(k>=0) code_stream_length++; code_si-=8; } if(k==0) bit_last_left=8; else /* ** encode Run/Size */ bit_last_left= -k; if(z<0) { z--; tmp1=0xffff; tmp1>>=16-ssss; tmp1&=z; } else tmp1=z; num_of_byte=(ssss-bit_last_left+15)/8; for(j=0;j =0) tmp[j]=tmp1>>k; else tmp[j]=tmp1<<(-k); if((code_stream[code_stream_length]|=tmp[j])==0xff) { code_stream_length++; code_stream[code_stream_length]=0; } if(k>=0) code_stream_length++; ssss-=8; } if(k==0) bit_last_left=8; else bit_last_left= -k; } /****************************************************************/ /* */ /* Function: Send code of AC coefficient(0 or F0) to the */ /* code stream */ /* */ /* Format: ac_send0f0(int ac_data) */ /* */ /* Parameter: ac_data-----AC data (0 or F0) to encoded into */ /* code stream. */ /* */ /* Return value: None. */ /* */ /****************************************************************/ void ac_send0f0(rs) int rs; { int j,k,code_si,num_of_byte; unsigned int tmp1; unsigned char tmp[3]; code_si=ac_ehuffsi[rs]; tmp1=ac_ehuffco[rs]; num_of_byte=(code_si-bit_last_left+15)/8; for(j=0;j =0) tmp[j]=tmp1>>k; else tmp[j]=tmp1<<(-k); if((code_stream[code_stream_length]|=tmp[j])==0xff) { code_stream_length++; code_stream[code_stream_length]=0; } if(k>=0) code_stream_length++; code_si-=8; } if(k==0) bit_last_left=8; else /* ** encode Run/Size */ bit_last_left= -k; } /*************************************************/ /* */ /* Function: Huffman encoding */ /* */ /* Format: encode() */ /* */ /* Parametre: None */ /* */ /* Return value: None */ /* */ /*************************************************/ void encode() { int k=0,r=0; diff=zz[0]-dc_pre; dc_pre=zz[0]; dc_send(diff); t1: k++; if(zz[k]==0) { if(k==63) { /* ** Code EHUFSI(0) bits of EHUFCO(0) */ ac_send0f0(0); goto e1; } else { r++; goto t1; } } else { while(r>15) { /* ** Code EHUFSI(240) bits of EHUFCO(240) */ ac_send0f0(240); r-=16; } /* ** Encode_R,zz[k] */ ac_send(r,zz[k]); r=0; if(k!=63) goto t1; } e1: ; } /**************************************************/ /* */ /* PROGRAM MAIN */ /* */ /**************************************************/ main(int argc,char **argv) { FILE *fp_so,*fp_tar; struct timeb start_time, end_time ; int second_d ; unsigned char byte_last,pad,n=0; long i,j,k,l; int q,block_count=0; int color; unsigned int img_width,img_height,tmp; union { unsigned int restart; unsigned char rh_rl[2]; } interval; ftime( &start_time ) ; if(argc<6) { printf(" Error of Insufficient Parameter!!\n"); printf(" \n Usage: encode imgfile jpgfile color imgwidth imgheight [q]\n"); exit(0); } if((code_stream=(unsigned char far *)farcalloc(64000l,1))==NULL) { printf("No Enough Memory!\n") ; exit(0) ; } if((fp_so=fopen(argv[1],"rb"))==NULL) { printf(" Image file open error ! \n"); exit(0); } if((fp_tar=fopen(argv[2],"wb"))==NULL) { printf( "Target file open error ! \n"); exit(0); } /* ** set default Q value for encode */ q=20; if(argc==7) q=atoi(argv[6]); /* ** get parametres from command line */ color=atoi(argv[3]); img_height=atoi(argv[5]); img_width=atoi(argv[4]); tmp=((img_width>>3)<<3); fwrite(&img_width, sizeof(int),1,fp_tar); tmp=((img_height>>3)<<3); fwrite(&img_height,sizeof(int),1,fp_tar); interval.restart=img_width>>3; if(color==0) { get_q_table(q,qu_table); loadhuf(dc_bits,dc_huffval,ac_bits,ac_huffval); } else { get_q_table(q,co_qu_table); loadhuf(co_dc_bits,co_dc_huffval,co_ac_bits,co_ac_huffval); } load_dct_coe(); code_stream[code_stream_length++]=0xff; /* ** Add Start Of Image mark */ code_stream[code_stream_length++]=0xd8; code_stream[code_stream_length++]=0xff; /* ** Define Quantization tables */ code_stream[code_stream_length++]=0xdb; code_stream[code_stream_length++]=0x00; /* ** Length of Quantization tables is 67 */ code_stream[code_stream_length++]=0x43; /* ** Y-Quantization table */ code_stream[code_stream_length++]=0x00; if(color==0) { for(i=0;i<64;i++) code_stream[code_stream_length++]=qu_table[i/8][i%8]; } else { for(i=0;i<64;i++) code_stream[code_stream_length++]=co_qu_table[i/8][i%8]; } code_stream[code_stream_length++]=0xff; /* ** Define Huffman tables */ code_stream[code_stream_length++]=0xc4; code_stream[code_stream_length++]=0x00; /* ** Huffman tables length=0xd2=210=2+1+16+12+1+16+162 */ code_stream[code_stream_length++]=0xd2; /* ** Y-DC table */ code_stream[code_stream_length++]=0x00; if(color==0) { for(i=0;i<16;i++) /* ** Y-DC BITS */ code_stream[code_stream_length++]=dc_bits[i]; for(i=0;i<12;i++) /* ** DC-Huffman values */ code_stream[code_stream_length++]=dc_huffval[i]; } else { for(i=0;i<16;i++) /* ** Y-DC BITS */ code_stream[code_stream_length++]=co_dc_bits[i]; for(i=0;i<12;i++) /* ** DC-Huffman values */ code_stream[code_stream_length++]=co_dc_huffval[i]; } /* ** Y-AC table */ code_stream[code_stream_length++]=0x10; if(color==0) { for(i=0;i<16;i++) code_stream[code_stream_length++]=ac_bits[i]; for(i=0;i<162;i++) code_stream[code_stream_length++]=ac_huffval[i]; } else { for(i=0;i<16;i++) code_stream[code_stream_length++]=co_ac_bits[i]; for(i=0;i<162;i++) code_stream[code_stream_length++]=co_ac_huffval[i]; } /* ** Define Restart Interval */ code_stream[code_stream_length++]=0xff; code_stream[code_stream_length++]=0xdd; code_stream[code_stream_length++]=0x00; code_stream[code_stream_length++]=0x04; code_stream[code_stream_length++]=interval.rh_rl[1]; code_stream[code_stream_length++]=interval.rh_rl[0]; /* ** Define Restart Interval */ for(i=0;i<(img_height>>3);i++) { /* **read 8 lines from the source imgfile */ for(j=0;j<8;j++) { fread(buffer+j*((img_width>>3)<<3),1,((img_width>>3)<<3),fp_so); fseek(fp_so,img_width-((img_width>>3)<<3),SEEK_CUR); } for(j=0;j<(img_width>>3);j++) { /* ** read one 8x8 block to si_data[][] */ for(k=0;k<8;k++) for(l=0;l<8;l++) si_data[k][l]=(int)(buffer[k*((img_width>>3)<<3)+j*8+l])-128; /* ** DCT transform */ dct_tran(); /* ** Quantization */ if(color==0) { quant(qu_table); } else { quant(co_qu_table); } /* ** chage to zigzag sequence */ zigzag(); encode(); block_count++; if((block_count%interval.restart)==0) { if(bit_last_left!=8) { pad=0xff; pad>>=(8-bit_last_left); code_stream[code_stream_length++]|=pad; bit_last_left=8; if(code_stream[code_stream_length-1]==0xff) { code_stream[code_stream_length]=0; code_stream_length++; } /* ** byte padding */ } code_stream[code_stream_length++]=0xff; code_stream[code_stream_length++]=((n++)&7)+0xd0; dc_pre=0; /* ** Init before a new interval */ } } } code_stream[code_stream_length++]=0xff; /* ** End Of Image */ code_stream[code_stream_length++]=0xd9; fwrite(code_stream,1,code_stream_length,fp_tar); fclose(fp_so); fclose(fp_tar); ftime( &end_time ) ; second_d = end_time.millitm - start_time.millitm ; second_d = second_d + (end_time.time-start_time.time) * 1000 ; printf( " The encoding costs: %.3f second.\n", (float)second_d/1000.0 ) ; }