// Copyright 2012 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.
// -----------------------------------------------------------------------------
//
// GIF decode.

#include "./gifdec.h"

#include <stdio.h>

#ifdef WEBP_HAVE_GIF
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#include "webp/encode.h"
#include "webp/mux_types.h"

#define GIF_TRANSPARENT_COLOR 0x00000000u
#define GIF_WHITE_COLOR       0xffffffffu
#define GIF_TRANSPARENT_MASK  0x01
#define GIF_DISPOSE_MASK      0x07
#define GIF_DISPOSE_SHIFT     2

// from utils/utils.h
#ifdef __cplusplus
extern "C" {
#endif
extern void WebPCopyPlane(const uint8_t* src, int src_stride,
                          uint8_t* dst, int dst_stride,
                          int width, int height);
extern void WebPCopyPixels(const WebPPicture* const src,
                           WebPPicture* const dst);
#ifdef __cplusplus
}
#endif

void GIFGetBackgroundColor(const ColorMapObject* const color_map,
                           int bgcolor_index, int transparent_index,
                           uint32_t* const bgcolor) {
  if (transparent_index != GIF_INDEX_INVALID &&
      bgcolor_index == transparent_index) {
    *bgcolor = GIF_TRANSPARENT_COLOR;  // Special case.
  } else if (color_map == NULL || color_map->Colors == NULL
             || bgcolor_index >= color_map->ColorCount) {
    *bgcolor = GIF_WHITE_COLOR;
    fprintf(stderr,
            "GIF decode warning: invalid background color index. Assuming "
            "white background.\n");
  } else {
    const GifColorType color = color_map->Colors[bgcolor_index];
    *bgcolor = (0xffu       << 24)
             | (color.Red   << 16)
             | (color.Green <<  8)
             | (color.Blue  <<  0);
  }
}

int GIFReadGraphicsExtension(const GifByteType* const buf, int* const duration,
                             GIFDisposeMethod* const dispose,
                             int* const transparent_index) {
  const int flags = buf[1];
  const int dispose_raw = (flags >> GIF_DISPOSE_SHIFT) & GIF_DISPOSE_MASK;
  const int duration_raw = buf[2] | (buf[3] << 8);  // In 10 ms units.
  if (buf[0] != 4) return 0;
  *duration = duration_raw * 10;  // Duration is in 1 ms units.
  switch (dispose_raw) {
    case 3:
      *dispose = GIF_DISPOSE_RESTORE_PREVIOUS;
      break;
    case 2:
      *dispose = GIF_DISPOSE_BACKGROUND;
      break;
    case 1:
    case 0:
    default:
      *dispose = GIF_DISPOSE_NONE;
      break;
  }
  *transparent_index =
      (flags & GIF_TRANSPARENT_MASK) ? buf[4] : GIF_INDEX_INVALID;
  return 1;
}

static int Remap(const GifFileType* const gif, const uint8_t* const src,
                 int len, int transparent_index, uint32_t* dst) {
  int i;
  const GifColorType* colors;
  const ColorMapObject* const cmap =
      gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap;
  if (cmap == NULL) return 1;
  if (cmap->Colors == NULL || cmap->ColorCount <= 0) return 0;
  colors = cmap->Colors;

  for (i = 0; i < len; ++i) {
    if (src[i] == transparent_index) {
      dst[i] = GIF_TRANSPARENT_COLOR;
    } else if (src[i] < cmap->ColorCount) {
      const GifColorType c = colors[src[i]];
      dst[i] = c.Blue | (c.Green << 8) | (c.Red << 16) | (0xffu << 24);
    } else {
      return 0;
    }
  }
  return 1;
}

int GIFReadFrame(GifFileType* const gif, int transparent_index,
                 GIFFrameRect* const gif_rect, WebPPicture* const picture) {
  WebPPicture sub_image;
  const GifImageDesc* const image_desc = &gif->Image;
  uint32_t* dst = NULL;
  uint8_t* tmp = NULL;
  const GIFFrameRect rect = {
      image_desc->Left, image_desc->Top, image_desc->Width, image_desc->Height
  };
  const uint64_t memory_needed = 4 * rect.width * (uint64_t)rect.height;
  int ok = 0;
  *gif_rect = rect;

  if (memory_needed != (size_t)memory_needed || memory_needed > (4ULL << 32)) {
    fprintf(stderr, "Image is too large (%d x %d).", rect.width, rect.height);
    return 0;
  }

  // Use a view for the sub-picture:
  if (!WebPPictureView(picture, rect.x_offset, rect.y_offset,
                       rect.width, rect.height, &sub_image)) {
    fprintf(stderr, "Sub-image %dx%d at position %d,%d is invalid!\n",
            rect.width, rect.height, rect.x_offset, rect.y_offset);
    return 0;
  }
  dst = sub_image.argb;

  tmp = (uint8_t*)malloc(rect.width * sizeof(*tmp));
  if (tmp == NULL) goto End;

  if (image_desc->Interlace) {  // Interlaced image.
    // We need 4 passes, with the following offsets and jumps.
    const int interlace_offsets[] = { 0, 4, 2, 1 };
    const int interlace_jumps[]   = { 8, 8, 4, 2 };
    int pass;
    for (pass = 0; pass < 4; ++pass) {
      const size_t stride = (size_t)sub_image.argb_stride;
      int y = interlace_offsets[pass];
      uint32_t* row = dst + y * stride;
      const size_t jump = interlace_jumps[pass] * stride;
      for (; y < rect.height; y += interlace_jumps[pass], row += jump) {
        if (DGifGetLine(gif, tmp, rect.width) == GIF_ERROR) goto End;
        if (!Remap(gif, tmp, rect.width, transparent_index, row)) goto End;
      }
    }
  } else {  // Non-interlaced image.
    int y;
    uint32_t* ptr = dst;
    for (y = 0; y < rect.height; ++y, ptr += sub_image.argb_stride) {
      if (DGifGetLine(gif, tmp, rect.width) == GIF_ERROR) goto End;
      if (!Remap(gif, tmp, rect.width, transparent_index, ptr)) goto End;
    }
  }
  ok = 1;

 End:
  if (!ok) picture->error_code = sub_image.error_code;
  WebPPictureFree(&sub_image);
  free(tmp);
  return ok;
}

int GIFReadLoopCount(GifFileType* const gif, GifByteType** const buf,
                     int* const loop_count) {
  assert(!memcmp(*buf + 1, "NETSCAPE2.0", 11) ||
         !memcmp(*buf + 1, "ANIMEXTS1.0", 11));
  if (DGifGetExtensionNext(gif, buf) == GIF_ERROR) {
    return 0;
  }
  if (*buf == NULL) {
    return 0;  // Loop count sub-block missing.
  }
  if ((*buf)[0] < 3 || (*buf)[1] != 1) {
    return 0;   // wrong size/marker
  }
  *loop_count = (*buf)[2] | ((*buf)[3] << 8);
  return 1;
}

int GIFReadMetadata(GifFileType* const gif, GifByteType** const buf,
                    WebPData* const metadata) {
  const int is_xmp = !memcmp(*buf + 1, "XMP DataXMP", 11);
  const int is_icc = !memcmp(*buf + 1, "ICCRGBG1012", 11);
  assert(is_xmp || is_icc);
  (void)is_icc;  // silence unused warning.
  // Construct metadata from sub-blocks.
  // Usual case (including ICC profile): In each sub-block, the
  // first byte specifies its size in bytes (0 to 255) and the
  // rest of the bytes contain the data.
  // Special case for XMP data: In each sub-block, the first byte
  // is also part of the XMP payload. XMP in GIF also has a 257
  // byte padding data. See the XMP specification for details.
  while (1) {
    WebPData subblock;
    const uint8_t* tmp;
    if (DGifGetExtensionNext(gif, buf) == GIF_ERROR) {
      return 0;
    }
    if (*buf == NULL) break;  // Finished.
    subblock.size = is_xmp ? (*buf)[0] + 1 : (*buf)[0];
    assert(subblock.size > 0);
    subblock.bytes = is_xmp ? *buf : *buf + 1;
    // Note: We store returned value in 'tmp' first, to avoid
    // leaking old memory in metadata->bytes on error.
    tmp = (uint8_t*)realloc((void*)metadata->bytes,
                            metadata->size + subblock.size);
    if (tmp == NULL) {
      return 0;
    }
    memcpy((void*)(tmp + metadata->size),
           subblock.bytes, subblock.size);
    metadata->bytes = tmp;
    metadata->size += subblock.size;
  }
  if (is_xmp) {
    // XMP padding data is 0x01, 0xff, 0xfe ... 0x01, 0x00.
    const size_t xmp_pading_size = 257;
    if (metadata->size > xmp_pading_size) {
      metadata->size -= xmp_pading_size;
    }
  }
  return 1;
}

static void ClearRectangle(WebPPicture* const picture,
                           int left, int top, int width, int height) {
  int i, j;
  const size_t stride = picture->argb_stride;
  uint32_t* dst = picture->argb + top * stride + left;
  for (j = 0; j < height; ++j, dst += stride) {
    for (i = 0; i < width; ++i) dst[i] = GIF_TRANSPARENT_COLOR;
  }
}

void GIFClearPic(WebPPicture* const pic, const GIFFrameRect* const rect) {
  if (rect != NULL) {
    ClearRectangle(pic, rect->x_offset, rect->y_offset,
                   rect->width, rect->height);
  } else {
    ClearRectangle(pic, 0, 0, pic->width, pic->height);
  }
}

void GIFCopyPixels(const WebPPicture* const src, WebPPicture* const dst) {
  WebPCopyPixels(src, dst);
}

void GIFDisposeFrame(GIFDisposeMethod dispose, const GIFFrameRect* const rect,
                     const WebPPicture* const prev_canvas,
                     WebPPicture* const curr_canvas) {
  assert(rect != NULL);
  if (dispose == GIF_DISPOSE_BACKGROUND) {
    GIFClearPic(curr_canvas, rect);
  } else if (dispose == GIF_DISPOSE_RESTORE_PREVIOUS) {
    const size_t src_stride = prev_canvas->argb_stride;
    const uint32_t* const src = prev_canvas->argb + rect->x_offset
                              + rect->y_offset * src_stride;
    const size_t dst_stride = curr_canvas->argb_stride;
    uint32_t* const dst = curr_canvas->argb + rect->x_offset
                        + rect->y_offset * dst_stride;
    assert(prev_canvas != NULL);
    WebPCopyPlane((uint8_t*)src, (int)(4 * src_stride),
                  (uint8_t*)dst, (int)(4 * dst_stride),
                  4 * rect->width, rect->height);
  }
}

void GIFBlendFrames(const WebPPicture* const src,
                    const GIFFrameRect* const rect, WebPPicture* const dst) {
  int i, j;
  const size_t src_stride = src->argb_stride;
  const size_t dst_stride = dst->argb_stride;
  assert(src->width == dst->width && src->height == dst->height);
  for (j = rect->y_offset; j < rect->y_offset + rect->height; ++j) {
    for (i = rect->x_offset; i < rect->x_offset + rect->width; ++i) {
      const uint32_t src_pixel = src->argb[j * src_stride + i];
      const int src_alpha = src_pixel >> 24;
      if (src_alpha != 0) {
        dst->argb[j * dst_stride + i] = src_pixel;
      }
    }
  }
}

void GIFDisplayError(const GifFileType* const gif, int gif_error) {
  // libgif 4.2.0 has retired PrintGifError() and added GifErrorString().
#if LOCAL_GIF_PREREQ(4,2)
#if LOCAL_GIF_PREREQ(5,0)
  // Static string actually, hence the const char* cast.
  const char* error_str = (const char*)GifErrorString(
      (gif == NULL) ? gif_error : gif->Error);
#else
  const char* error_str = (const char*)GifErrorString();
  (void)gif;
#endif
  if (error_str == NULL) error_str = "Unknown error";
  fprintf(stderr, "GIFLib Error %d: %s\n", gif_error, error_str);
#else
  (void)gif;
  fprintf(stderr, "GIFLib Error %d: ", gif_error);
  PrintGifError();
  fprintf(stderr, "\n");
#endif
}

#else  // !WEBP_HAVE_GIF

static void ErrorGIFNotAvailable() {
  fprintf(stderr, "GIF support not compiled. Please install the libgif-dev "
          "package before building.\n");
}

void GIFGetBackgroundColor(const struct ColorMapObject* const color_map,
                           int bgcolor_index, int transparent_index,
                           uint32_t* const bgcolor) {
  (void)color_map;
  (void)bgcolor_index;
  (void)transparent_index;
  (void)bgcolor;
  ErrorGIFNotAvailable();
}

int GIFReadGraphicsExtension(const GifByteType* const data, int* const duration,
                             GIFDisposeMethod* const dispose,
                             int* const transparent_index) {
  (void)data;
  (void)duration;
  (void)dispose;
  (void)transparent_index;
  ErrorGIFNotAvailable();
  return 0;
}

int GIFReadFrame(struct GifFileType* const gif, int transparent_index,
                 GIFFrameRect* const gif_rect,
                 struct WebPPicture* const picture) {
  (void)gif;
  (void)transparent_index;
  (void)gif_rect;
  (void)picture;
  ErrorGIFNotAvailable();
  return 0;
}

int GIFReadLoopCount(struct GifFileType* const gif, GifByteType** const buf,
                     int* const loop_count) {
  (void)gif;
  (void)buf;
  (void)loop_count;
  ErrorGIFNotAvailable();
  return 0;
}

int GIFReadMetadata(struct GifFileType* const gif, GifByteType** const buf,
                    struct WebPData* const metadata) {
  (void)gif;
  (void)buf;
  (void)metadata;
  ErrorGIFNotAvailable();
  return 0;
}

void GIFDisposeFrame(GIFDisposeMethod dispose, const GIFFrameRect* const rect,
                     const struct WebPPicture* const prev_canvas,
                     struct WebPPicture* const curr_canvas) {
  (void)dispose;
  (void)rect;
  (void)prev_canvas;
  (void)curr_canvas;
  ErrorGIFNotAvailable();
}

void GIFBlendFrames(const struct WebPPicture* const src,
                    const GIFFrameRect* const rect,
                    struct WebPPicture* const dst) {
  (void)src;
  (void)rect;
  (void)dst;
  ErrorGIFNotAvailable();
}

void GIFDisplayError(const struct GifFileType* const gif, int gif_error) {
  (void)gif;
  (void)gif_error;
  ErrorGIFNotAvailable();
}

void GIFClearPic(struct WebPPicture* const pic,
                 const GIFFrameRect* const rect) {
  (void)pic;
  (void)rect;
  ErrorGIFNotAvailable();
}

void GIFCopyPixels(const struct WebPPicture* const src,
                   struct WebPPicture* const dst) {
  (void)src;
  (void)dst;
  ErrorGIFNotAvailable();
}

#endif  // WEBP_HAVE_GIF

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