| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> ZBar源码分析——image.c | 2021SC@SDUSC -> 正文阅读 |
|
[C++知识库]ZBar源码分析——image.c | 2021SC@SDUSC |
2021SC@SDUSC 一、Image 模块ZBar的工作流程在以往的博客中做过一些介绍,在前几次的博客分析中也对video input部分和image scanner部分的一些代码进行了分析。在分析的过程中,我们发现,ZBar的Image模块起着不可或缺的作用,所有的分析和解码工作都是建立在图像的基础上完成的。 从工作流程图中我们也能看出,视频输入后,需要转换成图像的形式进行后续分析,并不是之间对视频进行处理。?在之前的博客中,也对Image模块的部分代码进行过简单介绍和分析,这篇博客将从image.c展开,对Image模块进行探索。 二、代码分析首先对zbar_image_t的结构(ZBar图像的数据结构)进行说明。这在前面的博客中提及过。
uint32_t格式;/*fourcc图像格式代码*/ 注:FourCC全称Four-Character Codes,代表四字符代码 (four character code), 它是一个32位的标示符,其实就是typedef unsigned int FOURCC;是一种独立标示视频数据流格式的四字符代码。 视频播放软件通过查询 FourCC 代码并且寻找与 FourCC 代码相关联的视频解码器来播放特定的视频流。比如: DIV3 = DivX Low-Motion, DIV4 = DivX Fast-Motion, DIVX = DivX4, FFDS = FFDShow 等。比如wav、avi等RIFF文件的标签头标示,Quake 3的模型文件.md3中也大量存在等于“IDP3”的FOURCC。 unsigned width, height; /*图像大小*/ const void *data; /*图像样本数据*/ ?unsigned long datalen;??/*已分配/映射的数据大小*/? unsigned crop_x, crop_y;??/*裁剪矩形*/ unsigned crop_w, crop_h; void*userdata; /*与图像关联的用户指定数据*/ refcnt_t refcnt; /*引用计数*/ zbar_video_t*src; /*生成器*/ int srcidx; /*生成器使用的索引*/ zbar_image_t *next; /*内部图像列表*/ unsigned seq; /*页/帧序列号*/ zbar_symbol_set_t*syms; /*解码结果集*/ 检索、扫描并裁剪矩形
在前面的代码分析中提到,BZar在对图像进行扫描、解码等操作时,都是基于矩形进行的。这个函数将识别得到的图像中条码附近的矩形区域进行了处理,将不包含条码的区域裁剪掉,得到需要处理的区域。 图像内存释放
接下来分析的函数负责释放图像内存。首先注意到,这个函数是内联函数。 内联函数?在C语言中,如果一些函数被频繁调用,不断地有函数入栈,即函数栈,会造成栈空间或栈内存的大量消耗。 为了解决这个问题,特别的引入了inline修饰符,表示为内联函数。 栈空间就是指放置程式的局部数据也就是函数内数据的内存空间,在系统下,栈空间是有限的,假如频繁大量的使用就会造成因栈空间不足所造成的程式出错的问题,函数的死循环递归调用的最终结果就是导致栈内存空间枯竭。 内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。 ZBar项目中特地将释放图像内存的函数声明为内联函数,说明该函数在ZBar项目的运行过程中将被频繁调用,换言之,ZBar的运行过程中将频繁对图像进行创建和释放。这也在某种程度上体现了Image模块对ZBar项目的重要性。 回到函数本身,在释放图像内存时,首先判断当前图像是否处在一个视频文件的逐帧迭代中(由src属性确定),如果是,则更换带有新副本的视频图像,将下一帧图像需要的资源进行内存拷贝,并对当前图像的索引进行重置。如果当前图像并不处在一个视频文件的逐帧迭代中,或是以及完成迭代,则检查其中关联的数据是否被释放,如果未被释放,则需要先释放这些数据,否则会产生空指针异常。这些检查工作完成后,方可释放图像内存。 值得一提的是,上述函数中提及了memcpy()函数: 函数原型为:void *memcpy(void *destin, void *source, unsigned n); 它实现了从源source所指的内存地址的起始位置开始拷贝n个字节到目标destin所指的内存地址的起始位置中。 图像写入文件
对ZBar工作流程进行简单分析可以得知,ZBar对图像进行获取后,会在内存中以临时文件的形式进行保存,便于后续扫描器和解码器的使用。 在实现该函数时,首先声明了图像的渲染格式,即?zimg_hdr_s,所有的图像都会以该数据结构规整后的格式存入。代码中将渲染格式中的magic属性规定为0x676d697a,这也许是图像的统一色调。 该函数开始时,对图像文件创建一份副本,副本的文件大小=原文件大小+16。这是为了防止在后续的处理过程中,对图像文件进行了增量而导致申请的内存不够出现数据丢失的问题。 该函数的后续处理较为简单,通过几个分支对不同格式的图像进行分类保存。 三、总结本次博客对ZBar扫描器的Image模块的几个关键函数进行了分析,也是对Video模块的一些补充说明。如有不足,敬请指正。 |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 7:30:17- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |