/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
 *
 *  GRUB 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 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <grub/bitmap.h>
#include <grub/types.h>
#include <grub/normal.h>
#include <grub/dl.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/bufio.h>

GRUB_MOD_LICENSE ("GPLv3+");

/* Uncomment following define to enable TGA debug.  */
//#define TGA_DEBUG

#define dump_int_field(x) grub_dprintf ("tga", #x " = %d (0x%04x)\n", x, x);
#if defined(TGA_DEBUG)
static grub_command_t cmd;
#endif

enum
{
  GRUB_TGA_IMAGE_TYPE_NONE = 0,
  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_INDEXCOLOR = 1,
  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR = 2,
  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_BLACK_AND_WHITE = 3,
  GRUB_TGA_IMAGE_TYPE_RLE_INDEXCOLOR = 9,
  GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR = 10,
  GRUB_TGA_IMAGE_TYPE_RLE_BLACK_AND_WHITE = 11,
};

enum
{
  GRUB_TGA_COLOR_MAP_TYPE_NONE = 0,
  GRUB_TGA_COLOR_MAP_TYPE_INCLUDED = 1
};

enum
{
  GRUB_TGA_IMAGE_ORIGIN_RIGHT = 0x10,
  GRUB_TGA_IMAGE_ORIGIN_TOP   = 0x20
};

struct grub_tga_header
{
  grub_uint8_t id_length;
  grub_uint8_t color_map_type;
  grub_uint8_t image_type;

  /* Color Map Specification.  */
  grub_uint16_t color_map_first_index;
  grub_uint16_t color_map_length;
  grub_uint8_t color_map_bpp;

  /* Image Specification.  */
  grub_uint16_t image_x_origin;
  grub_uint16_t image_y_origin;
  grub_uint16_t image_width;
  grub_uint16_t image_height;
  grub_uint8_t image_bpp;
  grub_uint8_t image_descriptor;
} GRUB_PACKED;

struct tga_data
{
  struct grub_tga_header hdr;
  int uses_rle;
  int pktlen;
  int bpp;
  int is_rle;
  grub_uint8_t pixel[4];
  grub_uint8_t palette[256][3];
  struct grub_video_bitmap *bitmap;
  grub_file_t file;
  unsigned image_width;
  unsigned image_height;
};

static grub_err_t
fetch_pixel (struct tga_data *data)
{
  if (!data->uses_rle)
    {
      if (grub_file_read (data->file, &data->pixel[0], data->bpp)
	  != data->bpp)
	return grub_errno;
      return GRUB_ERR_NONE;
    }
  if (!data->pktlen)
    {
      grub_uint8_t type;
      if (grub_file_read (data->file, &type, sizeof (type)) != sizeof(type))
	return grub_errno;
      data->is_rle = !!(type & 0x80);
      data->pktlen = (type & 0x7f) + 1;
      if (data->is_rle && grub_file_read (data->file, &data->pixel[0], data->bpp)
	  != data->bpp)
	return grub_errno;
    }
  if (!data->is_rle && grub_file_read (data->file, &data->pixel[0], data->bpp)
      != data->bpp)
    return grub_errno;
  data->pktlen--;
  return GRUB_ERR_NONE;
}

static grub_err_t
tga_load_palette (struct tga_data *data)
{
  grub_size_t len = grub_le_to_cpu32 (data->hdr.color_map_length) * 3;

  if (len > sizeof (data->palette))
    len = sizeof (data->palette);
  
  if (grub_file_read (data->file, &data->palette, len)
      != (grub_ssize_t) len)
    return grub_errno;

#ifndef GRUB_CPU_WORDS_BIGENDIAN
  {
    grub_size_t i;
    for (i = 0; 3 * i < len; i++)
      {
	grub_uint8_t t;
	t = data->palette[i][0];
	data->palette[i][0] = data->palette[i][2];
	data->palette[i][2] = t;
      }
  }
#endif
  return GRUB_ERR_NONE;
}

static grub_err_t
tga_load_index_color (struct tga_data *data)
{
  unsigned int x;
  unsigned int y;
  grub_uint8_t *ptr;

  for (y = 0; y < data->image_height; y++)
    {
      ptr = data->bitmap->data;
      if ((data->hdr.image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
        ptr += y * data->bitmap->mode_info.pitch;
      else
        ptr += (data->image_height - 1 - y) * data->bitmap->mode_info.pitch;

      for (x = 0; x < data->image_width; x++)
        {
	  grub_err_t err;
	  err = fetch_pixel (data);
          if (err)
            return err;

          ptr[0] = data->palette[data->pixel[0]][0];
          ptr[1] = data->palette[data->pixel[0]][1];
          ptr[2] = data->palette[data->pixel[0]][2];

          ptr += 3;
        }
    }
  return GRUB_ERR_NONE;
}

static grub_err_t
tga_load_grayscale (struct tga_data *data)
{
  unsigned int x;
  unsigned int y;
  grub_uint8_t *ptr;

  for (y = 0; y < data->image_height; y++)
    {
      ptr = data->bitmap->data;
      if ((data->hdr.image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
        ptr += y * data->bitmap->mode_info.pitch;
      else
        ptr += (data->image_height - 1 - y) * data->bitmap->mode_info.pitch;

      for (x = 0; x < data->image_width; x++)
        {
	  grub_err_t err;
	  err = fetch_pixel (data);
          if (err)
            return err;

          ptr[0] = data->pixel[0];
          ptr[1] = data->pixel[0];
          ptr[2] = data->pixel[0];

          ptr += 3;
        }
    }
  return GRUB_ERR_NONE;
}

static grub_err_t
tga_load_truecolor_R8G8B8 (struct tga_data *data)
{
  unsigned int x;
  unsigned int y;
  grub_uint8_t *ptr;

  for (y = 0; y < data->image_height; y++)
    {
      ptr = data->bitmap->data;
      if ((data->hdr.image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
        ptr += y * data->bitmap->mode_info.pitch;
      else
        ptr += (data->image_height - 1 - y) * data->bitmap->mode_info.pitch;

      for (x = 0; x < data->image_width; x++)
        {
	  grub_err_t err;
	  err = fetch_pixel (data);
          if (err)
            return err;

#ifdef GRUB_CPU_WORDS_BIGENDIAN
          ptr[0] = data->pixel[0];
          ptr[1] = data->pixel[1];
          ptr[2] = data->pixel[2];
#else
          ptr[0] = data->pixel[2];
          ptr[1] = data->pixel[1];
          ptr[2] = data->pixel[0];
#endif
          ptr += 3;
        }
    }
  return GRUB_ERR_NONE;
}

static grub_err_t
tga_load_truecolor_R8G8B8A8 (struct tga_data *data)
{
  unsigned int x;
  unsigned int y;
  grub_uint8_t *ptr;

  for (y = 0; y < data->image_height; y++)
    {
      ptr = data->bitmap->data;
      if ((data->hdr.image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
        ptr += y * data->bitmap->mode_info.pitch;
      else
        ptr += (data->image_height - 1 - y) * data->bitmap->mode_info.pitch;

      for (x = 0; x < data->image_width; x++)
        {
	  grub_err_t err;
	  err = fetch_pixel (data);
          if (err)
            return err;

#ifdef GRUB_CPU_WORDS_BIGENDIAN
          ptr[0] = data->pixel[0];
          ptr[1] = data->pixel[1];
          ptr[2] = data->pixel[2];
          ptr[3] = data->pixel[3];
#else
          ptr[0] = data->pixel[2];
          ptr[1] = data->pixel[1];
          ptr[2] = data->pixel[0];
          ptr[3] = data->pixel[3];
#endif

          ptr += 4;
        }
    }
  return GRUB_ERR_NONE;
}

static grub_err_t
grub_video_reader_tga (struct grub_video_bitmap **bitmap,
                       const char *filename)
{
  grub_ssize_t pos;
  struct tga_data data;

  grub_memset (&data, 0, sizeof (data));

  data.file = grub_buffile_open (filename, GRUB_FILE_TYPE_PIXMAP, 0);
  if (! data.file)
    return grub_errno;

  /* TGA Specification states that we SHOULD start by reading
     ID from end of file, but we really don't care about that as we are
     not going to support developer area & extensions at this point.  */

  /* Read TGA header from beginning of file.  */
  if (grub_file_read (data.file, &data.hdr, sizeof (data.hdr))
      != sizeof (data.hdr))
    {
      grub_file_close (data.file);
      return grub_errno;
    }

  /* Skip ID field.  */
  pos = grub_file_tell (data.file);
  pos += data.hdr.id_length;
  grub_file_seek (data.file, pos);
  if (grub_errno != GRUB_ERR_NONE)
    {
      grub_file_close (data.file);
      return grub_errno;
    }

  grub_dprintf("tga", "tga: header\n");
  dump_int_field(data.hdr.id_length);
  dump_int_field(data.hdr.color_map_type);
  dump_int_field(data.hdr.image_type);
  dump_int_field(data.hdr.color_map_first_index);
  dump_int_field(data.hdr.color_map_length);
  dump_int_field(data.hdr.color_map_bpp);
  dump_int_field(data.hdr.image_x_origin);
  dump_int_field(data.hdr.image_y_origin);
  dump_int_field(data.hdr.image_width);
  dump_int_field(data.hdr.image_height);
  dump_int_field(data.hdr.image_bpp);
  dump_int_field(data.hdr.image_descriptor);

  data.image_width = grub_le_to_cpu16 (data.hdr.image_width);
  data.image_height = grub_le_to_cpu16 (data.hdr.image_height);

  /* Check that bitmap encoding is supported.  */
  switch (data.hdr.image_type)
    {
    case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
    case GRUB_TGA_IMAGE_TYPE_RLE_BLACK_AND_WHITE:
    case GRUB_TGA_IMAGE_TYPE_RLE_INDEXCOLOR:
      data.uses_rle = 1;
      break;
    case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
    case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_BLACK_AND_WHITE:
    case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_INDEXCOLOR:
      data.uses_rle = 0;
      break;

    default:
      grub_file_close (data.file);
      return grub_error (GRUB_ERR_BAD_FILE_TYPE,
			 "unsupported bitmap format (unknown encoding %d)", data.hdr.image_type);
    }

  data.bpp = data.hdr.image_bpp / 8;

  /* Check that bitmap depth is supported.  */
  switch (data.hdr.image_type)
    {
    case GRUB_TGA_IMAGE_TYPE_RLE_BLACK_AND_WHITE:
    case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_BLACK_AND_WHITE:
      if (data.hdr.image_bpp != 8)
	{
	  grub_file_close (data.file);
	  return grub_error (GRUB_ERR_BAD_FILE_TYPE,
			     "unsupported bitmap format (bpp=%d)",
			     data.hdr.image_bpp);
	}
      grub_video_bitmap_create (bitmap, data.image_width,
				data.image_height,
				GRUB_VIDEO_BLIT_FORMAT_RGB_888);
      if (grub_errno != GRUB_ERR_NONE)
	{
	  grub_file_close (data.file);
	  return grub_errno;
	}

      data.bitmap = *bitmap;
      /* Load bitmap data.  */
      tga_load_grayscale (&data);
      break;

    case GRUB_TGA_IMAGE_TYPE_RLE_INDEXCOLOR:
    case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_INDEXCOLOR:
      if (data.hdr.image_bpp != 8
	  || data.hdr.color_map_bpp != 24
	  || data.hdr.color_map_first_index != 0)
	{
	  grub_file_close (data.file);
	  return grub_error (GRUB_ERR_BAD_FILE_TYPE,
			     "unsupported bitmap format (bpp=%d)",
			     data.hdr.image_bpp);
	}
      grub_video_bitmap_create (bitmap, data.image_width,
				data.image_height,
				GRUB_VIDEO_BLIT_FORMAT_RGB_888);
      if (grub_errno != GRUB_ERR_NONE)
	{
	  grub_file_close (data.file);
	  return grub_errno;
	}

      data.bitmap = *bitmap;
      /* Load bitmap data.  */
      tga_load_palette (&data);
      tga_load_index_color (&data);
      break;

    case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
    case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
      switch (data.hdr.image_bpp)
	{
	case 24:
	  grub_video_bitmap_create (bitmap, data.image_width,
				    data.image_height,
				    GRUB_VIDEO_BLIT_FORMAT_RGB_888);
	  if (grub_errno != GRUB_ERR_NONE)
	    {
	      grub_file_close (data.file);
	      return grub_errno;
	    }

	  data.bitmap = *bitmap;
	  /* Load bitmap data.  */
	  tga_load_truecolor_R8G8B8 (&data);
	  break;

	case 32:
	  grub_video_bitmap_create (bitmap, data.image_width,
				    data.image_height,
				    GRUB_VIDEO_BLIT_FORMAT_RGBA_8888);
	  if (grub_errno != GRUB_ERR_NONE)
	    {
	      grub_file_close (data.file);
	      return grub_errno;
	    }

	  data.bitmap = *bitmap;
	  /* Load bitmap data.  */
	  tga_load_truecolor_R8G8B8A8 (&data);
	  break;

	default:
	  grub_file_close (data.file);
	  return grub_error (GRUB_ERR_BAD_FILE_TYPE,
			     "unsupported bitmap format (bpp=%d)",
			     data.hdr.image_bpp);
	}
    }

  /* If there was a loading problem, destroy bitmap.  */
  if (grub_errno != GRUB_ERR_NONE)
    {
      grub_video_bitmap_destroy (*bitmap);
      *bitmap = 0;
    }

  grub_file_close (data.file);
  return grub_errno;
}

#if defined(TGA_DEBUG)
static grub_err_t
grub_cmd_tgatest (grub_command_t cmd_d __attribute__ ((unused)),
                  int argc, char **args)
{
  struct grub_video_bitmap *bitmap = 0;

  if (argc != 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");

  grub_video_reader_tga (&bitmap, args[0]);
  if (grub_errno != GRUB_ERR_NONE)
    return grub_errno;

  grub_video_bitmap_destroy (bitmap);

  return GRUB_ERR_NONE;
}
#endif

static struct grub_video_bitmap_reader tga_reader = {
  .extension = ".tga",
  .reader = grub_video_reader_tga,
  .next = 0
};

GRUB_MOD_INIT(tga)
{
  grub_video_bitmap_reader_register (&tga_reader);
#if defined(TGA_DEBUG)
  cmd = grub_register_command ("tgatest", grub_cmd_tgatest,
                               "FILE", "Tests loading of TGA bitmap.");
#endif
}

GRUB_MOD_FINI(tga)
{
#if defined(TGA_DEBUG)
  grub_unregister_command (cmd);
#endif
  grub_video_bitmap_reader_unregister (&tga_reader);
}
