libjpeg/libjpeg-turbo RGBA/32-bit int解压

libjpeg/libjpeg-turbo RGBA/32-bit int decompression

当使用 libjpeg 将图像送入 OpenCL 时,为了能够将通道视为具有 CL_UNORM_INT8 的规范化 uint8(在 [0.0, 1.0] 范围内浮动),您只能将其送入具有 4 通道的缓冲区组件。这是有问题的,因为 libjpeg 只输出 3(默认情况下按 RGB 顺序),因为 JPEG 没有不透明度的概念。

我看到的唯一解决方法是使用 libjpeg 扫描线,然后复制一个适当长度的缓冲区(为扫描线中的每个像素添加第四个通道组件),然后 memcpy 值结束,将每个的 alpha 分量设置为 255。如果你很狡猾,你甚至可以就地执行此操作,并将缓冲区初始化为 row_stride * 4,然后从索引 row_stride * 3 - 1 向后移动到 0,将组件移动到适当的位置完整缓冲区(并在必要时为 alpha 添加 255)。

但是,这感觉很糟糕,如果您正在处理大图像(我是),那么将这个额外的传递(将是聚合的)整个图像是不可接受的。

那么,有没有办法让 libjpeg 将组件的数量扩展到 4 个?我尝试在 cinfo 上设置属性,例如 output_components,但无济于事。我读到过,唯一的解决方法是编译一个特殊版本的 libjpeg,并在 jmorecfg.h 中设置常量 RGB_COMPONENTS = 4,但这肯定感觉不到可移植性,或者就此而言(常见的) ) 输出变化。

事实证明,最好的解决方案(至少,不需要任何自定义构建库或额外通过缓冲区的解决方案)是使用 libjpeg-turbo。从 1.1.90 开始,他们提供了一个颜色空间常量 JCS_EXT_RGBX 来添加一个假的 alpha 通道。据我所知,这是 only documented in the release notes of a beta version on SourceForge,所以除非 URL 发生变化或不再存在(阅读:互联网反抗 sf 将代码阴暗地插入 "inactive" 流行回购,他们被迫关闭),这里是转载的相关位:

When decompressing a JPEG image using an output colorspace of JCS_EXT_RGBX, JCS_EXT_BGRX, JCS_EXT_XBGR, or JCS_EXT_XRGB, libjpeg-turbo will now set the unused byte to 0xFF, which allows applications to interpret that byte as an alpha channel (0xFF = opaque).

请注意,如果您需要,这还允许其他顺序,例如 BGR。

要在您的 jpeg_read_header() 调用之后使用它(因为此调用在 cinfo 上设置了一个成员,我们需要一个默认值)但在您的 jpeg_start_decompress() 调用之前(因为它使用值该成员的),添加:

cinfo.out_color_space = JCS_EXT_RGBX; // or JCS_EXT_XRGB, JCS_EXT_BGRX, etc.

现在解压缩期间的扫描线将为每个像素设置 return 额外的第四个分量 255