feat: Add 4bit bmp support#944
Conversation
|
No actionable comments were generated in the recent review. 🎉 📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used🧬 Code graph analysis (1)lib/GfxRenderer/Bitmap.cpp (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
🔇 Additional comments (7)
📝 WalkthroughWalkthroughAdds 4‑bpp BMP decoding support, palette luminance handling with native‑palette detection (skips dithering when palette maps to the display's 4 gray levels), conditional dithering paths (none / quantize / Atkinson / Floyd‑Steinberg), and a new script to generate BMP test images across bit depths. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
lib/GfxRenderer/Bitmap.cpplib/GfxRenderer/Bitmap.hscripts/generate_test_bmps.py
🧰 Additional context used
🧬 Code graph analysis (1)
lib/GfxRenderer/Bitmap.cpp (1)
lib/GfxRenderer/BitmapHelpers.cpp (4)
quantize(84-90)quantize(84-84)adjustPixel(40-51)adjustPixel(40-40)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build
- GitHub Check: cppcheck
🔇 Additional comments (13)
scripts/generate_test_bmps.py (7)
36-59: BMP header/palette helpers look solid.
Little‑endian packing and BI_RGB header fields are consistent for test output.
62-134: Pattern generators are well‑suited for dithering inspection.
The band layout and intermediate luminance values should expose artifacts clearly.
137-214: 1/2/4‑bit generators handle packing and padding correctly.
Row byte alignment and palette indexing look consistent with BMP specs.
217-260: 8‑bit generators align palette sizes with intent.
colorsUsedand palette entries match both the 4‑color and 256‑color cases.
263-285: 24‑bit generator writes correct BGR ordering with padding.
287-325: Main routine is clear and provides helpful usage guidance.
328-329: Standard entrypoint guard.lib/GfxRenderer/Bitmap.h (1)
59-65: Private palette‑tracking additions are appropriate.
They keep palette state encapsulated for the new parsing logic.lib/GfxRenderer/Bitmap.cpp (5)
7-12: Processing‑mode documentation is clear.
61-63: Error message now reflects 4bpp support.
108-119: 4bpp validation and default palette sizing look correct.
200-206: Direct‑mapping path for native palettes is clean.
246-252: 4bpp nibble unpacking looks correct.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@lib/GfxRenderer/Bitmap.cpp`:
- Around line 147-168: The native-palette detection currently skips the
luminance check for palettes larger than 4 entries due to the "colorsUsed <= 4"
guard; remove that constraint so the loop that examines paletteLum[] runs for
any colorsUsed > 0 (still keep bpp <= 2 auto-native behavior). Concretely,
update the logic around nativePalette (the branch that sets nativePalette = true
and iterates over paletteLum[i]) to omit the colorsUsed <= 4 requirement,
ensuring the quantization check (lum >> 6, reconstructed, ±21 threshold) runs
for all palette sizes so highColor is computed correctly.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
lib/GfxRenderer/Bitmap.cpp
🧰 Additional context used
🧬 Code graph analysis (1)
lib/GfxRenderer/Bitmap.cpp (1)
lib/GfxRenderer/BitmapHelpers.cpp (4)
quantize(84-90)quantize(84-84)adjustPixel(40-51)adjustPixel(40-40)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: cppcheck
- GitHub Check: build
🔇 Additional comments (5)
lib/GfxRenderer/Bitmap.cpp (5)
7-12: Processing-path documentation matches new behavior.Clear and accurate description of the native-palette/direct-mapping behavior.
62-62: UnsupportedBpp message now reflects 4bpp support.
108-118: colorsUsed defaulting for paletted formats looks correct.The
colorsUsed == 0fallback to1u << bppkeeps BMP palette handling aligned with spec.
147-176: Native-palette detection and ditherer initialization look consistent.
246-252: 4bpp nibble unpacking matches BMP pixel order.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@lib/GfxRenderer/Bitmap.cpp`:
- Around line 200-206: The native-palette branch currently computes color as
static_cast<uint8_t>(lum >> 6) and bypasses global pixel adjustments; change it
to apply adjustPixel before shifting so it matches other paths (use color =
static_cast<uint8_t>(adjustPixel(lum, currentX, prevRowY) >> 6) or equivalent).
Update the branch that checks nativePalette to call adjustPixel(lum, currentX,
prevRowY) prior to the >> 6 shift so nativePalette, ditherers, and quantize all
use the same brightness/contrast/gamma adjustments.
## Summary * What is the goal of this PR? - Allow users to create custom sleep screen images with standard tools (ImageMagick, GIMP, etc.) that render cleanly on the e-ink display without dithering artifacts. Previously, avoiding dithering required non-standard 2-bit BMPs that no standard image editor can produce. ( see issue crosspoint-reader#931 ) * What changes are included? - Add 4-bit BMP format support to Bitmap.cpp (standard format, widely supported by image tools) - Auto-detect "native palette" images: if a BMP has ≤4 palette entries and all luminances map within ±21 of the display's native gray levels (0, 85, 170, 255), skip dithering entirely and direct-map pixels - Clarify pixel processing strategy with three distinct paths: error-diffusion dithering, simple quantization, or direct mapping - Add scripts/generate_test_bmps.py for generating test images across all supported BMP formats ## Additional Context * The e-ink display has 4 native gray levels. When a BMP already uses exactly those levels, dithering adds noise to what should be clean output. The native palette detection uses a ±21 tolerance (~10%) to handle slight rounding from color space conversions in image tools. Users can now create a 4-color grayscale BMP with (imagemagic example): ``` convert input.png -colorspace Gray -colors 4 -depth ``` --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _** YES**_
## Summary * What is the goal of this PR? - Allow users to create custom sleep screen images with standard tools (ImageMagick, GIMP, etc.) that render cleanly on the e-ink display without dithering artifacts. Previously, avoiding dithering required non-standard 2-bit BMPs that no standard image editor can produce. ( see issue crosspoint-reader#931 ) * What changes are included? - Add 4-bit BMP format support to Bitmap.cpp (standard format, widely supported by image tools) - Auto-detect "native palette" images: if a BMP has ≤4 palette entries and all luminances map within ±21 of the display's native gray levels (0, 85, 170, 255), skip dithering entirely and direct-map pixels - Clarify pixel processing strategy with three distinct paths: error-diffusion dithering, simple quantization, or direct mapping - Add scripts/generate_test_bmps.py for generating test images across all supported BMP formats ## Additional Context * The e-ink display has 4 native gray levels. When a BMP already uses exactly those levels, dithering adds noise to what should be clean output. The native palette detection uses a ±21 tolerance (~10%) to handle slight rounding from color space conversions in image tools. Users can now create a 4-color grayscale BMP with (imagemagic example): ``` convert input.png -colorspace Gray -colors 4 -depth ``` --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _** YES**_
## Summary * What is the goal of this PR? - Allow users to create custom sleep screen images with standard tools (ImageMagick, GIMP, etc.) that render cleanly on the e-ink display without dithering artifacts. Previously, avoiding dithering required non-standard 2-bit BMPs that no standard image editor can produce. ( see issue crosspoint-reader#931 ) * What changes are included? - Add 4-bit BMP format support to Bitmap.cpp (standard format, widely supported by image tools) - Auto-detect "native palette" images: if a BMP has ≤4 palette entries and all luminances map within ±21 of the display's native gray levels (0, 85, 170, 255), skip dithering entirely and direct-map pixels - Clarify pixel processing strategy with three distinct paths: error-diffusion dithering, simple quantization, or direct mapping - Add scripts/generate_test_bmps.py for generating test images across all supported BMP formats ## Additional Context * The e-ink display has 4 native gray levels. When a BMP already uses exactly those levels, dithering adds noise to what should be clean output. The native palette detection uses a ±21 tolerance (~10%) to handle slight rounding from color space conversions in image tools. Users can now create a 4-color grayscale BMP with (imagemagic example): ``` convert input.png -colorspace Gray -colors 4 -depth ``` --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _** YES**_
Summary
What is the goal of this PR?
What changes are included?
Additional Context
Users can now create a 4-color grayscale BMP with (imagemagic example):
AI Usage
While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it
helps set the right context for reviewers.
Did you use AI tools to help write this code? ** YES**