Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Align with word boundary in RLE bitmap: contradiction in Microsoft documentation

Microsoft's Bitmap Compression documentation, specifically the description of BI_RLE8 (8-bit indexed color using run-length encoding compression), includes the following description of absolute mode:

In absolute mode, the first byte is zero and the second byte is a value in the range 03H through FFH. The second byte represents the number of bytes that follow, each of which contains the color index [into a color table] of a single pixel. [...] In absolute mode, each run must be aligned on a word boundary.

Presumably, this means that runs with an odd-numbered length must be zero-padded (although not specified, I assume words are 16 bits long in this context).

However, the example in the documentation includes a run with an odd-numbered length that doesn't end on a word boundary:

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

Should 00 03 45 56 67 be 00 03 45 56 67 00?

like image 632
Reign of Error Avatar asked Mar 08 '23 00:03

Reign of Error


1 Answers

I modified an 8-bit indexed color bitmap and the results appears to indicate that runs should indeed be zero-padded to end on a 16-bit word boundary (so 00 03 45 56 67 should be 00 03 45 56 67 00).

Details:

  • In Microsoft Paint (version 1607, included with Windows 10), I created a 4x4 bitmap containing red (R), green (G), and blue (B) pixels in the following arrangement:

    BRBR
    BBBB
    GGBB
    RRRG
    
  • I saved the file as a 256-color bitmap (there was no option to use indexed color or run-length encoding).
  • I opened the file in the Gnu Image Manipulation Program (GIMP), changed the color mode to indexed (via Image > Mode > Indexed), and exported it as a "Windows BMP", checking off the "Run-Length Encoded" option.
  • I made a copy of the file and opened it in HxD (a hex editor).
  • At this stage, the pixel data were represented as follows (note that, per the documentation, the image starts in the bottom-left and proceeds left to right):

    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
    
  • At the start of the pixel data region, I replaced 03 4F (three red pixels specified in encoded mode; note that red was mapped to index 0x4F = 79 in the color table) with 00 03 4F 4F 4F (three red pixels specified in absolute mode with no zero padding), updated the file size in the header, and saved the changes.
  • When opened in both GIMP and Paint, the modified file was rendered incorrectly: the pixels in the first two rows and the bottom-right pixel were black, and the last two pixels in the third row were green instead of blue.
  • In HxD, I changed the 00 03 4F 4F 4F to 00 03 4F 4F 4F 00 (three red pixels specified in absolute mode, with a zero byte added to end the run on a 16-bit word boundary), updated the file size in the header, and saved the file.
  • When opened in GIMP, the file was now rendered correctly. When opened in Paint, the top row was black (I suspect I neglected to update a header field that is used by Paint but not GIMP), but otherwise the image was correct.
like image 99
Reign of Error Avatar answered Mar 10 '23 15:03

Reign of Error