// Copyright 2014 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.
// -----------------------------------------------------------------------------
//
// WebP decode.

#ifdef HAVE_CONFIG_H
#include "webp/config.h"
#endif

#include "./webpdec.h"

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

#include "webp/decode.h"
#include "webp/demux.h"
#include "webp/encode.h"
#include "./imageio_util.h"
#include "./metadata.h"

//------------------------------------------------------------------------------
// WebP decoding

static const char* const kStatusMessages[VP8_STATUS_NOT_ENOUGH_DATA + 1] = {
  "OK", "OUT_OF_MEMORY", "INVALID_PARAM", "BITSTREAM_ERROR",
  "UNSUPPORTED_FEATURE", "SUSPENDED", "USER_ABORT", "NOT_ENOUGH_DATA"
};

static void PrintAnimationWarning(const WebPDecoderConfig* const config) {
  if (config->input.has_animation) {
    fprintf(stderr,
            "Error! Decoding of an animated WebP file is not supported.\n"
            "       Use webpmux to extract the individual frames or\n"
            "       vwebp to view this image.\n");
  }
}

void PrintWebPError(const char* const in_file, int status) {
  fprintf(stderr, "Decoding of %s failed.\n", in_file);
  fprintf(stderr, "Status: %d", status);
  if (status >= VP8_STATUS_OK && status <= VP8_STATUS_NOT_ENOUGH_DATA) {
    fprintf(stderr, "(%s)", kStatusMessages[status]);
  }
  fprintf(stderr, "\n");
}

int LoadWebP(const char* const in_file,
             const uint8_t** data, size_t* data_size,
             WebPBitstreamFeatures* bitstream) {
  VP8StatusCode status;
  WebPBitstreamFeatures local_features;
  if (!ImgIoUtilReadFile(in_file, data, data_size)) return 0;

  if (bitstream == NULL) {
    bitstream = &local_features;
  }

  status = WebPGetFeatures(*data, *data_size, bitstream);
  if (status != VP8_STATUS_OK) {
    free((void*)*data);
    *data = NULL;
    *data_size = 0;
    PrintWebPError(in_file, status);
    return 0;
  }
  return 1;
}

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

VP8StatusCode DecodeWebP(const uint8_t* const data, size_t data_size,
                         WebPDecoderConfig* const config) {
  if (config == NULL) return VP8_STATUS_INVALID_PARAM;
  PrintAnimationWarning(config);
  return WebPDecode(data, data_size, config);
}

VP8StatusCode DecodeWebPIncremental(
    const uint8_t* const data, size_t data_size,
    WebPDecoderConfig* const config) {
  VP8StatusCode status = VP8_STATUS_OK;
  if (config == NULL) return VP8_STATUS_INVALID_PARAM;

  PrintAnimationWarning(config);

  // Decoding call.
  {
    WebPIDecoder* const idec = WebPIDecode(data, data_size, config);
    if (idec == NULL) {
      fprintf(stderr, "Failed during WebPINewDecoder().\n");
      return VP8_STATUS_OUT_OF_MEMORY;
    } else {
      status = WebPIUpdate(idec, data, data_size);
      WebPIDelete(idec);
    }
  }
  return status;
}

// -----------------------------------------------------------------------------
// Metadata

static int ExtractMetadata(const uint8_t* const data, size_t data_size,
                           Metadata* const metadata) {
  WebPData webp_data = { data, data_size };
  WebPDemuxer* const demux = WebPDemux(&webp_data);
  WebPChunkIterator chunk_iter;
  uint32_t flags;

  if (demux == NULL) return 0;
  assert(metadata != NULL);

  flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);

  if ((flags & ICCP_FLAG) && WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter)) {
    MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size,
                 &metadata->iccp);
    WebPDemuxReleaseChunkIterator(&chunk_iter);
  }
  if ((flags & EXIF_FLAG) && WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter)) {
    MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size,
                 &metadata->exif);
    WebPDemuxReleaseChunkIterator(&chunk_iter);
  }
  if ((flags & XMP_FLAG) && WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter)) {
    MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size,
                 &metadata->xmp);
    WebPDemuxReleaseChunkIterator(&chunk_iter);
  }
  WebPDemuxDelete(demux);
  return 1;
}

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

int ReadWebP(const uint8_t* const data, size_t data_size,
             WebPPicture* const pic,
             int keep_alpha, Metadata* const metadata) {
  int ok = 0;
  VP8StatusCode status = VP8_STATUS_OK;
  WebPDecoderConfig config;
  WebPDecBuffer* const output_buffer = &config.output;
  WebPBitstreamFeatures* const bitstream = &config.input;

  if (data == NULL || data_size == 0 || pic == NULL) return 0;

  if (!WebPInitDecoderConfig(&config)) {
    fprintf(stderr, "Library version mismatch!\n");
    return 0;
  }

  status = WebPGetFeatures(data, data_size, bitstream);
  if (status != VP8_STATUS_OK) {
    PrintWebPError("input data", status);
    return 0;
  }

  do {
    const int has_alpha = keep_alpha && bitstream->has_alpha;
    uint64_t stride;
    pic->width = bitstream->width;
    pic->height = bitstream->height;
    if (pic->use_argb) {
      stride = (uint64_t)bitstream->width * 4;
    } else {
      stride = (uint64_t)bitstream->width * (has_alpha ? 5 : 3) / 2;
      pic->colorspace = has_alpha ? WEBP_YUV420A : WEBP_YUV420;
    }

    if (!ImgIoUtilCheckSizeArgumentsOverflow(stride, bitstream->height)) {
      status = VP8_STATUS_OUT_OF_MEMORY;
      break;
    }

    ok = WebPPictureAlloc(pic);
    if (!ok) {
      status = VP8_STATUS_OUT_OF_MEMORY;
      break;
    }
    if (pic->use_argb) {
#ifdef WORDS_BIGENDIAN
      output_buffer->colorspace = MODE_ARGB;
#else
      output_buffer->colorspace = MODE_BGRA;
#endif
      output_buffer->u.RGBA.rgba = (uint8_t*)pic->argb;
      output_buffer->u.RGBA.stride = pic->argb_stride * sizeof(uint32_t);
      output_buffer->u.RGBA.size = output_buffer->u.RGBA.stride * pic->height;
    } else {
      output_buffer->colorspace = has_alpha ? MODE_YUVA : MODE_YUV;
      output_buffer->u.YUVA.y = pic->y;
      output_buffer->u.YUVA.u = pic->u;
      output_buffer->u.YUVA.v = pic->v;
      output_buffer->u.YUVA.a = has_alpha ? pic->a : NULL;
      output_buffer->u.YUVA.y_stride = pic->y_stride;
      output_buffer->u.YUVA.u_stride = pic->uv_stride;
      output_buffer->u.YUVA.v_stride = pic->uv_stride;
      output_buffer->u.YUVA.a_stride = has_alpha ? pic->a_stride : 0;
      output_buffer->u.YUVA.y_size = pic->height * pic->y_stride;
      output_buffer->u.YUVA.u_size = (pic->height + 1) / 2 * pic->uv_stride;
      output_buffer->u.YUVA.v_size = (pic->height + 1) / 2 * pic->uv_stride;
      output_buffer->u.YUVA.a_size = pic->height * pic->a_stride;
    }
    output_buffer->is_external_memory = 1;

    status = DecodeWebP(data, data_size, &config);
    ok = (status == VP8_STATUS_OK);
    if (ok && !keep_alpha && pic->use_argb) {
      // Need to wipe out the alpha value, as requested.
      int x, y;
      uint32_t* argb = pic->argb;
      for (y = 0; y < pic->height; ++y) {
        for (x = 0; x < pic->width; ++x) argb[x] |= 0xff000000u;
        argb += pic->argb_stride;
      }
    }
  } while (0);   // <- so we can 'break' out of the loop

  if (status != VP8_STATUS_OK) {
    PrintWebPError("input data", status);
    ok = 0;
  }

  WebPFreeDecBuffer(output_buffer);

  if (ok && metadata != NULL) {
    ok = ExtractMetadata(data, data_size, metadata);
    if (!ok) {
      PrintWebPError("metadata", VP8_STATUS_BITSTREAM_ERROR);
    }
  }
  if (!ok) WebPPictureFree(pic);
  return ok;
}

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