libjpeg/libjpeg-turbo RGBA/32-битная внутренняя декомпрессия

При использовании libjpeg для подачи изображений в OpenCL, чтобы иметь возможность обрабатывать каналы как нормализованные uint8 с CL_UNORM_INT8 (плавает в диапазоне [0.0, 1.0]), вы можете использовать только 4-канальные компоненты. Это проблематично, поскольку libjpeg выводит только 3 (по умолчанию в порядке RGB), поскольку у JPEG нет понятия непрозрачности.

Единственный обходной путь, который я вижу, состоит в том, чтобы отсканировать строки с помощью libjpeg, а затем создать дублирующий буфер соответствующей длины (с добавлением компонента четвертого канала для каждого пикселя в строках сканирования), а затем memcpy значения более, устанавливая альфа-компонент в 255 для каждого. Вы могли бы даже сделать это на месте, если вы хитры и инициализируете буфер, чтобы row_stride * 4 сначала, а затем идти назад от индекса row_stride * 3 - 1 в 0, перемещая компоненты в соответствующие места в полном буфере (и добавляя 255 для альфы где надо).

Тем не менее, это кажется хакерским, и если вы имеете дело с большими изображениями (я), недопустимо иметь этот дополнительный проход (что будет в совокупности) всего изображения.

Итак, есть ли способ заставить libjpeg просто увеличить количество компонентов до 4? Я пытался установить свойства на cinfo лайк output_components но безрезультатно. Я читал, что единственный способ обойти это скомпилировать специальную версию libjpeg с константой RGB_COMPONENTS = 4 установить в jmorecfg.h, но это, конечно, не кажется переносимым или, в этом отношении, необходимым для такого (общего) изменения выхода.

1 ответ

Решение

Таким образом, оказывается, что лучшим решением (по крайней мере, тем, которое не требует каких-либо пользовательских сборок libs или дополнительных проходов через буфер), является использование libjpeg-turbo. Начиная с 1.1.90 они предоставляют константу цветового пространства JCS_EXT_RGBX это добавляет поддельный альфа-канал. Насколько мне известно, это задокументировано только в примечаниях к выпуску бета-версии на SourceForge, за исключением того, что этот URL-адрес изменяется или больше не существует (читай: интернет восстает против sf за его теневую вставку кода в "неактивные" популярные репозитории, и они вынужден выключить), вот соответствующий бит воспроизводится:

При распаковке изображения JPEG с использованием выходного цветового пространства JCS_EXT_RGBX, JCS_EXT_BGRX, JCS_EXT_XBGR, или же JCS_EXT_XRGBlibjpeg-turbo теперь будет устанавливать неиспользуемый байт в 0xFF, что позволяет приложениям интерпретировать этот байт как альфа-канал (0xFF = непрозрачный).

Обратите внимание, что это также позволяет альтернативные заказы, такие как BGR, если они вам нужны.

Чтобы использовать его после вашего jpeg_read_header() вызов (потому что этот вызов устанавливает член на cinfo нам нужно по умолчанию) но перед вашим jpeg_start_decompress() вызов (потому что он использует значение этого члена), добавьте:

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

И теперь сканирование строк во время распаковки будет возвращать дополнительный четвертый компонент для каждого пикселя, установленного в 255,

Другие вопросы по тегам