c 试水解码jpeg图片比特流

1c07421828194f0abd0b837d28bd185c.jpeg找到一张采用霍夫曼通用DC,AC编码表的图片,提取出此图片的比特流准备对它解码,再反推怎样编码。

下图是此图片比特流前100个字节。解码是每次读一字节,对这8比特解码,如8比特不能解码,再读入一字节。因为霍夫曼表最多是16比特位编码,意思是说超过16位比特还没有被解码就是错误的。当然不一定都是8比特,有时候是2比特等,这就涉及到比特的移位等操作。但操作单位是1字节8比特。

75a09a2e3d96400a96bb9e896184c227.jpeg

图1

上传此图片文件

下面是霍夫曼4张通用表;

cd389c8f03844d67a41b950187f2301c.jpeg

此图片帧全局(0xffc0)

ff ,c0 ,0 ,11 ,8 ,1 ,67 ,1 ,da ,3 ,1 ,22 ,0 ,2 ,11 ,1 ,3 ,11 ,1 ,

对全局头分析:

总长0x11=17位,8 代表采样精度是8位,1,67  是图片行数=1×256+0 x67=359行,1,da 代表图片列数:1x256+0xda=474,    3 代表图片的分量数:亮度Y,色度U,V 三个。

后9字节分为3组,每组3字节,第一组id为1(Y),第二为2(U),第三3(V),id号为第一字节,第3字节为每个分量采样的量化表id,第二个字节高4位代表水平采样个数,低4位垂直采样个数。

1,22,0    表示Y  在MCU中水平垂直隔有2个

2, 11 ,1   U 各一次

3, 11,  1         V 各一次 

意思就是说:此图片采样的是YUV 422 格式,有2个Y,1个U,1个V。

------------------------------------------------

此图片扫描头 SOS (0xffda)

ff ,da ,0 ,c ,3 ,1 ,0 ,2 ,11 ,3 ,11 ,0 ,3f ,0 ,

0,c:   扫描头长度 0×256+0xc=12 字节

 3: 3分量 ,Y,U,V

1,0,2,11,3,11  分位三组,每组2字节,第一个是id号

第二字节高4位是DC 号,低4位为AC 号

0 :代表Z排序是从0开始编号

3f: 0x3f=63   表示Z排序是63结束,最后一字节默认是0

有这些信息就可以解码了。

因为采用的是yuv422格式,那比特流开始就是2个Y,.紧跟1个U  ,1个V,组成一个MCU。比特流以此MCU格式为单位循环直到结束。

首先是亮度DC解码,马上是亮度AC解码,再是第二个亮度DC解码,再是第二个亮度AC解码。

 

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>  
#include <string.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <math.h>

int main(void) {
//	unsigned char dc0[28]={0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,0xa,0xb};
	
	 char y_dc(unsigned char len,int bit ){   //亮度DC
		if((len==2)&&(bit==0b00)){
		   return 0;	
		}	
		if((len==3)&&(bit==0b010)){
			return 1;
		}
		if((len==3)&&(bit==0b011)){
			return 2;
		}
		if((len==3)&&(bit==0b100)){
			return 3;
		}
		if((len==3)&&(bit==0b101)){
			return 4;
		}
		if((len==3)&&(bit==0b110)){
			return 5;
		}
		if((len==4)&&(bit==0b1110)){
			return 6;
		}
		if((len==5)&&(bit==0b11110)){
			return 7;
		}
		if((len==6)&&(bit==0b111110)){
			return 8;
		}
		if((len==7)&&(bit==0b1111110)){
			return 9;
		}
		if((len==8)&&(bit==0b11111110)){
			return 10;
		}
		if((len==9)&&(bit==0b111111110)){
			return 11;
		}
	    else return -1;
	}
	//----------------------------------
		
    char ali(char len,char i){            //ALI   
			char o;
			
			if (len == 0) {
				o = 0;
			}
			if ((len == 1) && (i == 0)) {
				o = -1;
			}
			if ((len == 1) && (i == 1)) {
				o = 1;
			}
			//--------------------------
			if ((i >= pow(2, len - 1)) && (i <= pow(2, len))) {
				o = i;
			}
			if ((i >= 0) && (i < pow(2, len - 1))) {
				o = i - pow(2, len) + 1;
			}
		    return o;
	    }	
	//------------------------------------------------------------------
	unsigned char data[100]={0xf5,0xe6,0x24,0x4e,0xff,0,0x41,0xfd,0x68};
	
	//    0xf5           ,  0xe6       ,    0x24
	//  1 1 1 1 0 1 0 1 ,1 1 1 0 0 1 1 0,0 0 1 0 0 1 0 0
	//11110   得到7,马上取7位 1011110=x   现在就可把7位加x,利用ALI 反退出真实的DC系数=94。    
	int a,b;
    char c;
	a=data[0];       //0xf5=0b11110101    5位=11110   输出7
	for(int n=2;n<7;n++){
		b=a;
		b=b>>(8-n);
		c=y_dc(n,b);
		if(c>0) break; 
	}
	//马上读7位,这7位不用转码
	
	printf("%d\n",ali(7,0b1011110));   //94
	return 0;
}

现在在验证转换的方法是否正确:对,正确!现在解码出亮度DC=94,马上就是对亮度AC解码。
  下一步搞一个读取变长度比特流的通用方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/262540.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

html/css实现简易圣诞贺卡

一、前言 HTML&#xff0c;全称HyperText Markup Language&#xff0c;即超文本标记语言&#xff0c;是用于创建网页的标准标记语言。HTML是一种标记语言&#xff0c;由一系列的元素标签组成&#xff0c;用于描述网页的结构和内容。 CSS&#xff0c;全称是“层叠样式表”&#…

Solon 开源框架,单月下载突破 250 万!!!

Solon 是什么开源项目&#xff1f; 一个&#xff0c;Java 生态型应用开发框架。它从零开始构建&#xff0c;有自己的标准规范与开放生态&#xff08;历时六年&#xff0c;已有全球第二级别的生态规模&#xff09;。与其他框架相比&#xff0c;它解决了两个重要的痛点&#xff…

linux下的进程组与会话的区别

进程组&#xff08;Process Group&#xff09;和会话&#xff08;Session&#xff09;是Unix/Linux操作系统中的两个概念&#xff0c;它们之间有一些关键区别&#xff1a; 定义和范围&#xff1a;一个进程组是一组相关进程的集合&#xff0c;它们具有相同的进程组ID&#xff08…

变分自动编码器【03/3】:使用 Docker 和 Bash 脚本进行超参数调整

一、说明 在深入研究第 1 部分中的介绍和实现&#xff0c;并在第 2 部分中探索训练过程之后&#xff0c;我们现在将重点转向在第 3 部分中通过超参数调整来优化模型的性能。要访问本系列的完整代码&#xff0c;请访问我们的 GitHub 存储库在GitHub - asokraju/ImageAutoEncoder…

最新国内免费使用GPT4教程,GPT语音对话使用,Midjourney绘画

一、前言 ChatGPT3.5、GPT4.0、GPT语音对话、Midjourney绘画&#xff0c;相信对大家应该不感到陌生吧&#xff1f;简单来说&#xff0c;GPT-4技术比之前的GPT-3.5相对来说更加智能&#xff0c;会根据用户的要求生成多种内容甚至也可以和用户进行创作交流。 然而&#xff0c;GP…

JS模块化规范之ES6及UMD

JS模块化规范之ES6及总结 前言ES6模块化概念基本使用ES6实现 UMD(Universal Module Definition)总结 前言 ESM在模块之间的依赖关系是高度确定的&#xff0c;与运行状态无关&#xff0c;编译工具只需要对ESM模块做静态分析&#xff0c;就可以从代码字面中推断出哪些模块值未曾被…

在 Windows 上恢复已删除文件的 9 种简单方法

本教程讨论永久丢失数据的原因以及在 Windows上恢复已删除文件的不同方法&#xff1a; 数据是提供给系统的任何形式的信息。它可以是从密码到记事本文件的任何内容。数据是当今世界的关键要素&#xff0c;因为它使我们的生活变得轻松。 我们每天都变得越来越依赖数据&#xf…

括号匹配问题

括号匹配问题是一个在算法和数据结构中常见的问题&#xff0c;主要目标是通过检查输入的括号序列是否平衡和闭合&#xff0c;以确定它们是否匹配。这涉及到各种类型的括号&#xff0c;如圆括号、花括号和大括号。 解决括号匹配问题的一种常见方法是使用栈。当遇到一个左括号时…

大语言模型(LLM)与 Jupyter 连接起来了!

现在&#xff0c;大语言模型&#xff08;LLM&#xff09;与 Jupyter 连接起来了&#xff01; 这主要归功于一个名叫 Jupyter AI 的项目&#xff0c;它是官方支持的 Project Jupyter 子项目。目前该项目已经完全开源&#xff0c;其连接的模型主要来自 AI21、Anthropic、AWS、Co…

探索鸿蒙:了解华为鸿蒙操作系统的基础课程

目录 学习目标&#xff1a; 学习内容&#xff1a; 学习时间&#xff1a; 学习产出&#xff1a; 介绍鸿蒙操作系统的起源和发展历程。 理解鸿蒙操作系统的核心概念和体系结构。 学习如何搭建和配置鸿蒙开发环境。 掌握基础的鸿蒙应用开发技术&#xff0c;包括应用的创建、…

别再犹豫!一键下载安装Substance3D,在数字世界中创造引人注目的艺术品!

不要再在网上浪费时间寻找Substance3D的安装包了&#xff0c;一键下载安装&#xff0c;你要的一切都可以在这里找到&#xff01; 对于那些热衷于数字艺术和建模的人来说&#xff0c;Substance3D是一个不可或缺的工具。然而&#xff0c;在网上寻找合法且可靠的软件安装包却常常…

微信开发工具修改编译一直报Cannot read property ‘call‘ of undefined?

我个人的解决方法 更新HbuilderX和微信小程序开发者工具到最新版&#xff0c;微信开发者工具-设置-本地设置-调试基础库也换成最新的3.2.4&#xff0c;打开又报错&#xff0c; 把manifest.json文件内的 “mp-weixin” : {“libVersion”: “latest”}配置上就好了 如果不能解…

【数据结构】图的创建(邻接矩阵,邻接表)以及深度广度遍历(BFS,DFS)

文章目录 前言1.图的存储结构1.邻接矩阵2.邻接表 一、邻接矩阵二、邻接表二、图的遍历1.DFS2.BFS 前言 图是由顶点集合及顶点间的关系组成的一种数据结构&#xff1a;G (V&#xff0c; E)&#xff0c;其中&#xff1a; 顶点集合V {x|x属于某个数据对象集}是有穷非空集合&…

PIC单片机项目(8)——基于PIC16F877A的温度光照检测装置的protues仿真

1.功能设计 使用PIC16F877A单片机&#xff0c;进行温度检测、光照检测。温度使用的是DS18B20&#xff0c;光照检测直接利用的AD转换。 光照太暗就开灯&#xff0c;温度太高就开风扇。温度阈值和光照阈值都实时显示在LCD1602屏幕上面。 完成了protues仿真。文件里面包含代码和仿…

聚观早报 |字节跳动今年销售额超腾讯;PS5游戏机全球销量

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 12月22日消息 字节跳动今年销售额超腾讯 PS5游戏机全球销量 华为nova 12 Pro参数曝光 抖音电商“焕新非遗”落地…

【Python】函数进阶

一、函数多返回值 二、函数多种传参方式 三、匿名函数 一、函数多返回值 函数如何返回多个返回值 多个返回值 二、函数多种传参方式 函数参数种类 使用方式上的不同, 函数有4中常见参数使用方式: 位置参数关键字参数不定长参数缺省参数 位置参数 关键字参数 缺省参数 不…

vivado 主时钟分析

主时钟 主时钟是通过输入端口或千兆位进入设计的板时钟收发器输出引脚&#xff08;例如恢复的时钟&#xff09;。主时钟只能由create_clock命令定义。主时钟必须附加到网表对象。此网表对象表示中的点所有时钟边沿源自其并在时钟树上向下游传播的设计。换句话说&#xff0c;主…

13 Linux 蜂鸣器

一、蜂鸣器驱动原理 常用蜂鸣器分两种&#xff0c;有源蜂鸣器和无源蜂鸣器。 它们俩的区别&#xff1a;有源蜂鸣器具有内置的振荡器和驱动电路&#xff0c;无源蜂鸣器没有&#xff1b;源蜂鸣器只需简单的数字信号来控制&#xff0c;无源蜂鸣器需要外部电路或微控制器来提供特定…

Fabric:使用GoLand+Fabric-SDK-Go操作Fabric网络

遇到bug, 未完待续!!! 写在最前 前序博客已经介绍了使用命令的方式在Fabric上创建通道以及部署执行链码的方法&#xff0c;但这个过程太繁琐&#xff0c;尤其是当Fabric网络中peer节点和组织Org过多时&#xff0c;需要频繁的更改环境变量。 Hyperledger Fabric官方提供了Fabri…