yuv格式的照片是纯yuv的数据,如果不告诉图片查看程序此数据流的长与宽,是无法显示图片的。
MJPG是由多帧jpg图片组成。jpg图片有文件头,里面就有必须的长,宽数据。jpg的图片数据是yuv压缩后的数据。所以jpg解码后的数据也是yuv,也必须转为RGB32显示器才能显示。
1. 查看文件头字节:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(void)
{
FILE *f=fopen("/home/wzpc/Pictures/my.jpg","rb");
if(f==NULL){
puts("file error");
exit(1);
}
fseek(f,0,SEEK_END);
int len=ftell(f);
fseek(f,0,SEEK_SET);
int ft=fileno(f);
char *fb=mmap(NULL,len,PROT_READ,MAP_SHARED,ft,0);
unsigned char (*c)[16]=(unsigned char (*)[16])fb;
for(int a=0;a<40;a++){
for(int b=0;b<16;b++){
printf("%x ",c[a][b]);
}
puts("");
}
return 0;
}
3.c摄像头 生成jpg图片
ff d8 ff db 0 43 0 5 3 3 4 3 3 5 4 3 ff d8:jpg 开始 ff db 0 43 0:量化表1开始 64字节 8*8
4 5 5 5 5 7 c 8 7 6 6 7 f a b 8
c 12 f 12 12 11 f 11 10 14 16 1c 18 14 15 1a
15 10 11 19 21 19 1a 1d 1e 1f 20 1f 13 17 23 25
23 1f 25 1c 1f 1f 1e ff db 0 43 1 5 5 5 7 ff db 0 43 1: 量化表2开始 64字节 8*8
6 7 e 8 8 e 1e 14 11 14 1e 1e 1e 1e 1e 1e
1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e
1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e
1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e ff c0 0 11 ff c0:量化表后面有一个“开始帧(SOF)”,由“FFC0”等标记表示。据说图像的大小是在SOF中定义的。
8 2 d0 5 0 3 1 21 0 2 11 1 3 11 1 ff ff c4:以标记“FFC4”开头的“霍夫曼表”是一步压缩数据的霍夫曼编码
c4 0 1f 0 0 1 5 1 1 1 1 1 1 0 0 0 ff c4 0 1f: 0x1f=31=29+2 所以数据长度为29个
0 0 0 0 0 1 2 3 4 5 6 7 8 9 a b
ff c4 0 b5 10 0 2 1 3 3 2 4 3 5 5 4 ff c4 0 b5: 0xb5=16*11+5=181=179+2 数据长度为179
0 0 1 7d 1 2 3 0 4 11 5 12 21 31 41
6 13 51 61 7 22 71 14 32 81 91 a1 8 23 42 b1
c1 15 52 d1 f0 24 33 62 72 82 9 a 16 17 18 19
1a 25 26 27 28 29 2a 34 35 36 37 38 39 3a 43 44
45 46 47 48 49 4a 53 54 55 56 57 58 59 5a 63 64
6 67 68 69 6a 73 74 75 76 77 78 79 7a 83 84
85 86 87 88 89 8a 92 93 94 95 96 97 98 99 9a a2
a3 a4 a5 a6 a7 a8 a9 aa b2 b3 b4 b5 b6 b7 b8 b9
ba c2 c3 c4 c5 c6 c7 c8 c9 ca d2 d3 d4 d5 d6 d7
d8 d9 da e1 e2 e3 e4 e5 e6 e7 e8 e9 ea f1 f2 f3
f4 f5 f6 f7 f8 f9 fa ff c4 0 1f 1 0 3 1 1 ff c4 0 1f:
1 1 1 1 1 0 0 0 0 0 0 1 2 3
4 5 6 7 8 9 a b ff c4 0 b5 11 0 2 1 ff c4 0 b5:
4 4 3 4 7 5 4 4 0 1 2 77 0 1 2
4. SOF (ff c0) 帧开始的定义
标记代码(2字节) 0xffc0
数据长度 2 sof 长度
精度 1 每个样本数据的位数 ,通常是8
图像高度 2 单位是像素点
图像宽度 2 单位是像素点
颜色分级 1 YCbCr 3
颜色分量信息 颜色分量数X3(一般为9字节) 每个颜色分量: 1字节分量id 1字节水平垂直采样因子 1字节分量使用的量化表id
ff c0 0 11 8 2 d0 5 0 3 1 21 0 2 11 1 3 11 1
sof数据`长度 0x11=17-2=15个字节
图像高度 [2][d0]=2*256+13*16=720
图像高度 [5][0]=5*256+0=1280
颜色分级 3: YCbCr
分量信息:
id 采样因子 使用的量化表id
Y : 1 21 0
Cb 2 11 1
Cr 3 11 1
5.
标记名字 标记识别符 说明
SOI 0xd8 jpg图像开始
APP0 0xe0 JFIF应用领域
0xe1-0xef 其他APP细分市场
0xdb 量化表
0xc0 帧开始
0xc4 霍夫曼表
0xda 扫描行开始
0xd9 jpg图片结束
到这里基本上就得到了jpg图片的基本数据,剩下的就是用代码把它解码还原成YCbCr。
文件头最重要必须的数据结构有3种类型:4张向量表,SOF 帧数据,多个霍夫曼编码数据。得到这三种类型数据后,就可把编码数据解码成YUV格式数据了。