Linux--使用libjpeg库解码jpg图片

使用libjpeg库解码jpg图片

libjpeg版本:v6b
运行环境:arm

/*
 *函数功能:解码jpg图片,存储解码出来的数据
 *函数参数:pPic记录源jpg图片,解码得到图片宽高、位深度、显示数据
 *返回值  :解码正确返回0,错误返回-1
 */
int jpg_analyze (struct pic_info *pPic)
{
    struct jpeg_decompress_struct cinfo; //解压参数
    struct my_error_mgr jerr;
    FILE * infile;              //指向打开图片的指针 
    char * buffer = NULL;       //指向解码行数据的指针
    int row_stride;             //解码出来的一行图片信息的字节数

    if ((infile = fopen(pPic->pathname, "rb")) == NULL) {
        fprintf(stderr, "can't open %s\n", pPic->pathname);
        return -1;
    }

    //第1步:申请和初始化JPEG解压目标
    cinfo.err = jpeg_std_error(&jerr.pub); //输出型参数
    jerr.pub.error_exit = my_error_exit;    
    if (setjmp(jerr.setjmp_buffer)) {
        jpeg_destroy_decompress(&cinfo);
        fclose(infile);
        return -1;
    }
    //给解码器作必要的内存分配和数据结构的初始化
    jpeg_create_decompress(&cinfo); 

    //第2步:将fopen打开的源jpg图片和解码器相关联
    jpeg_stdio_src(&cinfo, infile);

    //第3步:读取图片头信息
    (void) jpeg_read_header(&cinfo, TRUE);

    //第4步:开始解码
    (void) jpeg_start_decompress(&cinfo);
    row_stride = cinfo.output_width * cinfo.output_components; //一行的字节数
    buffer = (char *)malloc(row_stride);    //申请一行的空间
    if (NULL == buffer) {
        fprintf(stderr, "cinfo.mem->alloc_sarray error.\n");
        return -1;
    }

    //第5步:逐行解码,并将解码出的数据存到buffer中
    while (cinfo.output_scanline < cinfo.output_height) {
        jpeg_read_scanlines(&cinfo, &buffer, 1);
        //将buffer中的一行数据移到数据缓冲区中
        memcpy(pPic->pData + (cinfo.output_scanline-1)*row_stride, buffer, row_stride);
    }

    pPic->bpp = cinfo.output_components*8; 
    pPic->height = cinfo.image_height;
    pPic->width = cinfo.image_width;    

    //第6步:结束解码
    (void) jpeg_finish_decompress(&cinfo);

    //第7步:释放解码目标
    jpeg_destroy_decompress(&cinfo);
    fclose(infile);

    return 0;
}

typedef struct pic_info {
    char *pathname;       //图片在系统中的文件名加路径名
    unsigned int width;   //宽
    unsigned int height;  //高
    unsigned int bpp;     //位深度
    unsigned char *pData; //指向图片数据缓冲区
} pic_info;

note:执行读取函数jpeg_read_scanlines(),第一次读取出来的数据全是0000,所以存储数据的时候需要丢掉第一次读取的数据,操作就是pPic->pData + (cinfo.output_scanline-1)*row_stride,更改指针指向。

数据处理过程:



猜你喜欢

转载自blog.csdn.net/Meteor_s/article/details/82622152