Выровнять по границе слова в битовой карте RLE: противоречие в документации Microsoft

Документация Microsoft по сжатию растровых изображений, в частности описание BI_RLE8 (8-битный индексированный цвет с использованием сжатия кодирования по длине прогона), включает следующее описание абсолютного режима:

В абсолютном режиме первый байт равен нулю, а второй байт является значением в диапазоне от 03H до FFH. Второй байт представляет количество байтов, которые следуют, каждый из которых содержит индекс цвета [в таблицу цветов] одного пикселя. [...] В абсолютном режиме каждый прогон должен быть выровнен по границе слова.

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

Тем не менее, пример в документации включает прогон с нечетной длиной, который не заканчивается на границе слова:

[03 04] [05 06] [00 03 45 56 67] [02 78] [00 02 05 01] [02 78] [00 00] [09 1E] [00 01] 

Должен 00 03 45 56 67 быть 00 03 45 56 67 00?

3 ответа

Я изменил 8-битную индексированную цветную битовую карту, и результаты, по-видимому, указывают на то, что серии действительно должны быть дополнены нулями до конца на 16-битной границе слова (00 03 45 56 67 должно быть 00 03 45 56 67 00).

Подробности:

  • В Microsoft Paint (версия 1607, включенная в Windows 10) я создал растровое изображение 4x4, содержащее красные (R), зеленые (G) и синие (B) пиксели в следующем порядке:

    BRBR
    BBBB
    GGBB
    RRRG
    
  • Я сохранил файл в виде 256-цветного растрового изображения (не было возможности использовать индексированный цвет или кодирование по длине прогона).
  • Я открыл файл в Gnu Image Manipulation Program (GIMP), изменил цветовой режим на индексированный (через Image > Mode > Indexed) и экспортировал его как "Windows BMP", отметив опцию "Run-Length Encoded".
  • Я сделал копию файла и открыл его в HxD (шестнадцатеричный редактор).
  • На этом этапе данные пикселей были представлены следующим образом (обратите внимание, что в соответствии с документацией изображение начинается слева внизу и продолжается слева направо):

    03 4F // Three red pixels
    01 71 // One green pixel
    00 00 // EOL
    00 04 71 71 E8 E8 // GGBB
    00 00 // etc.
    04 E8
    00 00
    00 04 E8 4F E8 4F
    00 01 // EOF
    
  • В начале области данных пикселей я заменил 03 4F (три красных пикселя указаны в кодированном режиме; обратите внимание, что красный был отображен в индекс 0x4F = 79 в таблице цветов) с 00 03 4F 4F 4F (три красных пикселя указаны в абсолютном режиме без заполнения нулями), обновили размер файла в заголовке и сохранили изменения.
  • При открытии в GIMP и Paint измененный файл отображался неправильно: пиксели в первых двух строках и нижнем правом пикселе были черными, а последние два пикселя в третьей строке были зелеными, а не голубыми.
  • В HxD я изменил 00 03 4F 4F 4F в 00 03 4F 4F 4F 00 (три красных пикселя, заданные в абсолютном режиме, с нулевым байтом, добавленным для завершения цикла на границе 16-битного слова), обновили размер файла в заголовке и сохранили файл.
  • При открытии в GIMP файл теперь отображается правильно. При открытии в Paint верхний ряд был черным (я подозреваю, что я не обновил поле заголовка, которое используется Paint, но не GIMP), но в остальном изображение было правильным.

Чтобы усилить утверждение в вопросе и существующий ответ, я нашел документ ( http://www.martinreddy.net/gfx/2d/BMP.txt), который содержит определенную спецификацию формата BMP.

Как ни странно, там показан тот же пример, за исключением того, что добавлен правильный байт заполнения (ниже цитата):

Absolute mode is signaled by the first byte in the pair being set to zero and
the second byte to a value between 0x03 and 0xFF. The second byte represents
the number of bytes that follow, each of which contains the color index of a
single pixel. Each run must be aligned on a word boundary.  Following is an
example of an 8-bit RLE bitmap (the two-digit hexadecimal values in the
second column represent a color index for a single pixel):

Compressed data     Expanded data

03 04               04 04 04 
05 06               06 06 06 06 06 
00 03 45 56 67 00   45 56 67 
02 78               78 78 
00 02 05 01         Move 5 right and 1 down 
02 78               78 78 
00 00               End of line 
09 1E               1E 1E 1E 1E 1E 1E 1E 1E 1E 
00 01               End of RLE bitmap 

Я только что на создал запросперенос этой проблемы, и она была исправлена.

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