video: bmp: Update RLE8 support to use the write function
Update this code to use write_pix8() rather than writing the pixels only for a single supported display depth. This allows us to support any depth. Add some more tests too. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
51f92c1430
commit
646e169aa0
@ -67,28 +67,37 @@ static void write_pix8(u8 *fb, uint bpix, struct bmp_color_table_entry *palette,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VIDEO_BMP_RLE8
|
||||
static void draw_unencoded_bitmap(ushort **fbp, uchar *bmap, ushort *cmap,
|
||||
static void draw_unencoded_bitmap(u8 **fbp, uint bpix, uchar *bmap,
|
||||
struct bmp_color_table_entry *palette,
|
||||
int cnt)
|
||||
{
|
||||
u8 *fb = *fbp;
|
||||
|
||||
while (cnt > 0) {
|
||||
*(*fbp)++ = cmap[*bmap++];
|
||||
write_pix8(fb, bpix, palette, bmap++);
|
||||
fb += bpix / 8;
|
||||
cnt--;
|
||||
}
|
||||
*fbp = fb;
|
||||
}
|
||||
|
||||
static void draw_encoded_bitmap(ushort **fbp, ushort col, int cnt)
|
||||
static void draw_encoded_bitmap(u8 **fbp, uint bpix,
|
||||
struct bmp_color_table_entry *palette, u8 *bmap,
|
||||
int cnt)
|
||||
{
|
||||
ushort *fb = *fbp;
|
||||
u8 *fb = *fbp;
|
||||
|
||||
while (cnt > 0) {
|
||||
*fb++ = col;
|
||||
write_pix8(fb, bpix, palette, bmap);
|
||||
fb += bpix / 8;
|
||||
cnt--;
|
||||
}
|
||||
*fbp = fb;
|
||||
}
|
||||
|
||||
static void video_display_rle8_bitmap(struct udevice *dev,
|
||||
struct bmp_image *bmp, ushort *cmap,
|
||||
struct bmp_image *bmp, uint bpix,
|
||||
struct bmp_color_table_entry *palette,
|
||||
uchar *fb, int x_off, int y_off,
|
||||
ulong width, ulong height)
|
||||
{
|
||||
@ -97,6 +106,7 @@ static void video_display_rle8_bitmap(struct udevice *dev,
|
||||
ulong cnt, runlen;
|
||||
int x, y;
|
||||
int decode = 1;
|
||||
uint bytes_per_pixel = bpix / 8;
|
||||
|
||||
debug("%s\n", __func__);
|
||||
bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
|
||||
@ -112,8 +122,8 @@ static void video_display_rle8_bitmap(struct udevice *dev,
|
||||
bmap += 2;
|
||||
x = 0;
|
||||
y--;
|
||||
/* 16bpix, 2-byte per pixel, width should *2 */
|
||||
fb -= (width * 2 + priv->line_length);
|
||||
fb -= width * bytes_per_pixel +
|
||||
priv->line_length;
|
||||
break;
|
||||
case BMP_RLE8_EOBMP:
|
||||
/* end of bitmap */
|
||||
@ -123,9 +133,9 @@ static void video_display_rle8_bitmap(struct udevice *dev,
|
||||
/* delta run */
|
||||
x += bmap[2];
|
||||
y -= bmap[3];
|
||||
/* 16bpix, 2-byte per pixel, x should *2 */
|
||||
fb = (uchar *)(priv->fb + (y + y_off - 1)
|
||||
* priv->line_length + (x + x_off) * 2);
|
||||
fb = (uchar *)(priv->fb +
|
||||
(y + y_off - 1) * priv->line_length +
|
||||
(x + x_off) * bytes_per_pixel);
|
||||
bmap += 4;
|
||||
break;
|
||||
default:
|
||||
@ -139,8 +149,8 @@ static void video_display_rle8_bitmap(struct udevice *dev,
|
||||
else
|
||||
cnt = runlen;
|
||||
draw_unencoded_bitmap(
|
||||
(ushort **)&fb,
|
||||
bmap, cmap, cnt);
|
||||
&fb, bpix,
|
||||
bmap, palette, cnt);
|
||||
}
|
||||
x += runlen;
|
||||
}
|
||||
@ -164,8 +174,8 @@ static void video_display_rle8_bitmap(struct udevice *dev,
|
||||
cnt = width - x;
|
||||
else
|
||||
cnt = runlen;
|
||||
draw_encoded_bitmap((ushort **)&fb,
|
||||
cmap[bmap[1]], cnt);
|
||||
draw_encoded_bitmap(&fb, bpix, palette,
|
||||
&bmap[1], cnt);
|
||||
}
|
||||
x += runlen;
|
||||
}
|
||||
@ -311,13 +321,8 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
|
||||
u32 compression = get_unaligned_le32(&bmp->header.compression);
|
||||
debug("compressed %d %d\n", compression, BMP_BI_RLE8);
|
||||
if (compression == BMP_BI_RLE8) {
|
||||
if (bpix != 16) {
|
||||
/* TODO implement render code for bpix != 16 */
|
||||
printf("Error: only support 16 bpix");
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
video_display_rle8_bitmap(dev, bmp, cmap_base, fb, x,
|
||||
y, width, height);
|
||||
video_display_rle8_bitmap(dev, bmp, bpix, palette, fb,
|
||||
x, y, width, height);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -373,6 +373,44 @@ static int dm_test_video_bmp_comp(struct unit_test_state *uts)
|
||||
}
|
||||
DM_TEST(dm_test_video_bmp_comp, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
|
||||
|
||||
/* Test drawing a bitmap file on a 32bpp display */
|
||||
static int dm_test_video_comp_bmp32(struct unit_test_state *uts)
|
||||
{
|
||||
struct udevice *dev;
|
||||
ulong addr;
|
||||
|
||||
ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
|
||||
ut_assertnonnull(dev);
|
||||
ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP32));
|
||||
|
||||
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
|
||||
|
||||
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
|
||||
ut_asserteq(2024, compress_frame_buffer(uts, dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_video_comp_bmp32, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
|
||||
|
||||
/* Test drawing a bitmap file on a 8bpp display */
|
||||
static int dm_test_video_comp_bmp8(struct unit_test_state *uts)
|
||||
{
|
||||
struct udevice *dev;
|
||||
ulong addr;
|
||||
|
||||
ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev));
|
||||
ut_assertnonnull(dev);
|
||||
ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP8));
|
||||
|
||||
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
|
||||
|
||||
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
|
||||
ut_asserteq(1247, compress_frame_buffer(uts, dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_video_comp_bmp8, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
|
||||
|
||||
/* Test TrueType console */
|
||||
static int dm_test_video_truetype(struct unit_test_state *uts)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user