[Concept,01/18] test: video: Fix 16bpp BMP pixel format conversion

Message ID 20251010034255.1099728-2-sjg@u-boot.org
State New
Headers
Series expo: Extend the boot menu |

Commit Message

Simon Glass Oct. 10, 2025, 3:42 a.m. UTC
  From: Simon Glass <sjg@chromium.org>

The video_write_bmp() function was writing 16bpp framebuffer data
directly to BMP files without proper format conversion. The framebuffer
uses RGB565 format (5 red, 6 green, 5 blue), but standard Windows BMP
16bpp format uses RGB555 (5 red, 5 green, 5 blue).

Convert pixels from RGB565 to RGB555 by:
- Extracting the 5-bit red, 6-bit green, and 5-bit blue components
- Dropping the LSB of the green channel to convert from 6 to 5 bits
- Reconstructing as RGB555 with the same R/B order

This fixes incorrect colors in BMP output files (e.g., orange appearing
as blue).

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

 test/dm/video.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)
  

Patch

diff --git a/test/dm/video.c b/test/dm/video.c
index b06facec6e1..e51ff7789c7 100644
--- a/test/dm/video.c
+++ b/test/dm/video.c
@@ -70,7 +70,7 @@  static int video_write_bmp(struct unit_test_state *uts, struct udevice *dev,
 	void *bmp_data;
 	int ret, y;
 
-	/* Support 16bpp and 32bpp */
+	/* Support 16bpp (converted to 15bpp for BMP) and 32bpp */
 	switch (priv->bpix) {
 	case VIDEO_BPP16:
 		bpp = 16;
@@ -112,7 +112,24 @@  static int video_write_bmp(struct unit_test_state *uts, struct udevice *dev,
 		void *src = priv->fb + (height - 1 - y) * priv->line_length;
 		void *dst = bmp_data + y * row_bytes;
 
-		memcpy(dst, src, width * bytes_per_pixel);
+		if (bpp == 16) {
+			/* Convert RGB565 to RGB555 for BMP format */
+			u16 *src16 = (u16 *)src;
+			u16 *dst16 = (u16 *)dst;
+			int x;
+
+			for (x = 0; x < width; x++) {
+				u16 pixel = src16[x];
+				/* Extract RGB565 components */
+				u16 r = (pixel >> 11) & 0x1f;  /* 5 bits */
+				u16 g = (pixel >> 5) & 0x3f;   /* 6 bits */
+				u16 b = pixel & 0x1f;          /* 5 bits */
+				/* Convert to RGB555: drop LSB of green */
+				dst16[x] = (r << 10) | ((g >> 1) << 5) | b;
+			}
+		} else {
+			memcpy(dst, src, width * bytes_per_pixel);
+		}
 	}
 
 	ret = os_write_file(fname, bmp, bmp_size);