分享

如何使用jpeglib库压缩yuv422?

 dwlinux 2014-04-05
如题:
我是yuv422 yuyv这样的格式,然后我将它转换成了平面格式,即先是Y,后是U,再是V,这样排列。使用的函数如下,该函数是在网上搜的,但是运行出现错误,不知是yuv的输入参数错误(不知他是怎么排的),还是本来这个函数就有问题,请大侠们帮忙看看:

int yuv422_to_jpeg(unsigned char *data, int image_width, int image_height, char *filename, int 

quality)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
//JSAMPROW row_pointer[1];  /* pointer to JSAMPLE row[s] */
//int row_stride;    /* physical row width in image buffer */
JSAMPIMAGE  buffer;
int band,i,buf_width[3],buf_height[3], mem_size, max_line, counter;
unsigned char *yuv[3];
/*uint8_t*/unsigned char *pSrc, *pDst;

FILE * outfile; /* target file */

yuv[0] = data;
yuv[1] = yuv[0] + (image_width * image_height);
yuv[2] = yuv[1] + (image_width * image_height) /2;

if ((outfile = fopen(filename, "wb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}

cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
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.do_fancy_downsampling=FALSE;

cinfo.jpeg_color_space = JCS_YCbCr;
cinfo.comp_info[0].h_samp_factor = 2;
cinfo.comp_info[0].v_samp_factor = 1;

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]);
}

max_line = cinfo.max_v_samp_factor*DCTSIZE;
for(counter=0; cinfo.next_scanline < cinfo.image_height; counter++)
{
//buffer image copy.
for(band=0; band <3; band++)
{
mem_size = buf_width[band];
pDst = (unsigned char *) buffer[band][0];
pSrc = (unsigned char *) yuv[band] + counter*buf_height[band] * 

buf_width[band];

for(i=0; i <buf_height[band]; i++)
{
memcpy(pDst, pSrc, mem_size); //拷贝一


pSrc += 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;
}

跟踪发现:
buf_width[0]=1632,而我的图像的分辨率是1628*1236

同时:
for(counter=0; cinfo.next_scanline < cinfo.image_height; counter++)
{
//buffer image copy.
for(band=0; band <3; band++)
{
mem_size = buf_width[band];
pDst = (unsigned char *) buffer[band][0];
pSrc = (unsigned char *) yuv[band] + counter*buf_height[band] * 

buf_width[band];

for(i=0; i <buf_height[band]; i++)
{
memcpy(pDst, pSrc, mem_size); //拷贝一


pSrc += buf_width[band];
pDst += buf_width[band];
}
}

jpeg_write_raw_data(&cinfo, buffer, max_line); //写一行
}

这个地方当
counter=154时,就发生内存错误了,因为后面还有一个循环,154*8=1232,这样在进行memcpy时,内存错误,

不知道大家是怎么讲Yuv422 转换到jpg的,谢谢!
回复次数:6
smilestone322
smilestone322
smilestone
等级:Blank
#1 得分:0 回复于: 2012-03-26 09:48:19
有人知道吗,呵呵!
gavinr
gavinr
gavinr
等级:Blank
#2 得分:80 回复于: 2012-03-26 10:47:07
找到了以前用过的一段程序,是可以正常工作的,你可以参考下
C/C++ code?
1
/**
\brief jpeg编码,输入格式为uyvy
*/
void write_YUV_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;

    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_YCbCr; /* 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 = 1;
    /////////////////////////

    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*3/2;

    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 = buf_width[band];
            unsigned char *pDst = (unsigned char *) buffer[band][0];
            unsigned char *pSrc = (unsigned char *) (rawData[band] + //yuv.data[band]分别表示YUV起始地址
                counter*buf_height[band] * buf_width[band]);

            for(i=0; i<buf_height[band]; i++)
            {
                memcpy(pDst, pSrc, mem_size);
                pSrc += 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);


}
smilestone322
smilestone322
smilestone
等级:Blank
#3 得分:0 回复于: 2012-03-27 13:24:40
引用 2 楼 gavinr 的回复:
找到了以前用过的一段程序,是可以正常工作的,你可以参考下
C/C++ code?
1
/**
\brief jpeg编码,输入格式为uyvy
*/
void write_YUV_JPEG_file (char * filename, unsigned char* yuvData, int quality,
  int image_width,int image_height)
……

你这段程序和我的一样啊,我运行有错误,你以前用这段代码时,yuvData是怎么输入的,格式是怎样的呢,谢谢
gavinr
gavinr
gavinr
等级:Blank
#4 得分:0 回复于: 2012-03-28 20:45:55
yuvData格式,开头的注释里写着啊,uyvy
smilestone322
smilestone322
smilestone
等级:Blank
#5 得分:0 回复于: 2012-04-03 15:03:28
自己使用intel的库解决了! ijl
happy08god
happy08god
happy08god
等级:Blank
#6 得分:0 回复于: 2013-09-03 11:14:17
cinfo.input_components = 3;    /* # of color components per pixel */
cinfo.in_color_space = JCS_RGB;  /* colorspace of input image */

========> 这个是对的?? 你还讲raw_in 设置为TRUE了。。
2楼的程序才是对的

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多