This command can use the bitmap display code in the uclass. This is similar
to the code in lcd.c and cfb_console.c. These other copies will go away when
all boards are converted to use driver model for video.
Signed-off-by: Simon Glass
Acked-by: Anatolij Gustschin
---
Changes in v2: None
common/cmd_bmp.c | 22 ++-
drivers/video/Makefile| 1 +
drivers/video/video_bmp.c | 353 ++
3 files changed, 375 insertions(+), 1 deletion(-)
create mode 100644 drivers/video/video_bmp.c
diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c
index f04b7d4..fd5b7db 100644
--- a/common/cmd_bmp.c
+++ b/common/cmd_bmp.c
@@ -10,7 +10,9 @@
*/
#include
+#include
#include
+#include
#include
#include
#include
@@ -225,6 +227,9 @@ static int bmp_info(ulong addr)
*/
int bmp_display(ulong addr, int x, int y)
{
+#ifdef CONFIG_DM_VIDEO
+ struct udevice *dev;
+#endif
int ret;
struct bmp_image *bmp = map_sysmem(addr, 0);
void *bmp_alloc_addr = NULL;
@@ -240,7 +245,22 @@ int bmp_display(ulong addr, int x, int y)
}
addr = map_to_sysmem(bmp);
-#if defined(CONFIG_LCD)
+#ifdef CONFIG_DM_VIDEO
+ ret = uclass_first_device(UCLASS_VIDEO, &dev);
+ if (!ret) {
+ if (!dev)
+ ret = -ENODEV;
+ if (!ret) {
+ bool align = false;
+
+# ifdef CONFIG_SPLASH_SCREEN_ALIGN
+ align = true;
+# endif /* CONFIG_SPLASH_SCREEN_ALIGN */
+ ret = video_bmp_display(dev, addr, x, y, align);
+ }
+ }
+ return ret ? CMD_RET_FAILURE : 0;
+#elif defined(CONFIG_LCD)
ret = lcd_display_bitmap(addr, x, y);
#elif defined(CONFIG_VIDEO)
ret = video_display_bitmap(addr, x, y);
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 8f26d1d..ee04629 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -8,6 +8,7 @@
ifdef CONFIG_DM
obj-$(CONFIG_DISPLAY_PORT) += dp-uclass.o
obj-$(CONFIG_DM_VIDEO) += video-uclass.o vidconsole-uclass.o console_normal.o
+obj-$(CONFIG_DM_VIDEO) += video_bmp.o
obj-$(CONFIG_VIDEO_ROTATION) += console_rotate.o
endif
diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c
new file mode 100644
index 000..c9075d6
--- /dev/null
+++ b/drivers/video/video_bmp.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef CONFIG_VIDEO_BMP_RLE8
+#define BMP_RLE8_ESCAPE0
+#define BMP_RLE8_EOL 0
+#define BMP_RLE8_EOBMP 1
+#define BMP_RLE8_DELTA 2
+
+static void draw_unencoded_bitmap(ushort **fbp, uchar *bmap, ushort *cmap,
+ int cnt)
+{
+ while (cnt > 0) {
+ *(*fbp)++ = cmap[*bmap++];
+ cnt--;
+ }
+}
+
+static void draw_encoded_bitmap(ushort **fbp, ushort col, int cnt)
+{
+ ushort *fb = *fbp;
+
+ while (cnt > 0) {
+ *fb++ = col;
+ cnt--;
+ }
+ *fbp = fb;
+}
+
+static void video_display_rle8_bitmap(struct udevice *dev,
+ struct bmp_image *bmp, ushort *cmap,
+ uchar *fb, int x_off, int y_off)
+{
+ struct video_priv *priv = dev_get_uclass_priv(dev);
+ uchar *bmap;
+ ulong width, height;
+ ulong cnt, runlen;
+ int x, y;
+ int decode = 1;
+
+ debug("%s\n", __func__);
+ width = get_unaligned_le32(&bmp->header.width);
+ height = get_unaligned_le32(&bmp->header.height);
+ bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
+
+ x = 0;
+ y = height - 1;
+
+ while (decode) {
+ if (bmap[0] == BMP_RLE8_ESCAPE) {
+ switch (bmap[1]) {
+ case BMP_RLE8_EOL:
+ /* end of line */
+ bmap += 2;
+ x = 0;
+ y--;
+ /* 16bpix, 2-byte per pixel, width should *2 */
+ fb -= (width * 2 + priv->line_length);
+ break;
+ case BMP_RLE8_EOBMP:
+ /* end of bitmap */
+ decode = 0;
+ break;
+ case BMP_RLE8_DELTA:
+ /* 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);
+ bmap +=