Jpeg图片在图像处理领域已经用的相当广泛了。但在编程领域,尤其是嵌入式编程领域使用的还不是很广。主要的原因是Jpeg的数据结构和算法远较bmp复杂,非图像算法的专业人士,通常是无法理解这些的。(我有个同事,他曾经花了半个月,研究过Jpeg的原理,还为此在team内部举办了一个讲座,讲了足足有一个小时,令众人对之仰慕万分,但他却说,仅得皮毛,未得要害。从此我对Jpeg的原理敬而远之。)
近来,因工作需要,要在wince平台下,为程序添加Jpeg支持。一般来说,此类问题最容易的解决方案是使用OS提供的相关库,毕竟现在不支持Jpeg的OS几乎没有。但在wince下这里出了个问题。目前绝大多数的wince设备是wince 4.X或5.X的,不过碰巧在图像处理这块,5.X和4.X的方法是不一样的。4.X提供的方法在IMGDECMP.DLL中,而5.X提供的方法在Imaging.DLL中,而且不止是链接库不同,库的接口也是完全两样的。因此,如果软件采用OS提供的相关库的话,在这里就要准备两套接口,非常的麻烦。况且,我们的软件不仅要在wince下部署,将来还打算推广到其他的平台,因此这种方案显然是不太好的。
这时我想到了JpegLib。JpegLib是Independent JPEG Group——一个非Jpeg官方组织推出的Jpeg库。这是个开源免费的库,支持多种平台和编译器,你可以在www.ijg.org中获得它的最新版本。在PC上它的效率比不了intel的Jpeg库,因为后者进行了汇编优化。但在wince上应该和系统库的效率相当。事实上如果查看系统的版权信息的话,Microsoft在wince中也使用了这个库。RISC的芯片也基本没有汇编优化的问题。
网上的中文资料以以下两篇文章最为详尽。
http://mobile.winfans.net/ccs/forums/516/PrintPost.aspx (文献A)
http://blog.csdn.net/zhao3728/archive/2007/08/22/1754877.aspx (文献B)
所以我的这篇文章主要作为补遗之用。
文献A和B都是使用现成的JpegLib库,这样的库只在特定的平台下才能用,完全体现不出JpegLib的优势。所以掌握编译JpegLib库的方法,是很有必要的。
JpegLib库源代码的组成
1)makefile。JpegLib库中有很多文件名为makefile的文件。它的后缀名表示它所用于的平台或用途。随便打开一个,就可以看到JpegLib库源代码的组成。
2)makefile中LIBSOURCES变量所代表的文件是JpegLib的核心算法部分。
3)makefile中SYSDEPSOURCES变量所代表的文件是JpegLib中负责内存分配的部分。这部分是系统相关的,所以根据需要选用一个就行了。
4)makefile中APPSOURCES变量所代表的文件是JpegLib中提供诸如命令行压缩Jpeg之类的功能的部分,实际上就是一些小工具。不过在编译JpegLib库时,不要将之添加到工程中。
5)makefile中INCLUDES变量所代表的文件是源代码中用到的头文件。不是所有的头文件都被核心算法部分使用到,因此有些头文件在编译JpegLib库时,是不必要的,当然将之添加到工程中也不会出错。
6)makefile中DOCS变量所代表的文件是一些文档、测试用例之类的东西。其中最有用的是example.c,文献A和B的示例最重要的部分,就来自这里。
7)jconfig。JpegLib库中还有很多和makefile类似的jconfig,这是针对不同平台的类型声明。在使用时,应根据需要,将适当的jconfig文件的后缀名改为h。
以上这些内容更详细的说明见JpegLib库的文档,以及
http://blog.csdn.net/axlrosek/archive/2007/03/29/1545496.aspx
ijg jpeg函数库:文件列表
VC:不同版本的VC、EVC都差不多,参照文献A的步骤修改相关文件,然后新建一个空工程,然后打开JpegLib中的makefile.vc文件,将2)和3)、5)、7)中的文件添加到工程中。将生成文件的类型定为lib就行了。此外,还需要针对调用的情况选择适当的运行时库,否则可能会出LNK2005错误。
JpegLib库的使用参照文献A和B,以及example.c就可以了。但文献A的示例是有问题的。
bmpBuffer[start+i]=pBuffer[0];
应改为
bmpBuffer[start+i]=pBuffer[0][i];
jpeg_read_scanlines(&cinfo, pBuffer, 1)执行之后,扫描线的内容被放到pBuffer[0],而不是pBuffer中,用memcpy将扫描线的内容转移到其他的缓冲区就行了,无需用循环语句。
上面的示例处理的都是从文件读入的Jpeg,在现实中,还存在流输入的Jpeg。在很多PC游戏中,程序的数据都被集中起来放入一个大文件之中,最典型的当属暴雪的mpq文件。当这些文件被读入内存时,就形成了字节流形式的文件。将之存为临时文件,然后再用之前的方法,显然是笨方法。这时可以采用jpeg_arr_src函数来替换jpeg_stdio_src函数。
这一点还可以参考以下文档,不过该文针对的好像是旧版本,使用时要注意。
http://blog.china.com/u/060803/5544/200608/15355.html
stb_image是一个C语言的图像解码库,支持JPG, PNG, TGA, BMP, PSD, GIF, HDR, PIC等格式。
代码:
https://github.com/nothings/stb
参考:
https://www.jianshu.com/p/5e4b99586282
简单易用的图像解码库介绍——stb_image
WireShark是一个网络协议包分析工具,最初名叫Ethereal。它的官网是:
https://www.wireshark.org/
sudo apt install wireshark
安装好了之后,还不能立即使用。需要给/usr/bin/dumpcap提升权限,才能使用WireShark的抓包功能。否则会出no interfaces
的错误。
提升权限的方法有:
1.root方式。
命令行:sudo wireshark
桌面图标:gksudo wireshark
2.非root方式,这也是官方推荐的方式。
sudo dpkg-reconfigure wireshark-common
sudo usermod -a -G wireshark <your user name>
sudo chgrp wireshark /usr/bin/dumpcap
sudo chmod 4750 /usr/bin/dumpcap
sudo setcap cap_net_raw,cap_net_admin=eip /usr/bin/dumpcap
最后注销当前用户,重新登陆即可。
WireShark以丰富的过滤器著称,现将我使用到的过滤器规则摘录如下:
ip.src == 10.3.9.234 || ip.dst == 10.3.9.234
过滤源地址和目标地址。
tcp matches Bob
匹配特定字符串。
tcp.stream eq id
将一次TCP交互的包过滤出来,id表示是第几次交互。
这套规则实际上就是所谓的BPF(Berkeley Packet Filter)。1992年由Steven McCanne和Van Jacobson提出,1997年引入Linux Kernel 2.1,3.0中增加了即时编译器,应用在网络过滤领域。
2014年Alexei Starovoitov实现了eBPF并扩展到用户空间,威力更大。
https://mp.weixin.qq.com/s/SQ-3fO5ZInqB5aeKCPpluw
Linux中基于eBPF的恶意利用与检测机制
https://mp.weixin.qq.com/s/y89cPgaIBWeudJnsFRR-Ow
我用“大白鲨”让你看见TCP
Fiddler是另一个常用的抓包工具。
fiddler相当于一个中间商,当浏览器发送请求,会先经过fiddler,然后在转给服务器;当服务器有返回数据给浏览器显示时,也会先经过fiddler,然后再把数据返沪给客户端,在这样一个过程,fiddler就可以截取请求和响应。
Wireshark跟fiddler的主要区别就是,Wireshark主要用来帮助用户对网络行为有一个了解,而不能对网络内容做更改或是提示,也就是说只能查看不能修改或转发。
官网:
https://www.telerik.com/fiddler
参考:
https://www.cnblogs.com/Adam-Ye/p/15265899.html
抓包:Fiddler和Wireshark的简单使用
Whistle是腾讯推出的Fiddler替代品。
官网:
https://wproxy.org/whistle/
代码:
https://github.com/avwo/whistle
参考:
https://www.cnblogs.com/zhihuilai/p/9992533.html
Whistle,web抓包与debug利器
https://zhuanlan.zhihu.com/p/441818328
Whistle实现原理——从0开始实现一个抓包工具
早期如Bochs之类的没用过,现在估计也没什么人用了吧。
现在主要是以下三个选择:
1.VMware。商业收费软件。有免费版本的VMware Player,但该版本不可创建虚拟机,只可使用别人已经建好的虚拟机。
2.VirtualBox。开源免费软件。
3.Qemu。Qemu的易用性不佳,作为使用的话,能不用就不用了。但其不仅开源,而且支持的架构也很多,有的时候往往是唯一之选。作为研究学习来说,这个是首选。
这里主要讨论前两者的选择。
VMware由于是收费软件之故,因此用户的软件升级是个大问题。(土豪除外,有钱的话,这个就不是事了。)而旧的软件,往往对新的Linux发行版的支持较差。很多情况下,VMware Tool因为这个原因总是无法完美运行。严重影响了软件的易用性。
反之,VirtualBox就没有这些问题。虽然比较同期的VMware来说,VirtualBox的性能略逊。但是一般来说,科技行业里领先半年就已经是巨大的优势了。我相信现在的VirtualBox,无论如何也不会弱于两年前的VMware。
因此与其守着过时的VMware 8.0,还不如换用VirtualBox,这就是我的选择。
http://www.tinylab.org/learn-x86-language-courses-on-the-ubuntu-qemu-cs630/
Linux下通过Qemu学习X86 AT&T汇编语言
http://www.tinylab.org/using-qemu-simulation-inserts-the-type-system-to-produce-the-whole-process/
利用qemu模拟嵌入式系统制作全过程
这两篇文章讲述如何使用qemu运行各种汇编程序和微内核。
您的打赏,是对我的鼓励