libjpeg decoding to BGR

libjpeg decoding to BGR

本文关键字:BGR to decoding libjpeg      更新时间:2023-10-16

我使用libjpeg将一个jpeg图像从磁盘解码到堆上分配的内存缓冲区。我使用jpeg_read_scanlines从文件中读取和解码每个扫描线。这是完美的工作,解码每个像素为24位RGB值。

问题是我正在使用一个额外的第三方库,它需要BGR格式的缓冲区(而不是RGB)。当使用这个库时,我得到奇怪的结果,因为通道的顺序错误。

因此,我想找到一种方法,使libjpeg解码为BGR格式,而不是RGB。我已经在网上搜索了,找不到如何配置libjpeg来做到这一点?我知道我可以在内存缓冲区上做一个额外的传递,并手动重新排序颜色通道,但是我正在做的应用程序是非常时间关键的,必须尽可能快速和高效。

为您提供几个解决方案:

  • 按照建议进行转换。如果你在4个像素的组上工作,你可以用3个32位的读写,位掩码和移位来做任何事情,并且非常快。
  • 修改libjpeg的YUV到RGB转换或之后的阶段,以便它交换R和b。
  • libjpeg-turbo使用。它向后兼容libjpeg,具有SIMD加速,并提供JCS_EXT_BGRJCS_EXT_BGRX颜色空间。
  • 修改源图像,使它们的R和B通道交换。听起来很傻,但它不需要修改源代码。

同样,你说你追求速度,但你操作BGR数据(而不是BGRX)。这对我来说没有多大意义,因为在32位边界上对齐像素可能会快得多。

如Antun Tun所说,配置在jmorecfg.h中。在我的libjpeg版本(v7)中,它位于第320行:

#define RGB_RED     0   /* Offset of Red in an RGB scanline element */
#define RGB_GREEN   1   /* Offset of Green */
#define RGB_BLUE    2   /* Offset of Blue */

所以你只需把它们改成:

#define RGB_RED     2   /* Offset of Red in an RGB scanline element */
#define RGB_GREEN   1   /* Offset of Green */
#define RGB_BLUE    0   /* Offset of Blue */

你完成了。注释进一步说:

/*
 * RESTRICTIONS:
 * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
 * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not
 *    useful if you are using JPEG color spaces other than YCbCr or grayscale.
 * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
 *    is not 3 (they don't understand about dummy color components!).  So you
 *    can't use color quantization if you change that value.
 */

JPEGLIB说您必须修改jmorecfg.h才能更改通常的rgb值顺序。这是文件的链接:http://www.opensource.apple.com/source/tcl/tcl-20/tcl_ext/tkimg/tkimg/libjpeg/libjpeg.doc它位于

数据格式部分

看看我的JPEG编解码器。

我还没有实际测试它对libjpeg的速度。如果你能做到这一点,这可能是一个启示。无论如何,解码器都在一个文件中,并且简单地颠倒通道的顺序将非常简单。

我在这里维护JPEG代码:

https://github.com/MalcolmMcLean/babyxrc/tree/master/src

从libjpeg的最后一个版本开始,还可以修改jpeg_read_header()调用后获得的cinfo对象的out_color_space属性。

引用libjpeg.txt:

J_COLOR_SPACE out_color_space

输出颜色空间。jpeg_read_header()基于jpeg_color_space设置一个合适的默认值;通常是RGB或灰度。应用程序可以更改此字段以请求不同颜色空间的输出。例如,将其设置为JCS_GRAYSCALE以从颜色文件中获得灰度输出。

所以,如果你希望你的图像被解码为BGR,你可以在解压时添加这一行:

cinfo.out_color_space = JCS_EXT_BGR;

据我所知,Libjpeg没有办法做到这一点。
在任何情况下,它只是一个O(n)变换。