// Copyright 2011 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
//  Simple OpenGL-based WebP file viewer.
//
// Author: Skal (pascal.massimino@gmail.com)
#ifdef HAVE_CONFIG_H
#include "webp/config.h"
#endif

#if defined(__unix__) || defined(__CYGWIN__)
#define _POSIX_C_SOURCE 200112L  // for setenv
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(WEBP_HAVE_GL)

#if defined(HAVE_GLUT_GLUT_H)
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#ifdef FREEGLUT
#include <GL/freeglut.h>
#endif
#endif

#ifdef WEBP_HAVE_QCMS
#include <qcms.h>
#endif

#include "webp/decode.h"
#include "webp/demux.h"

#include "../examples/example_util.h"
#include "../imageio/imageio_util.h"

#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
#endif

// Unfortunate global variables. Gathered into a struct for comfort.
static struct {
  int has_animation;
  int has_color_profile;
  int done;
  int decoding_error;
  int print_info;
  int only_deltas;
  int use_color_profile;

  int canvas_width, canvas_height;
  int loop_count;
  uint32_t bg_color;

  const char* file_name;
  WebPData data;
  WebPDecoderConfig config;
  const WebPDecBuffer* pic;
  WebPDemuxer* dmux;
  WebPIterator curr_frame;
  WebPIterator prev_frame;
  WebPChunkIterator iccp;
  int viewport_width, viewport_height;
} kParams;

static void ClearPreviousPic(void) {
  WebPFreeDecBuffer((WebPDecBuffer*)kParams.pic);
  kParams.pic = NULL;
}

static void ClearParams(void) {
  ClearPreviousPic();
  WebPDataClear(&kParams.data);
  WebPDemuxReleaseIterator(&kParams.curr_frame);
  WebPDemuxReleaseIterator(&kParams.prev_frame);
  WebPDemuxReleaseChunkIterator(&kParams.iccp);
  WebPDemuxDelete(kParams.dmux);
  kParams.dmux = NULL;
}

// Sets the previous frame to the dimensions of the canvas and has it dispose
// to background to cause the canvas to be cleared.
static void ClearPreviousFrame(void) {
  WebPIterator* const prev = &kParams.prev_frame;
  prev->width = kParams.canvas_width;
  prev->height = kParams.canvas_height;
  prev->x_offset = prev->y_offset = 0;
  prev->dispose_method = WEBP_MUX_DISPOSE_BACKGROUND;
}

// -----------------------------------------------------------------------------
// Color profile handling
static int ApplyColorProfile(const WebPData* const profile,
                             WebPDecBuffer* const rgba) {
#ifdef WEBP_HAVE_QCMS
  int i, ok = 0;
  uint8_t* line;
  uint8_t major_revision;
  qcms_profile* input_profile = NULL;
  qcms_profile* output_profile = NULL;
  qcms_transform* transform = NULL;
  const qcms_data_type input_type = QCMS_DATA_RGBA_8;
  const qcms_data_type output_type = QCMS_DATA_RGBA_8;
  const qcms_intent intent = QCMS_INTENT_DEFAULT;

  if (profile == NULL || rgba == NULL) return 0;
  if (profile->bytes == NULL || profile->size < 10) return 1;
  major_revision = profile->bytes[8];

  qcms_enable_iccv4();
  input_profile = qcms_profile_from_memory(profile->bytes, profile->size);
  // qcms_profile_is_bogus() is broken with ICCv4.
  if (input_profile == NULL ||
      (major_revision < 4 && qcms_profile_is_bogus(input_profile))) {
    fprintf(stderr, "Color profile is bogus!\n");
    goto Error;
  }

  output_profile = qcms_profile_sRGB();
  if (output_profile == NULL) {
    fprintf(stderr, "Error creating output color profile!\n");
    goto Error;
  }

  qcms_profile_precache_output_transform(output_profile);
  transform = qcms_transform_create(input_profile, input_type,
                                    output_profile, output_type,
                                    intent);
  if (transform == NULL) {
    fprintf(stderr, "Error creating color transform!\n");
    goto Error;
  }

  line = rgba->u.RGBA.rgba;
  for (i = 0; i < rgba->height; ++i, line += rgba->u.RGBA.stride) {
    qcms_transform_data(transform, line, line, rgba->width);
  }
  ok = 1;

 Error:
  if (input_profile != NULL) qcms_profile_release(input_profile);
  if (output_profile != NULL) qcms_profile_release(output_profile);
  if (transform != NULL) qcms_transform_release(transform);
  return ok;
#else
  (void)profile;
  (void)rgba;
  return 1;
#endif  // WEBP_HAVE_QCMS
}

//------------------------------------------------------------------------------
// File decoding

static int Decode(void) {   // Fills kParams.curr_frame
  const WebPIterator* const curr = &kParams.curr_frame;
  WebPDecoderConfig* const config = &kParams.config;
  WebPDecBuffer* const output_buffer = &config->output;
  int ok = 0;

  ClearPreviousPic();
  output_buffer->colorspace = MODE_RGBA;
  ok = (WebPDecode(curr->fragment.bytes, curr->fragment.size,
                   config) == VP8_STATUS_OK);
  if (!ok) {
    fprintf(stderr, "Decoding of frame #%d failed!\n", curr->frame_num);
  } else {
    kParams.pic = output_buffer;
    if (kParams.use_color_profile) {
      ok = ApplyColorProfile(&kParams.iccp.chunk, output_buffer);
      if (!ok) {
        fprintf(stderr, "Applying color profile to frame #%d failed!\n",
                curr->frame_num);
      }
    }
  }
  return ok;
}

static void decode_callback(int what) {
  if (what == 0 && !kParams.done) {
    int duration = 0;
    if (kParams.dmux != NULL) {
      WebPIterator* const curr = &kParams.curr_frame;
      if (!WebPDemuxNextFrame(curr)) {
        WebPDemuxReleaseIterator(curr);
        if (WebPDemuxGetFrame(kParams.dmux, 1, curr)) {
          --kParams.loop_count;
          kParams.done = (kParams.loop_count == 0);
          if (kParams.done) return;
          ClearPreviousFrame();
        } else {
          kParams.decoding_error = 1;
          kParams.done = 1;
          return;
        }
      }
      duration = curr->duration;
      // Behavior copied from Chrome, cf:
      // https://cs.chromium.org/chromium/src/third_party/WebKit/Source/
      // platform/graphics/DeferredImageDecoder.cpp?
      // rcl=b4c33049f096cd283f32be9a58b9a9e768227c26&l=246
      if (duration <= 10) duration = 100;
    }
    if (!Decode()) {
      kParams.decoding_error = 1;
      kParams.done = 1;
    } else {
      glutPostRedisplay();
      glutTimerFunc(duration, decode_callback, what);
    }
  }
}

//------------------------------------------------------------------------------
// Callbacks

static void HandleKey(unsigned char key, int pos_x, int pos_y) {
  (void)pos_x;
  (void)pos_y;
  if (key == 'q' || key == 'Q' || key == 27 /* Esc */) {
#ifdef FREEGLUT
    glutLeaveMainLoop();
#else
    ClearParams();
    exit(0);
#endif
  } else if (key == 'c') {
    if (kParams.has_color_profile && !kParams.decoding_error) {
      kParams.use_color_profile = 1 - kParams.use_color_profile;

      if (kParams.has_animation) {
        // Restart the completed animation to pickup the color profile change.
        if (kParams.done && kParams.loop_count == 0) {
          kParams.loop_count =
              (int)WebPDemuxGetI(kParams.dmux, WEBP_FF_LOOP_COUNT) + 1;
          kParams.done = 0;
          // Start the decode loop immediately.
          glutTimerFunc(0, decode_callback, 0);
        }
      } else {
        Decode();
        glutPostRedisplay();
      }
    }
  } else if (key == 'i') {
    // Note: doesn't handle refresh of animation's last-frame (it's quite
    // more involved to do, since you need to save the previous frame).
    kParams.print_info = 1 - kParams.print_info;
    if (!kParams.has_animation) ClearPreviousFrame();
    glutPostRedisplay();
  } else if (key == 'd') {
    kParams.only_deltas = 1 - kParams.only_deltas;
    glutPostRedisplay();
  }
}

static void HandleReshape(int width, int height) {
  // Note: reshape doesn't preserve aspect ratio, and might
  // be handling larger-than-screen pictures incorrectly.
  glViewport(0, 0, width, height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  kParams.viewport_width = width;
  kParams.viewport_height = height;
  if (!kParams.has_animation) ClearPreviousFrame();
}

static void PrintString(const char* const text) {
  void* const font = GLUT_BITMAP_9_BY_15;
  int i;
  for (i = 0; text[i]; ++i) {
    glutBitmapCharacter(font, text[i]);
  }
}

static float GetColorf(uint32_t color, int shift) {
  return (color >> shift) / 255.f;
}

static void DrawCheckerBoard(void) {
  const int square_size = 8;  // must be a power of 2
  int x, y;
  GLint viewport[4];  // x, y, width, height

  glPushMatrix();

  glGetIntegerv(GL_VIEWPORT, viewport);
  // shift to integer coordinates with (0,0) being top-left.
  glOrtho(0, viewport[2], viewport[3], 0, -1, 1);
  for (y = 0; y < viewport[3]; y += square_size) {
    for (x = 0; x < viewport[2]; x += square_size) {
      const GLubyte color = 128 + 64 * (!((x + y) & square_size));
      glColor3ub(color, color, color);
      glRecti(x, y, x + square_size, y + square_size);
    }
  }
  glPopMatrix();
}

static void HandleDisplay(void) {
  const WebPDecBuffer* const pic = kParams.pic;
  const WebPIterator* const curr = &kParams.curr_frame;
  WebPIterator* const prev = &kParams.prev_frame;
  GLfloat xoff, yoff;
  if (pic == NULL) return;
  glPushMatrix();
  glPixelZoom((GLfloat)(+1. / kParams.canvas_width * kParams.viewport_width),
              (GLfloat)(-1. / kParams.canvas_height * kParams.viewport_height));
  xoff = (GLfloat)(2. * curr->x_offset / kParams.canvas_width);
  yoff = (GLfloat)(2. * curr->y_offset / kParams.canvas_height);
  glRasterPos2f(-1.f + xoff, 1.f - yoff);
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  glPixelStorei(GL_UNPACK_ROW_LENGTH, pic->u.RGBA.stride / 4);

  if (kParams.only_deltas) {
    DrawCheckerBoard();
  } else if (prev->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND ||
      curr->blend_method == WEBP_MUX_NO_BLEND) {
    // glScissor() takes window coordinates (0,0 at bottom left).
    int window_x, window_y;
    int frame_w, frame_h;
    if (prev->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) {
      // Clear the previous frame rectangle.
      window_x = prev->x_offset;
      window_y = kParams.canvas_height - prev->y_offset - prev->height;
      frame_w = prev->width;
      frame_h = prev->height;
    } else {  // curr->blend_method == WEBP_MUX_NO_BLEND.
      // We simulate no-blending behavior by first clearing the current frame
      // rectangle (to a checker-board) and then alpha-blending against it.
      window_x = curr->x_offset;
      window_y = kParams.canvas_height - curr->y_offset - curr->height;
      frame_w = curr->width;
      frame_h = curr->height;
    }
    glEnable(GL_SCISSOR_TEST);
    // Only update the requested area, not the whole canvas.
    window_x = window_x * kParams.viewport_width / kParams.canvas_width;
    window_y = window_y * kParams.viewport_height / kParams.canvas_height;
    frame_w = frame_w * kParams.viewport_width / kParams.canvas_width;
    frame_h = frame_h * kParams.viewport_height / kParams.canvas_height;
    glScissor(window_x, window_y, frame_w, frame_h);

    glClear(GL_COLOR_BUFFER_BIT);  // use clear color
    DrawCheckerBoard();

    glDisable(GL_SCISSOR_TEST);
  }

  *prev = *curr;

  glDrawPixels(pic->width, pic->height,
               GL_RGBA, GL_UNSIGNED_BYTE,
               (GLvoid*)pic->u.RGBA.rgba);
  if (kParams.print_info) {
    char tmp[32];

    glColor4f(0.90f, 0.0f, 0.90f, 1.0f);
    glRasterPos2f(-0.95f, 0.90f);
    PrintString(kParams.file_name);

    snprintf(tmp, sizeof(tmp), "Dimension:%d x %d", pic->width, pic->height);
    glColor4f(0.90f, 0.0f, 0.90f, 1.0f);
    glRasterPos2f(-0.95f, 0.80f);
    PrintString(tmp);
    if (curr->x_offset != 0 || curr->y_offset != 0) {
      snprintf(tmp, sizeof(tmp), " (offset:%d,%d)",
               curr->x_offset, curr->y_offset);
      glRasterPos2f(-0.95f, 0.70f);
      PrintString(tmp);
    }
  }
  glPopMatrix();
#if defined(__APPLE__) || defined(_WIN32)
  glFlush();
#else
  glutSwapBuffers();
#endif
}

static void StartDisplay(void) {
  const int width = kParams.canvas_width;
  const int height = kParams.canvas_height;
  // TODO(webp:365) GLUT_DOUBLE results in flickering / old frames to be
  // partially displayed with animated webp + alpha.
#if defined(__APPLE__) || defined(_WIN32)
  glutInitDisplayMode(GLUT_RGBA);
#else
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
#endif
  glutInitWindowSize(width, height);
  glutCreateWindow("WebP viewer");
  glutDisplayFunc(HandleDisplay);
  glutReshapeFunc(HandleReshape);
  glutIdleFunc(NULL);
  glutKeyboardFunc(HandleKey);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glEnable(GL_BLEND);
  glClearColor(GetColorf(kParams.bg_color, 0),
               GetColorf(kParams.bg_color, 8),
               GetColorf(kParams.bg_color, 16),
               GetColorf(kParams.bg_color, 24));
  glClear(GL_COLOR_BUFFER_BIT);
  DrawCheckerBoard();
}

//------------------------------------------------------------------------------
// Main

static void Help(void) {
  printf("Usage: vwebp in_file [options]\n\n"
         "Decodes the WebP image file and visualize it using OpenGL\n"
         "Options are:\n"
         "  -version ..... print version number and exit\n"
         "  -noicc ....... don't use the icc profile if present\n"
         "  -nofancy ..... don't use the fancy YUV420 upscaler\n"
         "  -nofilter .... disable in-loop filtering\n"
         "  -dither <int>  dithering strength (0..100), default=50\n"
         "  -noalphadither disable alpha plane dithering\n"
         "  -mt .......... use multi-threading\n"
         "  -info ........ print info\n"
         "  -h ........... this help message\n"
         "\n"
         "Keyboard shortcuts:\n"
         "  'c' ................ toggle use of color profile\n"
         "  'i' ................ overlay file information\n"
         "  'd' ................ disable blending & disposal (debug)\n"
         "  'q' / 'Q' / ESC .... quit\n"
        );
}

int main(int argc, char *argv[]) {
  int c;
  WebPDecoderConfig* const config = &kParams.config;
  WebPIterator* const curr = &kParams.curr_frame;

  if (!WebPInitDecoderConfig(config)) {
    fprintf(stderr, "Library version mismatch!\n");
    return -1;
  }
  config->options.dithering_strength = 50;
  config->options.alpha_dithering_strength = 100;
  kParams.use_color_profile = 1;

  for (c = 1; c < argc; ++c) {
    int parse_error = 0;
    if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
      Help();
      return 0;
    } else if (!strcmp(argv[c], "-noicc")) {
      kParams.use_color_profile = 0;
    } else if (!strcmp(argv[c], "-nofancy")) {
      config->options.no_fancy_upsampling = 1;
    } else if (!strcmp(argv[c], "-nofilter")) {
      config->options.bypass_filtering = 1;
    } else if (!strcmp(argv[c], "-noalphadither")) {
      config->options.alpha_dithering_strength = 0;
    } else if (!strcmp(argv[c], "-dither") && c + 1 < argc) {
      config->options.dithering_strength =
          ExUtilGetInt(argv[++c], 0, &parse_error);
    } else if (!strcmp(argv[c], "-info")) {
      kParams.print_info = 1;
    } else if (!strcmp(argv[c], "-version")) {
      const int dec_version = WebPGetDecoderVersion();
      const int dmux_version = WebPGetDemuxVersion();
      printf("WebP Decoder version: %d.%d.%d\nWebP Demux version: %d.%d.%d\n",
             (dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
             dec_version & 0xff, (dmux_version >> 16) & 0xff,
             (dmux_version >> 8) & 0xff, dmux_version & 0xff);
      return 0;
    } else if (!strcmp(argv[c], "-mt")) {
      config->options.use_threads = 1;
    } else if (!strcmp(argv[c], "--")) {
      if (c < argc - 1) kParams.file_name = argv[++c];
      break;
    } else if (argv[c][0] == '-') {
      printf("Unknown option '%s'\n", argv[c]);
      Help();
      return -1;
    } else {
      kParams.file_name = argv[c];
    }

    if (parse_error) {
      Help();
      return -1;
    }
  }

  if (kParams.file_name == NULL) {
    printf("missing input file!!\n");
    Help();
    return 0;
  }

  if (!ImgIoUtilReadFile(kParams.file_name,
                         &kParams.data.bytes, &kParams.data.size)) {
    goto Error;
  }

  if (!WebPGetInfo(kParams.data.bytes, kParams.data.size, NULL, NULL)) {
    fprintf(stderr, "Input file doesn't appear to be WebP format.\n");
    goto Error;
  }

  kParams.dmux = WebPDemux(&kParams.data);
  if (kParams.dmux == NULL) {
    fprintf(stderr, "Could not create demuxing object!\n");
    goto Error;
  }

  kParams.canvas_width = WebPDemuxGetI(kParams.dmux, WEBP_FF_CANVAS_WIDTH);
  kParams.canvas_height = WebPDemuxGetI(kParams.dmux, WEBP_FF_CANVAS_HEIGHT);
  if (kParams.print_info) {
    printf("Canvas: %d x %d\n", kParams.canvas_width, kParams.canvas_height);
  }

  ClearPreviousFrame();

  memset(&kParams.iccp, 0, sizeof(kParams.iccp));
  kParams.has_color_profile =
      !!(WebPDemuxGetI(kParams.dmux, WEBP_FF_FORMAT_FLAGS) & ICCP_FLAG);
  if (kParams.has_color_profile) {
#ifdef WEBP_HAVE_QCMS
    if (!WebPDemuxGetChunk(kParams.dmux, "ICCP", 1, &kParams.iccp)) goto Error;
    printf("VP8X: Found color profile\n");
#else
    fprintf(stderr, "Warning: color profile present, but qcms is unavailable!\n"
            "Build libqcms from Mozilla or Chromium and define WEBP_HAVE_QCMS "
            "before building.\n");
#endif
  }

  if (!WebPDemuxGetFrame(kParams.dmux, 1, curr)) goto Error;

  kParams.has_animation = (curr->num_frames > 1);
  kParams.loop_count = (int)WebPDemuxGetI(kParams.dmux, WEBP_FF_LOOP_COUNT);
  kParams.bg_color = WebPDemuxGetI(kParams.dmux, WEBP_FF_BACKGROUND_COLOR);
  printf("VP8X: Found %d images in file (loop count = %d)\n",
         curr->num_frames, kParams.loop_count);

  // Decode first frame
  if (!Decode()) goto Error;

  // Position iterator to last frame. Next call to HandleDisplay will wrap over.
  // We take this into account by bumping up loop_count.
  WebPDemuxGetFrame(kParams.dmux, 0, curr);
  if (kParams.loop_count) ++kParams.loop_count;

#if defined(__unix__) || defined(__CYGWIN__)
  // Work around GLUT compositor bug.
  // https://bugs.launchpad.net/ubuntu/+source/freeglut/+bug/369891
  setenv("XLIB_SKIP_ARGB_VISUALS", "1", 1);
#endif

  // Start display (and timer)
  glutInit(&argc, argv);
#ifdef FREEGLUT
  glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
#endif
  StartDisplay();

  if (kParams.has_animation) glutTimerFunc(0, decode_callback, 0);
  glutMainLoop();

  // Should only be reached when using FREEGLUT:
  ClearParams();
  return 0;

 Error:
  ClearParams();
  return -1;
}

#else   // !WEBP_HAVE_GL

int main(int argc, const char *argv[]) {
  fprintf(stderr, "OpenGL support not enabled in %s.\n", argv[0]);
  (void)argc;
  return 0;
}

#endif

//------------------------------------------------------------------------------
