On Sun, 2 Nov 2025, Chad Jablonski wrote:
Convert 1bpp monochrome images to 32bpp ARGB given a foreground and
background color. This also supports most significant and least
significant bit ordering.

This is useful for host data transfers of glyphs when drawing text in X.

Signed-off-by: Chad Jablonski <[email protected]>
---
hw/display/ati_2d.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)

diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c
index 15cf29a061..181bf634f0 100644
--- a/hw/display/ati_2d.c
+++ b/hw/display/ati_2d.c
@@ -45,6 +45,28 @@ static int ati_bpp_from_datatype(ATIVGAState *s)
}

#define DEFAULT_CNTL (s->regs.dp_gui_master_cntl & GMC_DST_PITCH_OFFSET_CNTL)
+/* Convert 1bpp monochrome data to 32bpp ARGB using color expansion */
+static void expand_colors(uint8_t *color_dst, const uint8_t *mono_src,
+                          uint32_t width, uint32_t height,
+                          uint32_t fg_color, uint32_t bg_color,
+                          bool lsb_to_msb)
+{
+    uint32_t byte, color;
+    uint8_t *pixel;
+    int i, j, bit;
+    /* Rows are 32-bit aligned */
+    int bytes_per_row = ((width + 31) / 32) * 4;

I think there's some QEMU_ALIGN macro for that maybe in qemu/osdep.h?

+
+    for (i = 0; i < height; i++) {
+        for (j = 0; j < width; j++) {
+            byte = mono_src[i * bytes_per_row + (j / 8)];
+            bit = lsb_to_msb ? 7 - (j % 8) : j % 8;
+            color = (byte >> bit) & 0x1 ? fg_color : bg_color;
+            pixel = &color_dst[(i * width + j) * 4];
+            memcpy(pixel, &color, sizeof(color));

Since it's just writing a 32 bit value maybe cast and = would be faster than calling memcpy for this.

Regards,
BALATON Zoltan

+        }
+    }
+}

void ati_2d_blt(ATIVGAState *s)
{


Reply via email to