// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2015 Google, Inc
 */

#include <common.h>
#include <bmp_layout.h>
#include <dm.h>
#include <log.h>
#include <mapmem.h>
#include <splash.h>
#include <video.h>
#include <watchdog.h>
#include <asm/unaligned.h>

#define BMP_RLE8_ESCAPE		0
#define BMP_RLE8_EOL		0
#define BMP_RLE8_EOBMP		1
#define BMP_RLE8_DELTA		2

/**
 * get_bmp_col_16bpp() - Convert a colour-table entry into a 16bpp pixel value
 *
 * @return value to write to the 16bpp frame buffer for this palette entry
 */
static uint get_bmp_col_16bpp(struct bmp_color_table_entry cte)
{
	return ((cte.red   << 8) & 0xf800) |
		((cte.green << 3) & 0x07e0) |
		((cte.blue  >> 3) & 0x001f);
}

/**
 * write_pix8() - Write a pixel from a BMP image into the framebuffer
 *
 * This handles frame buffers with 8, 16, 24 or 32 bits per pixel
 *
 * @fb: Place in frame buffer to update
 * @bpix: Frame buffer bits-per-pixel, which controls how many bytes are written
 * @palette: BMP palette table
 * @bmap: Pointer to BMP bitmap position to write. This contains a single byte
 *	which is either written directly (bpix == 8) or used to look up the
 *	palette to get a colour to write
 */
static void write_pix8(u8 *fb, uint bpix, struct bmp_color_table_entry *palette,
		       u8 *bmap)
{
	if (bpix == 8) {
		*fb++ = *bmap;
	} else if (bpix == 16) {
		*(u16 *)fb = get_bmp_col_16bpp(palette[*bmap]);
	} else {
		/* Only support big endian */
		struct bmp_color_table_entry *cte = &palette[*bmap];

		if (bpix == 24) {
			*fb++ = cte->red;
			*fb++ = cte->green;
			*fb++ = cte->blue;
		} else {
			*fb++ = cte->blue;
			*fb++ = cte->green;
			*fb++ = cte->red;
			*fb++ = 0;
		}
	}
}

#ifdef CONFIG_VIDEO_BMP_RLE8
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) {
		write_pix8(fb, bpix, palette, bmap++);
		fb += bpix / 8;
		cnt--;
	}
	*fbp = fb;
}

static void draw_encoded_bitmap(u8 **fbp, uint bpix,
				struct bmp_color_table_entry *palette, u8 *bmap,
				int cnt)
{
	u8 *fb = *fbp;

	while (cnt > 0) {
		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, uint bpix,
				      struct bmp_color_table_entry *palette,
				      uchar *fb, int x_off, int y_off,
				      ulong width, ulong height)
{
	struct video_priv *priv = dev_get_uclass_priv(dev);
	uchar *bmap;
	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);

	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--;
				fb -= width * bytes_per_pixel +
					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];
				fb = (uchar *)(priv->fb +
					(y + y_off - 1) * priv->line_length +
					(x + x_off) * bytes_per_pixel);
				bmap += 4;
				break;
			default:
				/* unencoded run */
				runlen = bmap[1];
				bmap += 2;
				if (y < height) {
					if (x < width) {
						if (x + runlen > width)
							cnt = width - x;
						else
							cnt = runlen;
						draw_unencoded_bitmap(
							&fb, bpix,
							bmap, palette, cnt);
					}
					x += runlen;
				}
				bmap += runlen;
				if (runlen & 1)
					bmap++;
			}
		} else {
			/* encoded run */
			if (y < height) {
				runlen = bmap[0];
				if (x < width) {
					/* aggregate the same code */
					while (bmap[0] == 0xff &&
					       bmap[2] != BMP_RLE8_ESCAPE &&
					       bmap[1] == bmap[3]) {
						runlen += bmap[2];
						bmap += 2;
					}
					if (x + runlen > width)
						cnt = width - x;
					else
						cnt = runlen;
					draw_encoded_bitmap(&fb, bpix, palette,
							    &bmap[1], cnt);
				}
				x += runlen;
			}
			bmap += 2;
		}
	}
}
#endif

/**
 * video_splash_align_axis() - Align a single coordinate
 *
 *- if a coordinate is 0x7fff then the image will be centred in
 *  that direction
 *- if a coordinate is -ve then it will be offset to the
 *  left/top of the centre by that many pixels
 *- if a coordinate is positive it will be used unchnaged.
 *
 * @axis:	Input and output coordinate
 * @panel_size:	Size of panel in pixels for that axis
 * @picture_size:	Size of bitmap in pixels for that axis
 */
static void video_splash_align_axis(int *axis, unsigned long panel_size,
				    unsigned long picture_size)
{
	long panel_picture_delta = panel_size - picture_size;
	long axis_alignment;

	if (*axis == BMP_ALIGN_CENTER)
		axis_alignment = panel_picture_delta / 2;
	else if (*axis < 0)
		axis_alignment = panel_picture_delta + *axis + 1;
	else
		return;

	*axis = max(0, (int)axis_alignment);
}

int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
		      bool align)
{
	struct video_priv *priv = dev_get_uclass_priv(dev);
	int i, j;
	uchar *start, *fb;
	struct bmp_image *bmp = map_sysmem(bmp_image, 0);
	uchar *bmap;
	ushort padded_width;
	unsigned long width, height, byte_width;
	unsigned long pwidth = priv->xsize;
	unsigned colours, bpix, bmp_bpix;
	struct bmp_color_table_entry *palette;
	int hdr_size;
	int ret;

	if (!bmp || !(bmp->header.signature[0] == 'B' &&
	    bmp->header.signature[1] == 'M')) {
		printf("Error: no valid bmp image at %lx\n", bmp_image);

		return -EINVAL;
	}

	width = get_unaligned_le32(&bmp->header.width);
	height = get_unaligned_le32(&bmp->header.height);
	bmp_bpix = get_unaligned_le16(&bmp->header.bit_count);
	hdr_size = get_unaligned_le16(&bmp->header.size);
	debug("hdr_size=%d, bmp_bpix=%d\n", hdr_size, bmp_bpix);
	palette = (void *)bmp + 14 + hdr_size;

	colours = 1 << bmp_bpix;

	bpix = VNBITS(priv->bpix);

	if (bpix != 1 && bpix != 8 && bpix != 16 && bpix != 32) {
		printf("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
		       bpix, bmp_bpix);

		return -EINVAL;
	}

	/*
	 * We support displaying 8bpp and 24bpp BMPs on 16bpp LCDs
	 * and displaying 24bpp BMPs on 32bpp LCDs
	 */
	if (bpix != bmp_bpix &&
	    !(bmp_bpix == 8 && bpix == 16) &&
	    !(bmp_bpix == 8 && bpix == 24) &&
	    !(bmp_bpix == 8 && bpix == 32) &&
	    !(bmp_bpix == 24 && bpix == 16) &&
	    !(bmp_bpix == 24 && bpix == 32)) {
		printf("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
		       bpix, get_unaligned_le16(&bmp->header.bit_count));
		return -EPERM;
	}

	debug("Display-bmp: %d x %d  with %d colours, display %d\n",
	      (int)width, (int)height, (int)colours, 1 << bpix);

	padded_width = (width & 0x3 ? (width & ~0x3) + 4 : width);

	if (align) {
		video_splash_align_axis(&x, priv->xsize, width);
		video_splash_align_axis(&y, priv->ysize, height);
	}

	if ((x + width) > pwidth)
		width = pwidth - x;
	if ((y + height) > priv->ysize)
		height = priv->ysize - y;

	bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
	start = (uchar *)(priv->fb +
		(y + height) * priv->line_length + x * bpix / 8);

	/* Move back to the final line to be drawn */
	fb = start - priv->line_length;

	switch (bmp_bpix) {
	case 1:
	case 8: {
#ifdef CONFIG_VIDEO_BMP_RLE8
		u32 compression = get_unaligned_le32(&bmp->header.compression);
		debug("compressed %d %d\n", compression, BMP_BI_RLE8);
		if (compression == BMP_BI_RLE8) {
			video_display_rle8_bitmap(dev, bmp, bpix, palette, fb,
						  x, y, width, height);
			break;
		}
#endif
		byte_width = width * (bpix / 8);
		if (!byte_width)
			byte_width = width;

		for (i = 0; i < height; ++i) {
			WATCHDOG_RESET();
			for (j = 0; j < width; j++) {
				write_pix8(fb, bpix, palette, bmap);
				bmap++;
				fb += bpix / 8;
			}
			bmap += (padded_width - width);
			fb -= byte_width + priv->line_length;
		}
		break;
	}
#if defined(CONFIG_BMP_16BPP)
	case 16:
		for (i = 0; i < height; ++i) {
			WATCHDOG_RESET();
			for (j = 0; j < width; j++) {
				*fb++ = *bmap++;
				*fb++ = *bmap++;
			}
			bmap += (padded_width - width);
			fb -= width * 2 + priv->line_length;
		}
		break;
#endif /* CONFIG_BMP_16BPP */
#if defined(CONFIG_BMP_24BPP)
	case 24:
		for (i = 0; i < height; ++i) {
			for (j = 0; j < width; j++) {
				if (bpix == 16) {
					/* 16bit 555RGB format */
					*(u16 *)fb = ((bmap[2] >> 3) << 10) |
						((bmap[1] >> 3) << 5) |
						(bmap[0] >> 3);
					bmap += 3;
					fb += 2;
				} else {
					*fb++ = *bmap++;
					*fb++ = *bmap++;
					*fb++ = *bmap++;
					*fb++ = 0;
				}
			}
			fb -= priv->line_length + width * (bpix / 8);
			bmap += (padded_width - width);
		}
		break;
#endif /* CONFIG_BMP_24BPP */
#if defined(CONFIG_BMP_32BPP)
	case 32:
		for (i = 0; i < height; ++i) {
			for (j = 0; j < width; j++) {
				*fb++ = *bmap++;
				*fb++ = *bmap++;
				*fb++ = *bmap++;
				*fb++ = *bmap++;
			}
			fb -= priv->line_length + width * (bpix / 8);
		}
		break;
#endif /* CONFIG_BMP_32BPP */
	default:
		break;
	};

	/* Find the position of the top left of the image in the framebuffer */
	fb = (uchar *)(priv->fb + y * priv->line_length + x * bpix / 8);
	ret = video_sync_copy(dev, start, fb);
	if (ret)
		return log_ret(ret);

	return video_sync(dev, false);
}
