// 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);
}

/**
 * get_bmp_col_x2r10g10b10() - Convert a colour-table entry into a x2r10g10b10  pixel value
 *
 * Return: value to write to the x2r10g10b10 frame buffer for this palette entry
 */
static u32 get_bmp_col_x2r10g10b10(struct bmp_color_table_entry *cte)
{
	return ((cte->red << 22U) |
		(cte->green << 12U) |
		(cte->blue << 2U));
}

/**
 * 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, enum video_format eformat,
		       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 if (eformat == VIDEO_X2R10G10B10) {
			*(u32 *)fb = get_bmp_col_x2r10g10b10(cte);
		} else {
			*fb++ = cte->blue;
			*fb++ = cte->green;
			*fb++ = cte->red;
			*fb++ = 0;
		}
	}
}

static void draw_unencoded_bitmap(u8 **fbp, uint bpix,
				  enum video_format eformat, uchar *bmap,
				  struct bmp_color_table_entry *palette,
				  int cnt)
{
	u8 *fb = *fbp;

	while (cnt > 0) {
		write_pix8(fb, bpix, eformat, palette, bmap++);
		fb += bpix / 8;
		cnt--;
	}
	*fbp = fb;
}

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

	while (cnt > 0) {
		write_pix8(fb, bpix, eformat, 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;
	enum video_format eformat = priv->format;

	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, eformat,
							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, eformat,
							    palette, &bmap[1],
							    cnt);
				}
				x += runlen;
			}
			bmap += 2;
		}
	}
}

/**
 * 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;
	enum video_format eformat;
	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);
	eformat = priv->format;

	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:
		if (IS_ENABLED(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;
			}
		}

		/* Not compressed */
		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, eformat, palette, bmap);
				bmap++;
				fb += bpix / 8;
			}
			bmap += (padded_width - width);
			fb -= byte_width + priv->line_length;
		}
		break;
	case 16:
		if (IS_ENABLED(CONFIG_BMP_16BPP)) {
			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;
	case 24:
		if (IS_ENABLED(CONFIG_BMP_24BPP)) {
			for (i = 0; i < height; ++i) {
				for (j = 0; j < width; j++) {
					if (bpix == 16) {
						/* 16bit 565RGB format */
						*(u16 *)fb = ((bmap[2] >> 3)
							<< 11) |
							((bmap[1] >> 2) << 5) |
							(bmap[0] >> 3);
						bmap += 3;
						fb += 2;
					} else if (eformat == VIDEO_X2R10G10B10) {
						u32 pix;

						pix = *bmap++ << 2U;
						pix |= *bmap++ << 12U;
						pix |= *bmap++ << 22U;
						*fb++ = pix & 0xff;
						*fb++ = (pix >> 8) & 0xff;
						*fb++ = (pix >> 16) & 0xff;
						*fb++ = pix >> 24;
					} else {
						*fb++ = *bmap++;
						*fb++ = *bmap++;
						*fb++ = *bmap++;
						*fb++ = 0;
					}
				}
				fb -= priv->line_length + width * (bpix / 8);
				bmap += (padded_width - width);
			}
		}
		break;
	case 32:
		if (IS_ENABLED(CONFIG_BMP_32BPP)) {
			for (i = 0; i < height; ++i) {
				for (j = 0; j < width; j++) {
					if (eformat == VIDEO_X2R10G10B10) {
						u32 pix;

						pix = *bmap++ << 2U;
						pix |= *bmap++ << 12U;
						pix |= *bmap++ << 22U;
						pix |= (*bmap++ >> 6) << 30U;
						*fb++ = pix & 0xff;
						*fb++ = (pix >> 8) & 0xff;
						*fb++ = (pix >> 16) & 0xff;
						*fb++ = pix >> 24;
					} else {
						*fb++ = *bmap++;
						*fb++ = *bmap++;
						*fb++ = *bmap++;
						*fb++ = *bmap++;
					}
				}
				fb -= priv->line_length + width * (bpix / 8);
			}
		}
		break;
	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);
}
