декодирование libjpeg в BGR - PullRequest
10 голосов
/ 11 апреля 2011

Я использую libjpeg для декодирования изображения jpeg с диска в буфер памяти, выделенный в куче.Я использую jpeg_read_scanlines для чтения и декодирования каждой строки сканирования из файла.Это работает отлично, декодируя каждый пиксель как 24-битное значение RGB.

Проблема в том, что я использую дополнительную стороннюю библиотеку, для которой требуется буфер в формате BGR (а не RGB).При использовании этой библиотеки я получаю странные результаты, так как каналы расположены в неправильном порядке.

Поэтому я бы хотел найти способ декодирования libjpeg в формат BGR, а не в RGB.Я трахал в Интернете и не могу найти, как настроить libjpeg для этого?Я знаю, что мог бы сделать дополнительный проход через буфер памяти и изменить порядок цветовых каналов вручную, однако приложение, над которым я работаю, чрезвычайно критично по времени и должно быть максимально быстрым и эффективным.

Ответы [ 6 ]

9 голосов
/ 11 апреля 2011

Несколько решений для вас:

  • Выполните преобразование в соответствии с предложением. Если вы работаете с группами по 4 пикселя, вы можете делать все с помощью трех 32-разрядных операций чтения и записи, битовых масок и сдвигов и быть очень быстрыми.
  • Измените преобразование libjpeg YUV в RGB или стадию сразу после него, чтобы поменять местами R и B.
  • Используйте libjpeg-turbo . Он обратно совместим с libjpeg, имеет ускорение SIMD и обеспечивает JCS_EXT_BGR и JCS_EXT_BGRX цветовые пространства.
  • Измените исходные изображения, чтобы их каналы R и B поменялись местами. Звучит глупо, но требует нулевого изменения исходного кода.

Кроме того, вы говорите, что вы набрали скорость, но управляете данными BGR (вместо BGRX). Это не имеет особого смысла для меня, поскольку выравнивание пикселей на 32-битных границах, вероятно, будет намного быстрее.

4 голосов
/ 05 октября 2013

Как говорит 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 */

Так что вы просто измените их на:

#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 */

И все готово. Комментарии далее говорят:

/*
 * 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.
 */
3 голосов
/ 16 февраля 2013

JPEGLIB говорит, что вам нужно изменить jmorecfg.h, чтобы изменить обычный порядок значений R G B. Вот ссылка на документ: http://www.opensource.apple.com/source/tcl/tcl-20/tcl_ext/tkimg/tkimg/libjpeg/libjpeg.doc Это в разделе Форматы данных

2 голосов
/ 21 декабря 2016

Начиная с последних версий libjpeg, также возможно изменить атрибут out_color_space объекта cinfo, полученный после вызова jpeg_read_header().

Цитирование libjpeg.txt:

J_COLOR_SPACE out_color_space

Выходное цветовое пространство.jpeg_read_header() устанавливает соответствующее значение по умолчанию на основе jpeg_color_space;как правило, это будет RGB или оттенки серого.Приложение может изменить это поле, чтобы запросить вывод в другом цветовом пространстве.Например, установите его на JCS_GRAYSCALE, чтобы получить вывод в градациях серого из цветного файла.

Итак, если вы хотите, чтобы ваши изображения были декодированы как BGR, вы можете добавить эту строку при распаковке:

cinfo.out_color_space = JCS_EXT_BGR;
1 голос
/ 21 декабря 2016

Посмотрите на мой кодек JPEG.

На самом деле я не проверял его на скорость по сравнению с libjpeg. Если бы ты мог сделать это, это могло бы быть откровением. В любом случае, декодер находится в одном файле, и будет очень просто просто изменить порядок каналов.

Я сохраняю код JPEG здесь:

https://github.com/MalcolmMcLean/babyxrc/tree/master/src

0 голосов
/ 11 апреля 2011

Насколько я знаю, у Libjpeg нет способа сделать это.
В любом случае, это всего лишь O (n) преобразование.

...