.读取量化表,全局参数,霍夫曼表,恢复表编码,现在只是实现思路。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <string.h>
#include <unistd.h>
#include <linux/fb.h>
#include <stdlib.h>static unsigned char h0[100];int main(void) {FILE *f = fopen("/home/wjs/Pictures/1.jpg", "rb");if (f == NULL) {puts("file_in error");exit(-1);}fseek(f, 0, SEEK_END);int len = ftell(f);fseek(f, 0, SEEK_SET);int fd = fileno(f);unsigned char *p = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);puts("-----------量化表---------------------");for (int t = 0; t < len; t++) {if ((*(p + t) == 0xff) && (*(p + t + 1) == 0xdb)) {// printf("ffdb:%d\n", t);}}puts("-----------帧全局---------------------");for (int t = 0; t < len; t++) {if ((*(p + t) == 0xff) && (*(p + t + 1) == 0xc0)) {// printf("ffc0:%d\n", t);}}puts("------------霍夫曼表--------------------");for (int t = 0; t < len; t++) {if ((*(p + t) == 0xff) && (*(p + t + 1) == 0xc4)) {// printf("ffc4:%d\n",t); //ff c4 (固定)0 1f(长度-2)0(表id)int cd = (*(p + t + 2)) * 256 + *(p + t + 3) - 3;unsigned char *hp = malloc(cd * (sizeof(char)));for (int n = 0; n < cd; n++) {*(hp + n) = *(p + t + 5 + n);// printf("%d ",*(hp+n));}if (*(p + t + 4) == 0) { //表1unsigned char hfm0[cd];// memcpy(&h0, hp, cd);}if (*(p + t + 4) == 16) { //2unsigned char hfm1[cd];// memcpy(&h0,hp,cd);}if (*(p + t + 4) == 1) { //3unsigned char hfm2[cd];// memcpy(&h0,hp,cd);}if (*(p + t + 4) == 17) { //4unsigned char hfm3[cd];memcpy(&h0,hp,cd);}printf("\n");free(hp);}}puts("------------差分数据--------------------");for (int t = 0; t < len; t++) {if ((*(p + t) == 0xff) && (*(p + t + 1) == 0xdd)) {// printf("ffdd:%d\n", t);}}puts("------------扫描数据--------------------");for (int t = 0; t < len; t++) {if ((*(p + t) == 0xff) && (*(p + t + 1) == 0xda)) {// printf("ffda:%d\n", t);}}
//----------------------------------------------------------------------//h0[26]// 0 1 2 3 4 5 6 7 8 9 10 15//0 1 5 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 4 5 6 7 3 2 8 9int bm[100];int t = 0; //输出数组递增数int n = 1; //内存递增数if (h0[n] == 1) {bm[t] = 0;} else if (h0[n] == 2) {bm[t] = 0; //生成2 位 0,1t = t + 1;bm[t] = 1;}for(int q=0;q<15;q++){n = n + 1;if (h0[n] != 0) { //3 2,3,4,5,6t = t + 1;bm[t] = 2 * (bm[t - 1] + 1);for (int z = 0; z < (h0[n] - 1); z++) {t = t + 1;bm[t] = bm[t - 1] + 1;}}}
/* n = n + 1;if (h0[n] != 0) { //4 (6+1)*2=14t = t + 1;bm[t] = 2 * (bm[t - 1] + 1);for (int z = 0; z < (h0[n] - 1); z++) {t = t + 1;bm[t] = bm[t - 1] + 1;}}n = n + 1;if (h0[n] != 0) { //5 (14+1)*2=30t = t + 1;bm[t] = 2 * (bm[t - 1] + 1);for (int z = 0; z < (h0[n] - 1); z++) {t = t + 1;bm[t] = bm[t - 1] + 1;}}n = n + 1;if (h0[n] != 0) { //6 (30+1)*2=62t = t + 1;bm[t] = 2 * (bm[t - 1] + 1);for (int z = 0; z < (h0[n] - 1); z++) {t = t + 1;bm[t] = bm[t - 1] + 1;}}n = n + 1;if (h0[n] != 0) { //7位 (62+1)*2=126t = t + 1;bm[t] = 2 * (bm[t - 1] + 1);for (int z = 0; z < (h0[n] - 1); z++) {t = t + 1;bm[t] = bm[t - 1] + 1;}}n = n + 1;if (h0[n] != 0) { //8t = t + 1;bm[t] = 2 * (bm[t - 1] + 1);for (int z = 0; z < (h0[n] - 1); z++) {t = t + 1;bm[t] = bm[t - 1] + 1;}}n = n + 1;if (h0[n] != 0) { //9t = t + 1;bm[t] = 2 * (bm[t - 1] + 1);for (int z = 0; z < (h0[n] - 1); z++) {t = t + 1;bm[t] = bm[t - 1] + 1;}}n = n + 1;if (h0[n] != 0) { //10t = t + 1;bm[t] = 2 * (bm[t - 1] + 1);for (int z = 0; z < (h0[n] - 1); z++) {t = t + 1;bm[t] = bm[t - 1] + 1;}}n = n + 1;if (h0[n] != 0) { //11t = t + 1;bm[t] = 2 * (bm[t - 1] + 1);for (int z = 0; z < (h0[n] - 1); z++) {t = t + 1;bm[t] = bm[t - 1] + 1;}}n = n + 1;if (h0[n] != 0) { //12t = t + 1;bm[t] = 2 * (bm[t - 1] + 1);for (int z = 0; z < (h0[n] - 1); z++) {t = t + 1;bm[t] = bm[t - 1] + 1;}}n = n + 1;if (h0[n] != 0) { //13t = t + 1;bm[t] = 2 * (bm[t - 1] + 1);for (int z = 0; z < (h0[n] - 1); z++) {t = t + 1;bm[t] = bm[t - 1] + 1;}}n = n + 1;if (h0[n] != 0) { //14t = t + 1;bm[t] = 2 * (bm[t - 1] + 1);for (int z = 0; z < (h0[n] - 1); z++) {t = t + 1;bm[t] = bm[t - 1] + 1;}}n = n + 1;if (h0[n] != 0) { //15t = t + 1;bm[t] = 2 * (bm[t - 1] + 1);for (int z = 0; z < (h0[n] - 1); z++) {t = t + 1;bm[t] = bm[t - 1] + 1;}}*/ for (int t = 0; t < 100; t++) {printf("%d ", bm[t]);}return 0;
}
Jpeg 用的是范式霍夫曼,可以00 开始推算出码表。
7现在又有一问题,ffda的扫描流中含有Y 和UV两种的交流与直流4个部分,怎样才能区分开这4部分。
搞清楚了码流结构才能试着用上面的码表解码。
一个正常的JPEG码流以SOI(FFD8)标记开始,以EOI(FFD9)标记结束,中间是一帧的图像信息,包括各种数据(如 huffman表FFC4部分,量化表FFC0部分,以及APP和COM等部分)和SCAN部分(FFDA部分)等。JPEG图像包含一个或者多个SCAN(progressive模式包含多个SCAN),一个SCAN下面有一个或者多个RST(Restart Interval),一个RST里有一个或者多个MCU,一个MCU里有一个或者多个Block。
细读rfc2435 jpeg定义标准
主要找SOS段的详细资料信息