/* ply-image.c - png file loader
 *
 * Copyright (C) 2006, 2007 Red Hat, Inc.
 * Copyright (C) 2003 University of Southern California
 *
 * 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, 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.
 *
 * Some implementation taken from the cairo library.
 *
 * Shamelessly taken and unmercifully hacked for temporary use
 * in Chrome OS.
 *
 * Written by: Charlie Brej <cbrej@cs.man.ac.uk>
 *             Kristian Høgsberg <krh@redhat.com>
 *             Ray Strode <rstrode@redhat.com>
 *             Carl D. Worth <cworth@cworth.org>
 */

#include <assert.h>
#include <errno.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

// <png.h> depends on <math.h> but doesn't include it.  Boo!
//
// Also, <png.h> includes <setjmp.h> and is designed to break if we
// re-include it.  Boo!
#include <math.h>
#include <png.h>

#include "ply-frame-buffer.h"
#include "ply-gamma.h"
#include "ply-utils.h"


typedef union {
  uint32_t *as_pixels;
  png_byte *as_png_bytes;
  char *address;
} ply_image_layout_t;

typedef struct {
  char  *filename;
  FILE  *fp;

  ply_image_layout_t layout;
  size_t size;

  png_uint_32 width;
  png_uint_32 height;
} ply_image_t;


static bool ply_image_open_file(ply_image_t *image) {
  assert(image != NULL);

  image->fp = fopen(image->filename, "r");

  return image->fp != NULL;
}

static void ply_image_close_file(ply_image_t *image) {
  assert(image != NULL);

  if (image->fp == NULL)
    return;
  fclose(image->fp);
  image->fp = NULL;
}

static ply_image_t *ply_image_new(const char *filename) {
  ply_image_t *image;

  assert(filename != NULL);

  image = calloc(1, sizeof(*image));

  image->filename = strdup(filename);
  image->fp = NULL;
  image->layout.address = NULL;
  image->size = -1;
  image->width = -1;
  image->height = -1;

  return image;
}

static void ply_image_free(ply_image_t *image) {
  if (image == NULL)
    return;

  assert(image->filename != NULL);

  if (image->layout.address != NULL) {
    free(image->layout.address);
    image->layout.address = NULL;
  }

  free(image->filename);
  free(image);
}

/*
 * The following function courtesy of Intel Moblin's
 * plymouth-lite port.
 */
static void transform_to_rgb32(png_struct   *png,
                               png_row_info *row_info,
                               png_byte     *data) {
  unsigned int i;

  for (i = 0; i < row_info->rowbytes; i += 4) {
    uint8_t  red, green, blue, alpha;
    uint32_t pixel_value;

    red = data[i + 0];
    green = data[i + 1];
    blue = data[i + 2];
    alpha = data[i + 3];
    pixel_value = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
    memcpy(data + i, &pixel_value, sizeof(pixel_value));
  }
}

static bool ply_image_load(ply_image_t *image) {
  png_struct *png;
  png_info *info;
  png_uint_32 width, height, bytes_per_row, row;
  int bits_per_pixel, color_type, interlace_method;
  png_byte **rows;

  assert(image != NULL);

  if (!ply_image_open_file(image))
    return false;

  png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  assert(png != NULL);

  info = png_create_info_struct(png);
  assert(info != NULL);

  png_init_io(png, image->fp);

  if (setjmp(png_jmpbuf(png)) != 0) {
    ply_image_close_file(image);
    return false;
  }

  png_read_info(png, info);
  png_get_IHDR(png, info,
               &width, &height, &bits_per_pixel,
               &color_type, &interlace_method, NULL, NULL);
  bytes_per_row = 4 * width;

  if (color_type == PNG_COLOR_TYPE_PALETTE)
    png_set_palette_to_rgb(png);

  if ((color_type == PNG_COLOR_TYPE_GRAY) && (bits_per_pixel < 8))
    png_set_gray_1_2_4_to_8(png);

  if (png_get_valid(png, info, PNG_INFO_tRNS))
    png_set_tRNS_to_alpha(png);

  if (bits_per_pixel == 16)
    png_set_strip_16(png);

  if (bits_per_pixel < 8)
    png_set_packing(png);

  if ((color_type == PNG_COLOR_TYPE_GRAY) ||
      (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
    png_set_gray_to_rgb(png);

  if (interlace_method != PNG_INTERLACE_NONE)
    png_set_interlace_handling(png);

  png_set_filler(png, 0xff, PNG_FILLER_AFTER);

  png_set_read_user_transform_fn(png, transform_to_rgb32);

  png_read_update_info(png, info);

  rows = malloc(height * sizeof(*rows));
  image->layout.address = malloc(height * bytes_per_row);

  for (row = 0; row < height; row++)
    rows[row] = &image->layout.as_png_bytes[row * bytes_per_row];

  png_read_image(png, rows);

  free(rows);
  png_read_end(png, info);
  ply_image_close_file(image);
  png_destroy_read_struct(&png, &info, NULL);

  image->width = width;
  image->height = height;

  return true;
}

static uint32_t *ply_image_get_data(ply_image_t *image) {
  assert(image != NULL);

  return image->layout.as_pixels;
}

static long ply_image_get_width(ply_image_t *image) {
  assert(image != NULL);

  return image->width;
}

static long ply_image_get_height(ply_image_t *image) {
  assert(image != NULL);

  return image->height;
}

static ply_image_t *ply_image_from_file(const char *path) {
  ply_image_t *image = ply_image_new(path);

  if (!ply_image_load(image)) {
    perror(path);
    exit(errno);
  }
  return image;
}

static int debug = 0;
static bool center_image = true;
static ply_frame_buffer_area_t image_location, image_offset;
static uint32_t clear_color;

static void ply_frame_buffer_show_file(
    ply_frame_buffer_t *buffer, const char *path) {
  ply_image_t *image;
  uint32_t *data;
  ply_frame_buffer_area_t area, buffer_area;
  bool fill_succeeded;

  image = ply_image_from_file(path);

  area.width = ply_image_get_width(image);
  area.height = ply_image_get_height(image);
  data = ply_image_get_data(image);

  if (center_image) {
    ply_frame_buffer_get_size(buffer, &buffer_area);
    area.x = (long) (buffer_area.width - area.width) / 2;
    area.y = (long) (buffer_area.height - area.height) / 2;
  } else {
    area.x = image_location.x;
    area.y = image_location.y;
  }

  area.x += image_offset.x;
  area.y += image_offset.y;
  if (debug) {
    fprintf(stderr, "%lux%lu image at (%ld, %ld) is %s\n",
                    area.width, area.height, area.x, area.y, path);
  }
  fill_succeeded = ply_frame_buffer_fill(buffer, &area, data);

  if (!fill_succeeded)
    fprintf(stderr, "image was not displayed\n");

  ply_image_free(image);
}


static int usage(void) {
  fprintf(stderr,
          "usage: ply-image [OPTION]... [FILE]...\n"
          "Copy one or more images to the framebuffer.\n"
          "\n"
          "Options:\n"
          "  --clear=0xRRGGBB         hexadecimal framebuffer clear color\n"
          "  --debug                  print debugging info to stderr\n"
          "  --frame-interval=MSEC    time interval between images\n"
          "  --gamma=FILE             file containing gamma ramps\n"
          "  --help                   display this message\n"
          "  --location=X,Y           image location relative to top left\n"
          "                           corner of framebuffer\n"
          "  --offset=[+|-]X,[+|-]Y   image location as offset from center\n"
          "                           of framebuffer\n"
          "  --print-resolution       print space-separated framebuffer\n"
          "                           width and height to stdout\n");
  exit(EXIT_FAILURE);
}


static bool parse_color(const char *arg) {
  char *endptr;

  clear_color = strtol(arg, &endptr, 16);
  if (endptr == arg || *endptr != '\0') {
    return false;
  }

  return true;
}

static bool parse_xy(const char *arg, ply_frame_buffer_area_t *area) {
  char *endptr;
  long x, y;

  x = strtol(arg, &endptr, 10);
  if (endptr == arg || *endptr != ',') {
    return false;
  }

  arg = endptr + 1;
  y = strtol(arg, &endptr, 10);
  if (endptr == arg || *endptr != '\0') {
    return false;
  }

  area->x = x;
  area->y = y;

  return true;
}

static bool parse_location(const char *arg) {
  bool result = parse_xy(arg, &image_location);
  if (result)
    center_image = false;
  return result;
}

static bool parse_offset(const char *arg) {
  return parse_xy(arg, &image_offset);
}


#define MS_PER_SEC      1000
#define NS_PER_SEC      (1000 * 1000 * 1000)
#define NS_PER_MS       (NS_PER_SEC / MS_PER_SEC)
#define FRAMES_PER_SEC  20

/* Frame rate as milliseconds per frame */
static long frame_interval_ms = MS_PER_SEC / FRAMES_PER_SEC;

static bool set_frame_interval(const char *arg) {
  char *endptr;

  long interval = strtol(arg, &endptr, 10);
  if (endptr == arg || *endptr != '\0') {
    return false;
  }

  frame_interval_ms = interval;
  return true;
}


/*
 * Animate the series of images named on the command line.  The
 * animation is timed so that the average time per frame is
 * frame_interval_ms milliseconds.
 */
static void process_images(
    ply_frame_buffer_t *buffer, int argc, char *argv[]) {
  struct timespec curr_time, last_time;
  int64_t sleep_ns = 0;

  clock_gettime(CLOCK_MONOTONIC, &last_time);
  while (argc > 0) {
    if (debug) {
      fprintf(stderr, "time now %ld.%06ld",
                      last_time.tv_sec,
                      (last_time.tv_nsec + 500) / 1000);
    }
    if (sleep_ns > 0) {
      struct timespec sleep_time;
      sleep_time.tv_sec = sleep_ns / NS_PER_SEC;
      sleep_time.tv_nsec = sleep_ns % NS_PER_SEC;
      nanosleep(&sleep_time, NULL);
    } else {
      sleep_ns = 0;
    }

    if (debug) {
      fprintf(stderr, "; slept for %ld.%06ld\n",
                      sleep_ns / NS_PER_SEC,
                      (sleep_ns + 500) / 1000);
    }
    ply_frame_buffer_show_file(buffer, argv[0]);

    clock_gettime(CLOCK_MONOTONIC, &curr_time);
    sleep_ns += frame_interval_ms * NS_PER_MS +
        NS_PER_SEC * (last_time.tv_sec - curr_time.tv_sec) +
        last_time.tv_nsec - curr_time.tv_nsec;
    last_time = curr_time;

    argc--;
    argv++;
  }
}


#define FLAG_CLEAR             'c'
#define FLAG_DEBUG             'D'
#define FLAG_FRAME             'f'
#define FLAG_GAMMA             'g'
#define FLAG_HELP              'h'
#define FLAG_LOCATION          'l'
#define FLAG_OFFSET            'o'
#define FLAG_PRINT_RESOLUTION  'p'

static struct option command_options[] = {
  { "clear", required_argument, NULL, FLAG_CLEAR },
  { "debug", no_argument, NULL, FLAG_DEBUG },
  { "frame-interval", required_argument, NULL, FLAG_FRAME },
  { "gamma", required_argument, NULL, FLAG_GAMMA },
  { "help", no_argument, NULL, FLAG_HELP },
  { "location", required_argument, NULL, FLAG_LOCATION },
  { "offset", required_argument, NULL, FLAG_OFFSET },
  { "print-resolution", no_argument, NULL, FLAG_PRINT_RESOLUTION },
  { NULL, 0, NULL, 0 },
};


int main(int argc, char **argv) {
  int clear = 0;
  bool location_assigned = false;
  bool offset_assigned = false;
  bool print_resolution = false;
  ply_frame_buffer_t *buffer;

  /*
   * TODO(jrbarnette): The command line parsing here and throughout
   * the code is a bit rudimentary, especially w.r.t. error
   * checking.  This command is only invoked in a handful of places
   * in Chromium OS; outside of those cases, you should be grateful
   * any time the error message isn't
   *   Segmentation fault (core dumped)
   * :-)
   */
  for (;;) {
    int c = getopt_long(argc, argv, "", command_options, NULL);
    if (c == -1) {
      break;
    }

    if (c == FLAG_HELP) {
      usage();
    }

    if (c == FLAG_DEBUG) {
      debug = 1;
      continue;
    }

    if (c == FLAG_CLEAR) {
      clear = 1;
      if (!parse_color(optarg)) {
        usage();
      }
      continue;
    }

    if (c == FLAG_FRAME) {
      if (!set_frame_interval(optarg)) {
        usage();
      }
      continue;
    }

    if (c == FLAG_GAMMA) {
      // Not all platforms necessarily have a gamma ramp file, so we
      // ignore errors from this call.
      (void) ply_gamma_set(optarg);
      continue;
    }

    if (c == FLAG_LOCATION) {
      if (!parse_location(optarg)) {
        usage();
      }
      location_assigned = true;
      continue;
    }

    if (c == FLAG_OFFSET) {
      if (!parse_offset(optarg)) {
        usage();
      }
      offset_assigned = true;
      continue;
    }

    if (c == FLAG_PRINT_RESOLUTION) {
      print_resolution = true;
      continue;
    }
  }

  if (location_assigned && offset_assigned) {
    fprintf(stderr,
            "--location and --offset should not be assigned at same time.\n");
    usage();
  }

  buffer = ply_frame_buffer_new(NULL);
  if (!ply_frame_buffer_open(buffer)) {
    perror("could not open framebuffer");
    return errno;
  }

  ply_frame_buffer_area_t fb_area;
  ply_frame_buffer_get_size(buffer, &fb_area);

  if (print_resolution) {
    printf("%d %d\n", fb_area.width, fb_area.height);
  }

  if (debug) {
    fprintf(stderr, "screen dimensions:  %lux%lu\n",
            fb_area.width, fb_area.height);
  }

  if (clear) {
    ply_frame_buffer_clear(buffer, clear_color);
  }

  process_images(buffer, argc - optind, argv + optind);
  return EXIT_SUCCESS;
}
