目录
- 一、BMP图像
- 1. 文件整体结构
- 2. 位图头文件数据结构
- 3. 位图信息数据结构
- 4. 调色板
- 5. 位图数据
- 6. 要点
- 二、JPEG图像
- 1. 文件格式
- 2. 标记定义
- 三、YUV图像
- 1. 文件结构
- 2. 转换公式与要点
- 四、图像缩放
- 五、makefile编写
- 六、Linux多线程编程
- 1. 线程的概念
- 2. POSIX线程
- 3. 几个最基本的库函数
- 4. 编译要点
- 七、信号量
- 八、进程间通信
- 1. 命名管道:FIFO
- 命名管道的创建
- 命名管道的访问
- 1. 命名管道:FIFO
一、BMP图像
1. 文件整体结构
典型的BMP图像文件由四部分组成:
- 位图头文件数据结构:包含BMP图像文件的类型、显示内容等信息;
- 位图信息数据结构:包含BMP图像的宽、高、压缩方法,以及定义颜色等信息;
- 调色板:可选部分,有些位图需要调色板,有些位图(如真彩色图24位的BMP)不需要调色板;
- 位图数据:根据BMP位图使用的位数不同而不同,24位图中直接使用RGB,其他小于24位的使用调色板中颜色索引值。
2. 位图头文件数据结构
共14字节,含有BMP文件的类型、文件大小和位图起始位置等信息,结构体声明如下:
typedefstructtagBITMAPFILEHEADER{ushort u16bfType;// 位图文件的类型,必须为BM(1-2字节)uint u32bfSize;// 位图文件的大小,以字节为单位(3-6字节,低位在前)ushort u16bfReserved1;// 位图文件保留字,必须为0(7-8字节)ushort u16bfReserved2;// 位图文件保留字,必须为0(9-10字节)uint u32bfOffBits;// 位图数据的起始位置,以相对于位图(11-14字节,低位在前)}__attribute__((packed))BITMAPFILEHEADER;3. 位图信息数据结构
共40字节,用于说明位图的尺寸等信息,结构体声明如下:
typedefstructtagBITMAPINFOHEADER{uint u32biSize;// 本结构所占用字节数(15-18字节)uint u32biWidth;// 位图的宽度,以像素为单位(19-22字节)uint u32biHeight;// 位图的高度,以像素为单位(23-26字节)ushort u16biPlanes;// 目标设备的级别,必须为1(27-28字节)ushort u16biBitCount;// 每个像素所需的位数,必须是1(双色)、4(16色)、8(256色)、16(高彩色)或24(真彩色)之一(29-30字节)uint u32biCompression;// 位图压缩类型,必须是0(不压缩)、1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一(31-34字节)uint u32biSizeImage;// 位图的大小,以字节为单位,其中包含了为了补齐行数是4的倍数而添加的空字节(35-38字节)uint u32biXPelsPerMeter;// 位图水平分辨率,每米像素数(39-42字节)uint u32biYPelsPerMeter;// 位图垂直分辨率,每米像素数(43-46字节)uint u32biClrUsed;// 位图实际使用的颜色表中的颜色数(47-50字节)uint u32biClrImportant;// 位图显示过程中重要的颜色数(51-54字节)}__attribute__((packed))BITMAPINFOHEADER;4. 调色板
用于说明位图中的颜色,有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:
typedefstructtagRGBQUAD{uchar u8rgbBlue;// 蓝色的亮度(值范围为0-255)uchar u8rgbGreen;// 绿色的亮度(值范围为0-255)uchar u8rgbRed;// 红色的亮度(值范围为0-255)uchar u8rgbReserved;// 保留,必须为0}__attribute__((packed))RGBQUAD;颜色表中RGBQUAD结构数据的个数由biBitCount来确定:
- 当
biBitCount=1时,有2个表项 - 当
biBitCount=4时,有16个表项 - 当
biBitCount=8时,有256个表项 - 当
biBitCount=24时,没有颜色表项
位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:
typedefstructtagBITMAPINFO{BITMAPINFOHEADER bmiHeader;// 位图信息头RGBQUAD bmiColors[1];// 颜色表}__attribute__((packed))BITMAPINFO;5. 位图数据
位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数:
- 当
biBitCount=1时,8个像素占1个字节 - 当
biBitCount=4时,2个像素占1个字节 - 当
biBitCount=8时,1个像素占1个字节 - 当
biBitCount=24时,1个像素占3个字节,按顺序分别为B、G、R
结构体声明如下:
typedefstruct{uchar u8b;uchar u8g;uchar u8r;}RGB;6. 要点
由于编译器存在着字节自动对齐的问题,声明结构体的时候需要添加__attribute__((packed))让编译器取消自动对齐,才会获得正确的大小。
使用__attribute__((packed)):
typedefstructtagBITMAPFILEHEADER{ushort u16bfType;// 位图文件的类型,必须为BM(1-2字节)uint u32bfSize;// 位图文件的大小,以字节为单位(3-6字节,低位在前)ushort u16bfReserved1;// 位图文件保留字,必须为0(7-8字节)ushort u16bfReserved2;// 位图文件保留字,必须为0(9-10字节)uint u32bfOffBits;// 位图数据的起始位置,以相对于位图(11-14字节,低位在前)}__attribute__((packed))BITMAPFILEHEADER;// sizeof(BITMAPFILEHEADER) = 14不使用__attribute__((packed)):
typedefstructtagBITMAPFILEHEADER{ushort u16bfType;// 位图文件的类型,必须为BM(1-2字节)uint u32bfSize;// 位图文件的大小,以字节为单位(3-6字节,低位在前)ushort u16bfReserved1;// 位图文件保留字,必须为0(7-8字节)ushort u16bfReserved2;// 位图文件保留字,必须为0(9-10字节)uint u32bfOffBits;// 位图数据的起始位置,以相对于位图(11-14字节,低位在前)}BITMAPFILEHEADER;// sizeof(BITMAPFILEHEADER) = 16二、JPEG图像
1. 文件格式
JPEG文件由下面的8个部分组成:
(1) 图像开始 SOI (Start of Image) 标记
- 标记代码:2字节,固定值
0xFFD8
(2) APP0 标记 (Marker)
- 标记代码:2字节,固定值
0xFFE0 - 字段说明:
- APP0长度 (length):2字节,①~⑨9个字段的总长度
- 标识符 (identifier):5字节,固定值
0x4A46494600,即字符串"JFIF0" - 版本号 (version):2字节,一般是
0x0102,表示JFIF的版本号1.2 - X和Y的密度单位 (units):1字节,0:无单位;1:点数/英寸;2:点数/厘米
- X方向像素密度 (X density):2字节
- Y方向像素密度 (Y density):2字节
- 缩略图水平像素数目 (thumbnail horizontal pixels):1字节
- 缩略图垂直像素数目 (thumbnail vertical pixels):1字节
- 缩略图RGB位图 (thumbnail RGB bitmap)
标记段⑨可以包含图像的一个微缩版本,存为24位的RGB像素。如果没有微缩图像(这种情况更常见),则字段⑦和字段⑧的值均为0。
(3) APPn 标记 (Markers),其中 n=1~15 (任选)
- 标记代码:2字节,固定值
0xFFE1~0xFFEF - 字段说明:
- APPn长度 (length):2字节,①~②2个字段的总长度
- 详细信息 (application specific information):(数据长度-2)字节,内容不定
例如,Adobe Photoshop生成的JPEG图像中就用了APP1和APP13两个标记段分别存储了一幅图像的副本;Exif将数码照片的拍摄参数、缩略图及其他属性信息记录在APP1中。值得注意的是,同一APPn标记可以同时出现多个,例如用Ps处理过的数码相机拍摄的照片,可能会存在2个APP1标记。
(4) 一个或者多个量化表 DQT (Define Quantization Table)
- 标记代码:2字节,固定值
0xFFDB,最多只能出现4次 - 字段说明:
- 量化表长度 (quantization table length):2字节,①~③三个字段的总长度
- 量化表号 (quantization table number):1字节
- 量化表 (quantization table)
另一种说法为:
- 精度及量化表ID:1字节,高4位:精度,0:8位;1:16位,低4位:量化表ID,取值范围为0~3
- 表项:64×(精度+1)字节,例如8位精度的量化表,其表项长度为
64×(0+1)=64字节
查不到更多资料,无法分辨哪一种是正确的。
(5) 帧图像开始 SOF0 (Start of Frame)
- 标记代码:2字节,固定值
0xFFC0 - 字段说明:
- 帧开始长度 (start of frame length):2字节,①~⑥六个字段的总长度
- 精度 (precision):1字节,每个颜色分量每个像素的位数,通常是8位
- 图像高度 (image height):2字节,图像高度(单位:像素),如果不支持DNL就必须>0
- 图像宽度 (image width):2字节,图像宽度(单位:像素),如果不支持DNL就必须>0
- 颜色分量数 (number of color components):1字节,1:灰度图;3:YCrCb或YIQ;4:CMYK。JFIF中使用YCrCb,故这里颜色分量数恒为3
- 对每个颜色分量 (for each component):颜色分量数×3字节(通常为9字节)
- ID:1字节
- 水平/垂直采样因子:1字节,高4位:水平采样因子,低4位:垂直采样因子
- 量化表号 (quantization table#):1字节
字段⑥应该重复出现,有多少个颜色分量(字段⑤),就出现多少次(一般为3次)。
(6) 一个或者多个霍夫曼表 DHT (Define Huffman Table)
- 标记代码:2字节,固定值
0xFFC4 - 字段说明:
- 霍夫曼表的长度 (Huffman table length)
- 类型、AC或者DC (Type, AC or DC)
- 索引 (Index)
- 位表 (bits table)
- 值表 (value table)
DC表和AC表分开编码。另一种说法为:表ID和表类型占1字节,高4位:类型,0:DC直流;1:AC交流;低4位:哈夫曼表ID。
由于查不到更多资料,无法得出详细含义。
(7) 扫描开始 SOS (Start of Scan)
- 标记代码:2字节,固定值
0xFFDA - 字段说明:
- 扫描开始长度 (start of scan length):2字节,①~④两个字段的总长度
- 颜色分量数 (number of color components):1字节,应该和SOF中的字段⑤的值相同,1:灰度图;3:YCrCb或YIQ;4:CMYK
- 每个颜色分量:
- ID:1字节
- 直流/交流系数表号:1字节,高4位:直流分量使用的哈夫曼树编号,低4位:交流分量使用的哈夫曼树编号
- 压缩图像数据 (compressed image data):
- 谱选择开始:1字节,固定值
0x00 - 谱选择结束:1字节,固定值
0x3F - 谱选择:1字节,在基本JPEG中总为00
字段③应该重复出现,有多少个颜色分量(字段②),就出现多少次(一般为3次)。
本段结束后,紧接着就是真正的图像信息了。图像信息直至遇到一个标记代码就自动结束,一般就是以EOI标记表示结束。
(8) 图像结束 EOI (End of Image)
- 标记代码:2字节,固定值
0xFFD9
其他可能出现的标记段
DRI (Define Restart Interval):定义差分编码累计复位的间隔
- 标记代码:2字节,固定值
0xFFDD - 包含2个具体字段:
- 数据长度:2字节,固定值
0x0004,①~②两个字段的总长度 - MCU块的单元中的重新开始间隔:2字节,设其值为n,则表示每n个MCU块就有一个RSTn标记。第一个标记是RST0,第二个是RST1等,RST7后再从RST0重复
- 数据长度:2字节,固定值
如果没有本标记段,或间隔值为0时,就表示不存在重开始间隔和标记RST。
2. 标记定义
如果在图像数据流中遇到0xFF,应该检测其紧接着的字符:
0x00:表示0xFF是图像流的组成部分,需要进行译码0xD0~0xD7:组成RSTn标记,则忽视整个RSTn标记,即不对当前0xFF和紧接的0xDn两个字节进行译码,并按RST标记的规则调整译码变量0xFF:忽视当前0xFF,对后一个0xFF再作判断- 其他数值:忽视当前0xFF,并保留紧接的此数值用于译码
| 符号 | 标记代码 | 说明 | 英文解释原文 |
|---|---|---|---|
| 起始帧标记,非分层霍夫曼编码 | Start Of Frame markers, non-hierarchical Huffman coding | ||
| SOF0 | 0xFFC0 | 基线DCT | Baseline DCT |
| SOF1 | 0xFFC1 | 扩展顺序DCT | Extended sequential DCT |
| SOF2 | 0xFFC2 | 逐行DCT | Progressive DCT |
| SOF3 | 0xFFC3 | 空间(顺序)无损 | Spatial (sequential) lossless |
| 起始帧标记,分层霍夫曼编码 | Start Of Frame markers, hierarchical Huffman coding | ||
| SOF5 | 0xFFC5 | 差分顺序DCT | Differential sequential DCT |
| SOF6 | 0xFFC6 | 差分渐进DCT | Differential progressive DCT |
| SOF7 | 0xFFC7 | 差分空间无损 | Differential spatial lossless |
| 起始帧标记,非分层算术编码 |