libjpeg解码为BGR

Tho*_*son 10 c++ jpeg image image-processing libjpeg

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

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

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

sam*_*var 9

几种解决方案:

  • 按照建议进行转换.如果你处理4像素的组,你可以做三件32位读写,位掩码和移位,并且非常快.
  • 将libjpeg的YUV修改为RGB转换或刚刚修改后的阶段,以便交换R和B.
  • 使用libjpeg-turbo.它向后兼容libjpeg,具有SIMD加速,并提供JCS_EXT_BGRJCS_EXT_BGRX颜色空间.
  • 修改源图像,以便交换它们的R和B通道.听起来很傻,但它需要零源代码修改.

另外,你说你在追赶速度但你操纵BGR数据(而不是BGRX).这对我来说没有多大意义,因为在32位边界上对齐像素可能要快得多.

  • 很高兴知道它有所帮助.请注意,32位块可能更快的原因并不是高速缓存效率(24位块占用的空间更少,因此对缓存更好)但数据访问简单,因为访问具有24位像素的随机像素可能需要两个32位读取(或三个8位读取),而32位像素相同,只需要一次32位读取. (2认同)

the*_*ine 5

正如 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 */
Run Code Online (Sandbox Code Playgroud)

所以你只需将它们更改为:

#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 */
Run Code Online (Sandbox Code Playgroud)

你就完成了。评论进一步指出:

/*
 * 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.
 */
Run Code Online (Sandbox Code Playgroud)