JPG文件格式解码图片高度和宽度的分析

13. 简单说一下 JPG 文件的解码
-------------------------
解码程序先从 JPG 文件中读出采样系数, 这样就知道了 MCU 的大小, 算出整个图象
有几个 MCU. 解码程序再循环逐个对 MCU 解码, 一直到检查到 EOI 标记. 对于每个
MCU, 按正规的次序解出每个 DU, 然后组合, 转换成 (R,G,B) 就 OK 了

附:JPEG 文件格式
~~~~~~~~~~~~~~~~

  - 文件头 (2 bytes):  $ff, $d8 (SOI) (JPEG 文件标识)
  - 任意数量的段 , 见后面
  - 文件结束 (2 bytes): $ff, $d9 (EOI)

段的格式:
~~~~~~~~~

  - header (4 bytes):
       $ff     段标识
        n      段的类型 (1 byte)
       sh, sl  该段长度, 包括这两个字节, 但是不包括前面的 $ff 和 n.
               注意: 长度不是 intel 次序, 而是 Motorola 的, 高字节在前,
      低字节在后!
  - 该段的内容, 最多 65533 字节

 注意:
  - 有一些无参数的段 (下面那些前面注明星号的)
    这些段没有长度描述 (而且没有内容), 只有 $ff 和类型字节.
  - 段之间无论有多少 $ff 都是合法的, 必须被忽略掉.

段的类型:
~~~~~~~~~

   *TEM   = $01   可以忽略掉

    SOF0  = $c0   帧开始 (baseline JPEG), 细节附后
    SOF1  = $c1   dito
    SOF2  = $c2   通常不支持
    SOF3  = $c3   通常不支持

    SOF5  = $c5   通常不支持
    SOF6  = $c6   通常不支持
    SOF7  = $c7   通常不支持

    SOF9  = $c9   arithmetic 编码(Huffman 的一种扩展算法), 通常不支持
    SOF10 = $ca   通常不支持
    SOF11 = $cb   通常不支持

    SOF13 = $cd   通常不支持
    SOF14 = $ce   通常不支持
    SOF14 = $ce   通常不支持
    SOF15 = $cf   通常不支持

    DHT   = $c4   定义 Huffman Table,  细节附后
    JPG   = $c8   未定义/保留 (引起解码错误)
    DAC   = $cc   定义 Arithmetic Table, 通常不支持

   *RST0  = $d0   RSTn 用于 resync, 通常被忽略
   *RST1  = $d1
   *RST2  = $d2
   *RST3  = $d3
   *RST4  = $d4
   *RST5  = $d5
   *RST6  = $d6
   *RST7  = $d7

    SOI   = $d8   图片开始
    EOI   = $d9   图片结束
    SOS   = $da   扫描行开始, 细节附后
    DQT   = $db   定义 Quantization Table, 细节附后
    DNL   = $dc   通常不支持, 忽略
    DRI   = $dd   定义重新开始间隔, 细节附后
    DHP   = $de   忽略 (跳过)
    EXP   = $df   忽略 (跳过)

    APP0  = $e0   JFIF APP0 segment marker (细节略)
    APP15 = $ef   忽略

    JPG0  = $f0   忽略 (跳过)
    JPG13 = $fd   忽略 (跳过)
    COM   = $fe   注释, 细节附后

 其它的段类型都保留必须跳过

SOF0: Start Of Frame 0:
~~~~~~~~~~~~~~~~~~~~~~~

  - $ff, $c0 (SOF0)
  - 长度 (高字节, 低字节), 8+components*3     这里占两个字节
  - 数据精度 (1 byte) 每个样本位数, 通常是 8 (大多数 软件 不支持 12 和 16)    这里占一个字节
  - 图片高度 (高字节, 低字节), 如果不支持 DNL 就必须 >0      这里占两个字节
  - 图片宽度 (高字节, 低字节), 如果不支持 DNL 就必须 >0      这里占两个字节
  也就是说,在FFC0后3个字节开始 , 两个字节为图片高度 ,再两个字节为图片宽度
  - components 数量(1 byte), 灰度图是 1, YCbCr/YIQ 彩色图是 3, CMYK 彩色图
    是 4
  - 每个 component: 3 bytes
     - component id (1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q)
     - 采样系数 (bit 0-3 vert., 4-7 hor.)
     - quantization table 号
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用C语言的标准库函数和第三方库来读取和处理JPG文件。其中,libjpeg是一个常用的JPG图像处理库,可以用来读取和解码JPG文件。以下是一个简单的示例代码,用于读取JPG文件并显示图像像素数据: ``` #include <stdio.h> #include <stdlib.h> #include <jpeglib.h> int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage: %s <input.jpg>\n", argv[0]); return 1; } char *filename = argv[1]; FILE *infile = fopen(filename, "rb"); if (!infile) { printf("Error: failed to open file %s\n", filename); return 1; } struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo, infile); jpeg_read_header(&cinfo, TRUE); jpeg_start_decompress(&cinfo); int width = cinfo.output_width; int height = cinfo.output_height; int num_components = cinfo.output_components; int row_stride = width * num_components; unsigned char *buffer = (unsigned char *) malloc(row_stride * height); while (cinfo.output_scanline < cinfo.output_height) { unsigned char *row_pointer = buffer + cinfo.output_scanline * row_stride; jpeg_read_scanlines(&cinfo, &row_pointer, 1); } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); fclose(infile); // Display the image pixel data // ... free(buffer); return 0; } ``` 在上面的代码中,我们首先打开指定的JPG文件,然后使用libjpeg库来读取和解码JPG文件。读取完成后,我们可以获取图像的宽度高度、通道数等信息,并将像素数据存储在一个缓冲区中。最后,我们可以使用其他库或自己编写的代码来显示图像像素数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值