cd /news/computer-vision/tiny-bmp-icons-look-slanted-check-rg… · home › topics › computer-vision › article
[ARTICLE · art-155618] src=dev.to ↗ pub= topic=computer-vision verified=true sentiment=· neutral

Tiny BMP Icons Look Slanted? Check RGB24 Row Padding

The FrameSprite team published a restricted-profile guide showing that 24-bit uncompressed BMP rows must be advanced by their 4-byte-aligned stride rather than width × 3, since odd widths leave 1–3 padding bytes that, if read as pixels, shift subsequent rows and produce slanted colors in tiny game icons. A Python 3.12.10 checker built original 1-, 2-, 3- and 4-pixel-wide RGB24 fixtures and confirmed round trips plus the padding sequence 1, 2, 3, 0 across five assertions. The team notes the exercise is educational and not a hardened general BMP decoder, pointing readers to Pillow's implementation for production parsing.

by read3 min views3 publishedOct 22, 2026

Disclosure: This article was generated with AI for the FrameSprite team, which has a commercial interest in FrameSprite. It received a separate AI editorial review against the cited sources. Executed synthetic fixtures are identified with their runtime and limits; no other editor, engine, production or performance test is implied.

Advance through a 24-bit uncompressed BMP by its padded row stride, not simply width × 3. A width that does not naturally align to four bytes leaves padding at the end of each row. Treating that padding as pixels shifts every later row and can produce slanted colors in tiny game icons.

Key takeaway: Odd widths are useful parser tests. A four-pixel-wide RGB24 sample can hide a missing-padding bug.

For the restricted RGB24 BMP profile used here:

row_bytes = width * 3
stride = ((row_bytes + 3) // 4) * 4
padding = stride - row_bytes

The BITMAPINFOHEADER documentation explains DIB dimensions and stride. This guide is about uncompressed RGB24 data, not every BMP compression or bit-depth variant.

Width Visible row bytes Stored stride Padding bytes
1 3 4 1
2 6 8 2
3 9 12 3
4 12 12 0

The values come from authored two-row fixtures. The fourth row is a useful control: a broken parser may appear correct at width four while failing the other widths.

Locate the pixel array through the header's offset rather than assuming the image always begins at a hard-coded position. The authored files use a 54-byte header arrangement, but that is a fixture choice. Other BMP variants can include extra structures.

Within each stored row, read only width × 3 visible bytes. For this profile, convert the stored BGR triplets into your chosen canonical RGB representation, then skip the padding before the next row. Handle row orientation separately; adding padding does not decide which stored row is the top of the image.

The Pillow BMP implementation offers a maintained parser reference. Consult its accepted modes and checks instead of extending this small profile into an unbounded decoder.

Before iterating rows, verify that the pixel-data range fits inside the file. Do not let a permissive slice silently shorten the last row. Reject a height, offset or stride that exceeds your declared size and memory limits before allocating an output image.

Pillow's format-support documentation is useful when choosing a maintained decoder rather than maintaining format parsing in a game importer.

Python 3.12.10 constructed original 1-, 2-, 3- and 4-pixel-wide RGB24 BMPs and decoded both rows back into their original pixels. Five assertions in the checker confirmed four round trips and the padding sequence 1, 2, 3, 0. The input and recorded layouts preserve the dimensions.

No engine or external image application was executed. The checker is an educational restricted-format exercise, not a hardened general BMP decoder.

If the file is actually a PNG with damaged chunks, use the PNG CRC diagnosis. If a texture upload has its own pitch, follow the streaming-texture row-pitch guide. If two formats render the same pixels but have different file hashes, use the decoded-pixel identity check.

Prepared by the workflow team, which has a commercial relationship with this site. This guide was drafted with AI assistance; independent editorial review is recorded separately. Report a technical correction with the relevant input, tool version and observed result.

── more in #computer-vision 4 stories · sorted by recency
── more on @framesprite 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/tiny-bmp-icons-look-…] indexed:0 read:3min 2026-10-22 · —