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
。
当使用 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
, orJCS_EXT_XRGB
, libjpeg-turbo will now set the unused byte to0xFF
, 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
。