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)
{