// 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*)WebPMalloc(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);
  WebPFree(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

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