用JpegLib压缩YUV

此处的YUV数据指I420I422应该做一下修改也能用,这个我没有测试。

Jpeg的宽度、和高度可以是任意的,原来在网上找的都只能是16的倍数才行。

下面的函数经过测试可用,有什么问题可以与我联系 lipku@pku.org.cn

 

函数实现如下:

参数说明:

Filenamejpg文件名字

yuvData:输入的yuv缓存地址

quality:压缩质量 1-100

image_width:图像宽度

image_height:图像高度

 

int write_JPEG_file (char * filename, unsigned char* yuvData, int quality,int image_width,int image_height)

{

     struct jpeg_compress_struct cinfo;

 

     struct jpeg_error_mgr jerr;

 

     FILE * outfile;    // target file 

     JSAMPROW row_pointer[1];  // pointer to JSAMPLE row[s] 

     int row_stride;    // physical row width in image buffer

     JSAMPIMAGE  buffer;

 

     unsigned char *pSrc,*pDst;

 

     int band,i,buf_width[3],buf_height[3];

     cinfo.err = jpeg_std_error(&jerr);

 

     jpeg_create_compress(&cinfo);

 

 

     if ((outfile = fopen(filename, "wb")) == NULL) {

         fprintf(stderr, "can't open %s/n", filename);

         exit(1);

     }

     jpeg_stdio_dest(&cinfo, outfile);

 

 

     cinfo.image_width = image_width;  // image width and height, in pixels

     cinfo.image_height = image_height;

     cinfo.input_components = 3;    // # of color components per pixel

     cinfo.in_color_space = JCS_RGB;  //colorspace of input image

 

     jpeg_set_defaults(&cinfo);

 

     jpeg_set_quality(&cinfo, quality, TRUE );

 

     //

     cinfo.raw_data_in = TRUE;

     cinfo.jpeg_color_space = JCS_YCbCr;

     cinfo.comp_info[0].h_samp_factor = 2;

     cinfo.comp_info[0].v_samp_factor = 2;

     /

 

     jpeg_start_compress(&cinfo, TRUE);

 

     buffer = (JSAMPIMAGE) (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo,

                                 JPOOL_IMAGE, 3 * sizeof(JSAMPARRAY)); 

     for(band=0; band <3; band++)

     {

         buf_width[band] = cinfo.comp_info[band].width_in_blocks * DCTSIZE;

         buf_height[band] = cinfo.comp_info[band].v_samp_factor * DCTSIZE;

         buffer[band] = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo,

                                 JPOOL_IMAGE, buf_width[band], buf_height[band]);

     } 

 

     unsigned char *rawData[3];

     rawData[0]=yuvData;

     rawData[1]=yuvData+image_width*image_height;

     rawData[2]=yuvData+image_width*image_height*5/4;

 

     int src_width[3],src_height[3];

     for(int i=0;i<3;i++)

     {

         src_width[i]=(i==0)?image_width:image_width/2;

         src_height[i]=(i==0)?image_height:image_height/2;

     }

 

     //max_line一般为16,外循环每次处理16行数据。

     int max_line = cinfo.max_v_samp_factor*DCTSIZE; 

     for(int counter=0; cinfo.next_scanline < cinfo.image_height; counter++)

     {   

         //buffer image copy.

         for(band=0; band <3; band++)  //每个分量分别处理

         {

              int mem_size = src_width[band];//buf_width[band];

              pDst = (unsigned char *) buffer[band][0];

              pSrc = (unsigned char *) rawData[band] + counter*buf_height[band] * src_width[band];//buf_width[band];  //yuv.data[band]分别表示YUV起始地址

 

              for(i=0; i <buf_height[band]; i++)  //处理每行数据

              {

                   memcpy(pDst, pSrc, mem_size);

                   pSrc += src_width[band];//buf_width[band];

                   pDst += buf_width[band];

              }

         }

         jpeg_write_raw_data(&cinfo, buffer, max_line);

     }

 

 

     jpeg_finish_compress(&cinfo);

 

     fclose(outfile);

 

     jpeg_destroy_compress(&cinfo);

 

     return 0;

}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值