libjpeg库解码jpeg图像输出数据排列问题
2015-02-04 23:08
471 查看
上一篇文章我们谈到如何修改libjpeg库来解码内存中的jpeg数据这件事情,也确实做到了这一点,然而紧随其后的就发现了一个很蛋疼的问题。因为libjpeg库输出的图像像素是以r-g-b这样的顺序排列的,而在Windows平台上要去显示内存中的图像数据通常是在内存中创建一个位图对象bitmap,然后将要显示的图像数据拷到其相应的位置中,拷贝完成后显示图像。蛋疼的地方就在于bitmap的像素是以b-g-r这样的顺序排列的,这就要求我们在拷贝数据的时候要逐个像素点进行修改,这样做浪费的时间是跟图像的大小成正比的,在图像稍微大一点的情况下,通过写测试程序痛苦的发现比用OpenCV直接读取硬盘的数据显示还要慢,简直不能忍。而即便是不拿去显示直接保存成BMP格式的图像也会遇到同样的问题。
难道就这样放弃了吗?其实解决的方法是有很多的,对于高富帅而言可以买一个性能超级强悍的CPU来让它计算的快点,做过显卡加速的可以用显卡开很多的线程来消除这个运算时间跟图像大小成正比的问题。然而我们有必要这样做吗?回头想一想libjpeg在这个过程中干了什么,它不过就是把jpeg数据解码出来然后逐个像素放进一块内存里面,放完之后传给我们啊,这个r-g-b或者b-g-r不过就是它放的时候地址偏移量设置的不同而已啊!我们如果能修改掉这部分的代码不就能直接连1ns都不需要浪费就解决这个问题吗?
说干就干,从源码入手,在苍茫的代码之中游魂了快半个钟后发现了jdcolor.c文件中有这么一处
可以说是踏破铁鞋无觅处得来全不费工夫,这不正是我们要找的地方吗?!把其中的
编译,完成!
现在libjpeg库解码jpeg图像数据输出的图像像素是以b-g-r顺序排列的啦!
难道就这样放弃了吗?其实解决的方法是有很多的,对于高富帅而言可以买一个性能超级强悍的CPU来让它计算的快点,做过显卡加速的可以用显卡开很多的线程来消除这个运算时间跟图像大小成正比的问题。然而我们有必要这样做吗?回头想一想libjpeg在这个过程中干了什么,它不过就是把jpeg数据解码出来然后逐个像素放进一块内存里面,放完之后传给我们啊,这个r-g-b或者b-g-r不过就是它放的时候地址偏移量设置的不同而已啊!我们如果能修改掉这部分的代码不就能直接连1ns都不需要浪费就解决这个问题吗?
说干就干,从源码入手,在苍茫的代码之中游魂了快半个钟后发现了jdcolor.c文件中有这么一处
while (--num_rows >= 0) { inptr0 = input_buf[0][input_row]; inptr1 = input_buf[1][input_row]; inptr2 = input_buf[2][input_row]; input_row++; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { y = GETJSAMPLE(inptr0[col]); cb = GETJSAMPLE(inptr1[col]); cr = GETJSAMPLE(inptr2[col]); /* Range-limiting is essential due to noise introduced by DCT losses, * for extended gamut (sYCC) and wide gamut (bg-sYCC) encodings. */ /* outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; outptr[RGB_GREEN] = range_limit[y + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS))]; outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]];*/ outptr[RGB_BLUE] = range_limit[y + Crrtab[cr]]; outptr[RGB_GREEN] = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS))]; outptr[RGB_RED] = range_limit[y + Cbbtab[cb]]; outptr += RGB_PIXELSIZE; } }
可以说是踏破铁鞋无觅处得来全不费工夫,这不正是我们要找的地方吗?!把其中的
outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; outptr[RGB_GREEN] = range_limit[y + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],SCALEBITS))]; outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]]改为
outptr[RGB_BLUE] = range_limit[y + Crrtab[cr]]; outptr[RGB_GREEN] = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS))]; outptr[RGB_RED] = range_limit[y + Cbbtab[cb]];
编译,完成!
现在libjpeg库解码jpeg图像数据输出的图像像素是以b-g-r顺序排列的啦!
相关文章推荐
- 利用libjpeg库解码内存中的jpeg数据
- CUDA 实现JPEG图像解码为RGB数据
- 使用openCV对JPEG图像内存进行解码及时间过长问题;
- QT中用socket接收图像数据(JPEG)后立即解码显示
- libjpeg库支持解码内存中的jpeg数据
- 海思音频解码采用主动获取解码通道数据发送到音频输出通道时出现的问题
- CUDA 实现JPEG图像解码为RGB数据
- 【数据结构及算法】2.图像染色问题
- 表数据输出格式问题
- [C]数组全排列输出问题
- Android中解决图像解码导致的OOM问题
- 将数据绑定DataGrid并输出Excel文档的数据模型问题
- 实时向客户端输出数据(例如1秒输出一行) 要注意的两个问题
- 数据传输出了问题,排错过程
- 图像解码之一——使用libjpeg解码jpeg图片
- 使用mapgis6.7进行工程输出为JPEG图片,弹出内存不足或者内存警告问题的解决方案
- Android中解决图像解码导致的OOM问题
- java合成jpeg图像 压缩问题 resize问题
- Graphics->BitmapDecode 介绍Android 平台对图像的解码功能,Android平台支持PNG, JPEG图像格式,并可以支持 gif动画。
- 转载:libjpeg解码内存jpeg数据