Hmm, looks sort of like this:
write a header and palette
save position of the size field
save position of dataStart field
write image contents
if compression is RLE4 or RLE8, write the EOF marker 0x0001
pad the current position to a multiple of 4 (writing bytes of zero), save that position as EOF
seek back to beginning of file+2 and write the EOF position DWORD as the total file size
seek to the size field position and write (EOF - dataStart) as the image size DWORD
There are also a few notes in the code about observations that most BMP implementations just ignore the size fields.
I think it should be:
"...pad the size of data to a multiple of 4..."
"...pad the current position to a multiple of 4..."
By "data" I mean the Pixel Array (a.k.a. "image contents" including the RLE end marker 0x0001).
Padding the size value and failing to write bytes for that adjusted size could cause problems.
That's why we pad the position by writing zeros.
I never meant to suggest the omission of padding the data with zeros.
Also, I did not suggest solely rounding up the value of BITMAP*INFOHEADER.biSizeImage member to the multiple of 4 bytes.
I suggested rounding up the size of "data" to the the multiple of 4 bytes.
This is accomplished by padding the "data" with zeros as needed to reach this desired size.
The distinction is between "rounding up the size of data" and "rounding up the position of data's end".
Both are accomplished by padding the "data" with zeros as needed.
For the purpose of calculating BITMAPFILEHEADER.bfSize, the BITMAP*INFOHEADER.biSizeImage member should reflect the exact size of the "data" (including the padding zeros).
Again, we extend the data to a multiple of 4, and account for that in the size.
You suggested what I already said we did...
If that was the case then the 0x1000 bytes of "data" in my example would not have been extended to 0x1002, because 0x1000 was already a multiple of 4 bytes.
It seems as if you are rounding up the offset of the data's end - not the data size. A significant difference.
Worst case, you can play with different size images or image content to see exactly what we're doing.
And what we're doing has been working well with other apps for about 18 years now.
After playing with different "data" sizes I can conclude that the Filesize, Datasize, BITMAP*INFOHEADER.biSizeImage and BITMAPFILEHEADER.bfSize are off by 1..3 bytes, when the OFFSET OF THE END of "data" is not a multiple of 4.
Also, the data's size (incl. padding) is often not a multiple of 4, because the offset of data's end is being rounded up, instead of its size.
The ubiquity of wrong does not make it right.