// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include "fuzz.h"
#include "webp/encode.h"
#include "webp/decode.h"

namespace {

const VP8CPUInfo default_VP8GetCPUInfo = VP8GetCPUInfo;

}  // namespace

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
  uint32_t bit_pos = 0;

  ExtractAndDisableOptimizations(default_VP8GetCPUInfo, data, size, &bit_pos);

  // Init the source picture.
  WebPPicture pic;
  if (!WebPPictureInit(&pic)) {
    fprintf(stderr, "WebPPictureInit failed.\n");
    abort();
  }
  pic.use_argb = Extract(1, data, size, &bit_pos);

  // Read the source picture.
  if (!ExtractSourcePicture(&pic, data, size, &bit_pos)) {
    fprintf(stderr, "Can't read input image.\n");
    WebPPictureFree(&pic);
    abort();
  }

  // Crop and scale.
  if (!ExtractAndCropOrScale(&pic, data, size, &bit_pos)) {
    fprintf(stderr, "ExtractAndCropOrScale failed.");
    WebPPictureFree(&pic);
    abort();
  }

  // Extract a configuration from the packed bits.
  WebPConfig config;
  if (!ExtractWebPConfig(&config, data, size, &bit_pos)) {
    fprintf(stderr, "ExtractWebPConfig failed.\n");
    abort();
  }
  // Skip slow settings on big images, it's likely to timeout.
  if (pic.width * pic.height > 32 * 32) {
    if (config.lossless) {
      if (config.quality > 99.0f && config.method >= 5) {
        config.quality = 99.0f;
        config.method = 5;
      }
    } else {
      if (config.quality > 99.0f && config.method == 6) {
        config.quality = 99.0f;
      }
    }
    if (config.alpha_quality == 100 && config.method == 6) {
      config.alpha_quality = 99;
    }
  }

  // Encode.
  WebPMemoryWriter memory_writer;
  WebPMemoryWriterInit(&memory_writer);
  pic.writer = WebPMemoryWrite;
  pic.custom_ptr = &memory_writer;
  if (!WebPEncode(&config, &pic)) {
    fprintf(stderr, "WebPEncode failed. Error code: %d\n", pic.error_code);
    WebPMemoryWriterClear(&memory_writer);
    WebPPictureFree(&pic);
    abort();
  }

  // Try decoding the result.
  int w, h;
  const uint8_t* const out_data = memory_writer.mem;
  const size_t out_size = memory_writer.size;
  uint8_t* const rgba = WebPDecodeBGRA(out_data, out_size, &w, &h);
  if (rgba == nullptr || w != pic.width || h != pic.height) {
    fprintf(stderr, "WebPDecodeBGRA failed.\n");
    WebPFree(rgba);
    WebPMemoryWriterClear(&memory_writer);
    WebPPictureFree(&pic);
    abort();
  }

  // Compare the results if exact encoding.
  if (pic.use_argb && config.lossless && config.near_lossless == 100) {
    const uint32_t* src1 = (const uint32_t*)rgba;
    const uint32_t* src2 = pic.argb;
    for (int y = 0; y < h; ++y, src1 += w, src2 += pic.argb_stride) {
      for (int x = 0; x < w; ++x) {
        uint32_t v1 = src1[x], v2 = src2[x];
        if (!config.exact) {
          if ((v1 & 0xff000000u) == 0 || (v2 & 0xff000000u) == 0) {
            // Only keep alpha for comparison of fully transparent area.
            v1 &= 0xff000000u;
            v2 &= 0xff000000u;
          }
        }
        if (v1 != v2) {
          fprintf(stderr, "Lossless compression failed pixel-exactness.\n");
          WebPFree(rgba);
          WebPMemoryWriterClear(&memory_writer);
          WebPPictureFree(&pic);
          abort();
        }
      }
    }
  }

  WebPFree(rgba);
  WebPMemoryWriterClear(&memory_writer);
  WebPPictureFree(&pic);
  return 0;
}
