Chinaunix首页 | 论坛 | 博客
  • 博客访问: 35511
  • 博文数量: 6
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2016-02-16 14:07
文章分类
文章存档

2016年(6)

我的朋友

分类: 嵌入式

2016-04-07 16:34:38

原文地址:libjpeg的解压过程 作者:fzhman

1、分配并初始化一个JPEG解压对象(本文中将JPEG解压对象命名为cinfo):

    struct jpeg_decompress_struct cinfo;

    struct jpeg_error_mgr jerr;

    ...

    cinfo.err = jpeg_std_error(&jerr);

    jpeg_create_decompress(&cinfo);

2、指定要解压缩的图像文件:

    FILE * infile;

    ...

    if ((infile = fopen(filename, "rb")) == NULL) {

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

        exit(1);

    }

    jpeg_stdio_src(&cinfo, infile);

3、调用jpeg_read_header()获取图像信息:

    jpeg_read_header(&cinfo, TRUE);

4、这是一个可选步骤,用于设置JPEG解压缩对象cinfo的一些参数,本文可忽略;

5、调用jpeg_start_decompress()开始解压过程:

    jpeg_start_decompress(&cinfo);

调用jpeg_start_decompress()函数之后,JPEG解压缩对象cinfo中的下面这几个字段将会比较有用:

l output_width                这是图像输出的宽度

l output_height                这是图像输出的高度

l output_components              每个像素的分量数,也即字节数

这是因为在调用jpeg_start_decompress()之后往往需要为解压后的扫描线上的所有像素点分配存储空间,这个空间的大小可以通过output_width * output_componets确定,而要读取的扫描线的总数为output_height行。

6、读取一行或者多行扫描线数据并处理,通常的代码是这样的:

       while (cinfo.output_scanline < cinfo.ouput_height) {

              jpeg_read_scanlines();

              /* deal with scanlines */

       }

对扫描线的读取是按照从上到下的顺序进行的,也就是说图像最上方的扫描线最先被jpeg_read_scanlines()读入存储空间中,紧接着是第二个扫描线,最后是图像底边的扫描线被读入存储空间中。

7、调用jpeg_finish_decompress()完成解压过程:

    jpeg_finish_decompress(&cinfo);

8、调用jpeg_destroy_decompress()释放JPEG解压对象cinfo:

    jpeg_destroy_decompress(&cinfo);

以上就是通过libjpeg函数解压JPEG压缩图像的基本过程,由于本文不涉及libjpeg的高级特性和用法,因此,上面的介绍对于说明本文中要用到的libjpeg的功能已经足够了。

另外一个需要说明地方是:由于作者所用的Framebuffer设备的颜色深度为16位,颜色格式为5-6-5格式——即R(红色)在16bit中占据高5位,G(绿色)在16bit中占据中间6位,B(蓝色)在16bit中占据低5位;而libjpeg解压出来的图像数据为24位RGB格式,因此必须进行转换。对于24位的RGB,每个字节表示一个颜色分量,因此转换的方式为:对于R字节,右移3位,对于G字节,右移2位,对于B字节,右移3位,然后将右移得到的值拼接起来,就得到了16位的颜色值。在后面的程序中,将把24位的颜色称为RGB888,而把16位颜色值称为RGB565,这种命名方式可能不太规范,不过无论如何,在本文中就这样称呼了。
阅读(1702) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~