⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enc.c

📁 非常不错的jpeg压缩/解压代码,可以实现常用的JPEG压缩/解
💻 C
📖 第 1 页 / 共 2 页
字号:
    tmp11 = tmp1 + tmp2;
    tmp12 = tmp1 - tmp2;

    dataptr[0] = tmp10 + tmp11; /* phase 3 */
    dataptr[4] = tmp10 - tmp11;

    z1 = (tmp12 + tmp13) * ((float) 0.707106781); /* c4 */
	dataptr[2] = tmp13 + z1;	/* phase 5 */
    dataptr[6] = 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;

    dataptr[5] = z13 + z2;	/* phase 6 */
    dataptr[3] = z13 - z2;
	dataptr[1] = z11 + z4;
    dataptr[7] = z11 - z4;

    dataptr += 8;		/* advance pointer to next row */
  }

  /* Pass 2: process columns. */

  dataptr = datafloat;
  for (ctr = 7; ctr >= 0; ctr--) {
    tmp0 = dataptr[0] + dataptr[56];
    tmp7 = dataptr[0] - dataptr[56];
    tmp1 = dataptr[8] + dataptr[48];
    tmp6 = dataptr[8] - dataptr[48];
    tmp2 = dataptr[16] + dataptr[40];
    tmp5 = dataptr[16] - dataptr[40];
    tmp3 = dataptr[24] + dataptr[32];
    tmp4 = dataptr[24] - dataptr[32];

    /* Even part */

    tmp10 = tmp0 + tmp3;	/* phase 2 */
    tmp13 = tmp0 - tmp3;
    tmp11 = tmp1 + tmp2;
    tmp12 = tmp1 - tmp2;

    dataptr[0] = tmp10 + tmp11; /* phase 3 */
    dataptr[32] = tmp10 - tmp11;

	z1 = (tmp12 + tmp13) * ((float) 0.707106781); /* c4 */
    dataptr[16] = tmp13 + z1; /* phase 5 */
    dataptr[48] = 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;

    dataptr[40] = z13 + z2; /* phase 6 */
	dataptr[24] = z13 - z2;
    dataptr[8] = z11 + z4;
    dataptr[56] = 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 = datafloat[i] * fdtbl[i];
/* 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.
*/
	   outdata[i] = (SWORD) ((SWORD)(temp + 16384.5) - 16384);
			  }
}

void process_DU(SBYTE *ComponentDU,float *fdtbl,SWORD *DC,
		bitstring *HTDC,bitstring *HTAC)
{
 bitstring EOB=HTAC[0x00];
 bitstring M16zeroes=HTAC[0xF0];
 BYTE i;
 BYTE startpos;
 BYTE end0pos;
 BYTE nrzeroes;
 BYTE nrmarker;
 SWORD Diff;

 fdct_and_quantization(ComponentDU,fdtbl,DU_DCT);
 //zigzag reorder
 for (i=0;i<=63;i++) DU[zigzag[i]]=DU_DCT[i];
 Diff=DU[0]-*DC;
 *DC=DU[0];
 //Encode DC
 if (Diff==0) writebits(HTDC[0]); //Diff might be 0
  else {writebits(HTDC[category[Diff]]);
	writebits(bitcode[Diff]);
       }
 //Encode ACs
 for (end0pos=63;(end0pos>0)&&(DU[end0pos]==0);end0pos--) ;
 //end0pos = first element in reverse order !=0
 if (end0pos==0) {writebits(EOB);return;}

 i=1;
 while (i<=end0pos)
  {
   startpos=i;
   for (; (DU[i]==0)&&(i<=end0pos);i++) ;
   nrzeroes=i-startpos;
   if (nrzeroes>=16) {
      for (nrmarker=1;nrmarker<=nrzeroes/16;nrmarker++) writebits(M16zeroes);
      nrzeroes=nrzeroes%16;
		     }
   writebits(HTAC[nrzeroes*16+category[DU[i]]]);writebits(bitcode[DU[i]]);
   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*Ximage+xpos;
 for (y=0;y<8;y++)
 {
  for (x=0;x<8;x++)
   {
    R=RGB_buffer[location].R;G=RGB_buffer[location].G;B=RGB_buffer[location].B;
    YDU[pos]=Y(R,G,B);
    CbDU[pos]=Cb(R,G,B);
    CrDU[pos]=Cr(R,G,B);
    location++;pos++;
   }
  location+=Ximage-8;
 }
}

void main_encoder()
{
 SWORD DCY=0,DCCb=0,DCCr=0; //DC coefficients used for differential encoding
 WORD xpos,ypos;
 for (ypos=0;ypos<Yimage;ypos+=8)
  for (xpos=0;xpos<Ximage;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 *Ximage_original, WORD *Yimage_original)
{
 WORD Xdiv8,Ydiv8;
 BYTE 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 TMPBUF[256];
 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 ((TMPBUF[0]!='B')||(TMPBUF[1]!='M')||(TMPBUF[28]!=24))
	 exitmessage("Need a truecolor BMP to encode.");
 Ximage=(WORD)TMPBUF[19]*256+TMPBUF[18];Yimage=(WORD)TMPBUF[23]*256+TMPBUF[22];
 *Ximage_original=Ximage;*Yimage_original=Yimage; //Keep the old dimensions
						// of the image
 if (Ximage%8!=0) Xdiv8=(Ximage/8)*8+8;
	else Xdiv8=Ximage;
 if (Yimage%8!=0) Ydiv8=(Yimage/8)*8+8;
	else Ydiv8=Yimage;
 // The image we encode shall be filled with the last line and the last column
 // from the original bitmap, until Ximage and Yimage are divisible by 8
 // Load BMP image from disk and complete X
 RGB_buffer=(colorRGB *)(malloc(3*Xdiv8*Ydiv8));
 if (RGB_buffer==NULL) exitmessage("Not enough memory for the bitmap image.");
 if (Ximage%4!=0) nr_fillingbytes=4-(Ximage%4);
  else nr_fillingbytes=0;
 for (nrline=0;nrline<Yimage;nrline++)
  {
   fread(RGB_buffer+nrline*Xdiv8,1,Ximage*3,fp_bitmap);
   fread(TMPBUF,1,nr_fillingbytes,fp_bitmap);
   memcpy(&lastcolor,RGB_buffer+nrline*Xdiv8+Ximage-1,3);
   for (column=Ximage;column<Xdiv8;column++)
	{memcpy(RGB_buffer+nrline*Xdiv8+column,&lastcolor,3);}
  }
 Ximage=Xdiv8;
 dimline=Ximage*3;tmpline=(colorRGB *)malloc(dimline);
 if (tmpline==NULL) exitmessage("Not enough memory.");
 //Reorder in memory the inversed bitmap
 for (nrline_up=Yimage-1,nrline_dn=0;nrline_up>nrline_dn;nrline_up--,nrline_dn++)
  {
   memcpy(tmpline,RGB_buffer+nrline_up*Ximage, dimline);
   memcpy(RGB_buffer+nrline_up*Ximage,RGB_buffer+nrline_dn*Ximage,dimline);
   memcpy(RGB_buffer+nrline_dn*Ximage,tmpline,dimline);
  }
 // Y completion:
 memcpy(tmpline,RGB_buffer+(Yimage-1)*Ximage,dimline);
 for (nrline=Yimage;nrline<Ydiv8;nrline++)
  {memcpy(RGB_buffer+nrline*Ximage,tmpline,dimline);}
 Yimage=Ydiv8;
 free(tmpline);fclose(fp_bitmap);
}

void init_all()
{
 set_DQTinfo();
 set_DHTinfo();
 init_Huffman_tables();
 set_numbers_category_and_bitcode();
 precalculate_YCbCr_tables();
 prepare_quant_tables();
}

void main(int argc,char *argv[])
{
 char BMP_filename[64];
 char JPG_filename[64];
 WORD Ximage_original,Yimage_original; //the original image dimensions,
	   // before we made them divisible by 8
 BYTE len_filename;
 bitstring fillbits; //filling bitstring for the bit alignment of the EOI marker
 if (argc>1) { strcpy(BMP_filename,argv[1]);
		   if (argc>2) strcpy(JPG_filename,argv[2]);
		else { strcpy(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, &Ximage_original, &Yimage_original);
 fp_jpeg_stream=fopen(JPG_filename,"wb");
 init_all();
 SOF0info.width=Ximage_original;
 SOF0info.height=Yimage_original;
 writeword(0xFFD8); //SOI
 write_APP0info();
 // write_comment("Cris made this JPEG with his own encoder");
 write_DQTinfo();
 write_SOF0info();
 write_DHTinfo();
 write_SOSinfo();

 bytenew=0;bytepos=7;
 main_encoder();
 //Do the bit alignment of the EOI marker
 if (bytepos>=0) {
		   fillbits.length=bytepos+1;
		   fillbits.value=(1<<(bytepos+1))-1;
		   writebits(fillbits);
		 }
 writeword(0xFFD9); //EOI
 free(RGB_buffer); free(category_alloc);free(bitcode_alloc);
 fclose(fp_jpeg_stream);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -