/*
 * Copyright 2012 Google Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but without any warranty; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <libpayload.h>
#include <stdint.h>
#include <sysinfo.h>

#include "base/bitmap.h"
#include "drivers/video/coreboot_fb.h"

static inline void dc_corebootfb_draw_pixel(uint32_t x, uint32_t y,
					    uint32_t red, uint32_t green,
					    uint32_t blue,
					    struct cb_framebuffer *fbinfo,
					    unsigned char *fbaddr)
{
	const uint32_t xres = fbinfo->x_resolution;
	const int bpp = fbinfo->bits_per_pixel;

	uint32_t color = 0;
	color |= (red >> (8 - fbinfo->red_mask_size))
		<< fbinfo->red_mask_pos;
	color |= (green >> (8 - fbinfo->green_mask_size))
		<< fbinfo->green_mask_pos;
	color |= (blue >> (8 - fbinfo->blue_mask_size))
		<< fbinfo->blue_mask_pos;

	uint8_t *pixel = fbaddr + (x + y * xres) * bpp / 8;
	for (int i = 0; i < bpp / 8; i++)
		pixel[i] = (color >> (i * 8));
}

static int dc_corebootfb_draw_bitmap_v2(uint32_t x, uint32_t y,
					void *bitmap,
					struct cb_framebuffer *fbinfo,
					unsigned char *fbaddr)
{
	printf("Bitmap version 2 not supported.\n");
	return -1;
}

static int dc_corebootfb_draw_bitmap_v3(uint32_t x, uint32_t y,
					void *bitmap,
					struct cb_framebuffer *fbinfo,
					unsigned char *fbaddr)
{
	BitmapFileHeader *file_header_ptr = (BitmapFileHeader *)bitmap;
	uint32_t bitmap_offset;
	memcpy(&bitmap_offset, &file_header_ptr->bitmap_offset,
		sizeof(bitmap_offset));
	BitmapHeaderV3 header;
	memcpy(&header, (uint8_t *)bitmap + sizeof(BitmapFileHeader),
		sizeof(header));
	int bpp = header.bits_per_pixel;

	// Check for things we don't support.
	if (header.compression != 0 || bpp >= 16) {
		printf("Non-palette bitmaps are not supported.\n");
		return -1;
	}
	if (bpp != 1 && bpp != 4 && bpp != 8) {
		printf("Unsupported bits per pixel.\n");
		return -1;
	}

	uintptr_t palette_offset =
		sizeof(BitmapFileHeader) + sizeof(BitmapHeaderV3);
	int palette_size = bitmap_offset - palette_offset;
	BitmapPaletteElementV3 *palette = malloc(palette_size);
	if (!palette) {
		printf("Failed to allocate space for the palette.\n");
		return -1;
	}
	memcpy(palette, (uint8_t *)bitmap + palette_offset, palette_size);

	int32_t width = header.width, height = header.height;
	int extra = width % 4;
	const int32_t padding = extra ? (4 - extra) : 0;
	int32_t ystep = -1;
	if (height < 0) {
		height = -height;
		ystep = -ystep;
	} else {
		y += height - 1;
	}
	uint8_t *cur_data = (uint8_t *)bitmap + bitmap_offset;
	uint32_t x_offset = 0, y_offset = 0;
	int bit = 0;
	// Loop over all the pixels in the image.
	for (uint32_t pixel = 0; pixel < width * height; pixel++) {
		int index = 0;
		// Extract the index value for this pixel.
		if (bpp >= 8) {
			// For pixels one byte or larger, glue them together
			// one byte at a time. Pixels are big endian.
			for (int i = 0; i < bpp / 8; i++) {
				index <<= 8;
				index |= *cur_data++;
			}
		} else {
			// For pixels smaller than a byte, extract some bits
			// from the right byte. Bytes are big endian.
			const uint8_t mask = (1 << bpp) - 1;
			bit += bpp;
			index = (*cur_data >> (8 - bit)) & mask;
			if (bit == 8) {
				bit = 0;
				cur_data++;
			}
		}

		// Actually draw that pixel on the display.
		dc_corebootfb_draw_pixel(x + x_offset,
					 y + y_offset,
					 palette[index].red,
					 palette[index].green,
					 palette[index].blue,
					 fbinfo,
					 fbaddr);

		// Keep track of position.
		if (++x_offset == width) {
			x_offset = 0;
			y_offset += ystep;
			cur_data += padding;
		}
	}
	free(palette);
	return 0;
}

static int dc_corebootfb_draw_bitmap_v4(uint32_t x, uint32_t y,
					void *bitmap,
					struct cb_framebuffer *fbinfo,
					unsigned char *fbaddr)
{
	printf("Bitmap version 4 not supported.\n");
	return -1;
}

int dc_corebootfb_draw_bitmap(uint32_t x, uint32_t y, void *bitmap)
{
	BitmapFileHeader *file_header = (BitmapFileHeader *)bitmap;

	if (file_header->signature[0] != 'B' ||
	    file_header->signature[1] != 'M') {
		printf("Bitmap signature check failed.\n");
		return -1;
	}

	struct cb_framebuffer *fbinfo = lib_sysinfo.framebuffer;
	if (!fbinfo)
		return 0;
	unsigned char *fbaddr =
		(unsigned char *)(uintptr_t)(fbinfo->physical_address);
	if (!fbaddr)
		return -1;

	uint32_t header_size;
	memcpy(&header_size, file_header + 1, sizeof(header_size));
	switch (header_size) {
	case 12:
		return dc_corebootfb_draw_bitmap_v2(x, y, bitmap,
						    fbinfo, fbaddr);
	case 40:
		return dc_corebootfb_draw_bitmap_v3(x, y, bitmap,
						    fbinfo, fbaddr);
	case 108:
		return dc_corebootfb_draw_bitmap_v4(x, y, bitmap,
						    fbinfo, fbaddr);
	default:
		printf("Unrecognized bitmap format.\n");
		return -1;
	}
	return 0;
}
