При использовании 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
, но это, конечно, не кажется переносимым или, в этом отношении, необходимым для такого (общего) изменения выхода.
Таким образом, оказывается, что лучшим решением (по крайней мере, тем, которое не требует каких-либо пользовательских сборок libs или дополнительных проходов через буфер) является использование libjpeg-turbo. Начиная с 1.1.90 они предоставляют константу цветового пространства JCS_EXT_RGBX
это добавляет поддельный альфа-канал. Насколько мне известно, это документировано только в примечаниях к выпуску бета-версии на SourceForge настолько, что этот URL меняется или больше не существует (Читайте: Интернет восстает против sf за его теневую вставку кода в «неактивные» популярные репозитории, и они вынуждены закрыться), вот соответствующий бит воспроизводится:
При распаковке изображения JPEG с использованием выходного цветового пространства
JCS_EXT_RGBX
,JCS_EXT_BGRX
,JCS_EXT_XBGR
, или жеJCS_EXT_XRGB
, libjpeg-турбо будет
теперь установите неиспользуемый байт в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
,