// Copyright 2013 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.
// -----------------------------------------------------------------------------
//
// Windows Imaging Component (WIC) decode.

#include "./wicdec.h"

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

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

#ifdef HAVE_WINCODEC_H
#ifdef __MINGW32__
#define INITGUID  // Without this GUIDs are declared extern and fail to link
#endif
#define CINTERFACE
#define COBJMACROS
#define _WIN32_IE 0x500  // Workaround bug in shlwapi.h when compiling C++
                         // code with COBJMACROS.
#include <ole2.h>  // CreateStreamOnHGlobal()
#include <shlwapi.h>
#include <windows.h>
#include <wincodec.h>

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

#define IFS(fn)                                                     \
  do {                                                              \
    if (SUCCEEDED(hr)) {                                            \
      hr = (fn);                                                    \
      if (FAILED(hr)) fprintf(stderr, #fn " failed %08lx\n", hr);   \
    }                                                               \
  } while (0)

// modified version of DEFINE_GUID from guiddef.h.
#define WEBP_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
  static const GUID name = \
      { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }

#ifdef __cplusplus
#define MAKE_REFGUID(x) (x)
#else
#define MAKE_REFGUID(x) &(x)
#endif

typedef struct WICFormatImporter {
  const GUID* pixel_format;
  int bytes_per_pixel;
  int (*import)(WebPPicture* const, const uint8_t* const, int);
} WICFormatImporter;

// From Microsoft SDK 7.0a -- wincodec.h
// Create local copies for compatibility when building against earlier
// versions of the SDK.
WEBP_DEFINE_GUID(GUID_WICPixelFormat24bppBGR_,
                 0x6fddc324, 0x4e03, 0x4bfe,
                 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0c);
WEBP_DEFINE_GUID(GUID_WICPixelFormat24bppRGB_,
                 0x6fddc324, 0x4e03, 0x4bfe,
                 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0d);
WEBP_DEFINE_GUID(GUID_WICPixelFormat32bppBGRA_,
                 0x6fddc324, 0x4e03, 0x4bfe,
                 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0f);
WEBP_DEFINE_GUID(GUID_WICPixelFormat32bppRGBA_,
                 0xf5c7ad2d, 0x6a8d, 0x43dd,
                 0xa7, 0xa8, 0xa2, 0x99, 0x35, 0x26, 0x1a, 0xe9);
WEBP_DEFINE_GUID(GUID_WICPixelFormat64bppBGRA_,
                 0x1562ff7c, 0xd352, 0x46f9,
                 0x97, 0x9e, 0x42, 0x97, 0x6b, 0x79, 0x22, 0x46);
WEBP_DEFINE_GUID(GUID_WICPixelFormat64bppRGBA_,
                 0x6fddc324, 0x4e03, 0x4bfe,
                 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x16);

static HRESULT OpenInputStream(const char* filename, IStream** stream) {
  HRESULT hr = S_OK;
  if (!strcmp(filename, "-")) {
    const uint8_t* data = NULL;
    size_t data_size = 0;
    const int ok = ImgIoUtilReadFile(filename, &data, &data_size);
    if (ok) {
      HGLOBAL image = GlobalAlloc(GMEM_MOVEABLE, data_size);
      if (image != NULL) {
        void* const image_mem = GlobalLock(image);
        if (image_mem != NULL) {
          memcpy(image_mem, data, data_size);
          GlobalUnlock(image);
          IFS(CreateStreamOnHGlobal(image, TRUE, stream));
        } else {
          hr = E_FAIL;
        }
      } else {
        hr = E_OUTOFMEMORY;
      }
      free((void*)data);
    } else {
      hr = E_FAIL;
    }
  } else {
    IFS(SHCreateStreamOnFileA(filename, STGM_READ, stream));
  }

  if (FAILED(hr)) {
    fprintf(stderr, "Error opening input file %s (%08lx)\n", filename, hr);
  }
  return hr;
}

// -----------------------------------------------------------------------------
// Metadata processing

// Stores the first non-zero sized color profile from 'frame' to 'iccp'.
// Returns an HRESULT to indicate success or failure. The caller is responsible
// for freeing 'iccp->bytes' in either case.
static HRESULT ExtractICCP(IWICImagingFactory* const factory,
                           IWICBitmapFrameDecode* const frame,
                           MetadataPayload* const iccp) {
  HRESULT hr = S_OK;
  UINT i, count;
  IWICColorContext** color_contexts;

  IFS(IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count));
  if (FAILED(hr) || count == 0) return hr;

  color_contexts = (IWICColorContext**)calloc(count, sizeof(*color_contexts));
  if (color_contexts == NULL) return E_OUTOFMEMORY;
  for (i = 0; SUCCEEDED(hr) && i < count; ++i) {
    IFS(IWICImagingFactory_CreateColorContext(factory, &color_contexts[i]));
  }

  if (SUCCEEDED(hr)) {
    UINT num_color_contexts;
    IFS(IWICBitmapFrameDecode_GetColorContexts(frame,
                                               count, color_contexts,
                                               &num_color_contexts));
    assert(FAILED(hr) || num_color_contexts <= count);
    for (i = 0; SUCCEEDED(hr) && i < num_color_contexts; ++i) {
      WICColorContextType type;
      IFS(IWICColorContext_GetType(color_contexts[i], &type));
      if (SUCCEEDED(hr) && type == WICColorContextProfile) {
        UINT size;
        IFS(IWICColorContext_GetProfileBytes(color_contexts[i],
                                             0, NULL, &size));
        if (SUCCEEDED(hr) && size > 0) {
          iccp->bytes = (uint8_t*)malloc(size);
          if (iccp->bytes == NULL) {
            hr = E_OUTOFMEMORY;
            break;
          }
          iccp->size = size;
          IFS(IWICColorContext_GetProfileBytes(color_contexts[i],
                                               (UINT)iccp->size, iccp->bytes,
                                               &size));
          if (SUCCEEDED(hr) && size != iccp->size) {
            fprintf(stderr, "Warning! ICC profile size (%u) != expected (%u)\n",
                    size, (uint32_t)iccp->size);
            iccp->size = size;
          }
          break;
        }
      }
    }
  }
  for (i = 0; i < count; ++i) {
    if (color_contexts[i] != NULL) IUnknown_Release(color_contexts[i]);
  }
  free(color_contexts);
  return hr;
}

static HRESULT ExtractMetadata(IWICImagingFactory* const factory,
                               IWICBitmapFrameDecode* const frame,
                               Metadata* const metadata) {
  // TODO(jzern): add XMP/EXIF extraction.
  const HRESULT hr = ExtractICCP(factory, frame, &metadata->iccp);
  if (FAILED(hr)) MetadataFree(metadata);
  return hr;
}

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

static int HasPalette(GUID pixel_format) {
  return (IsEqualGUID(MAKE_REFGUID(pixel_format),
                      MAKE_REFGUID(GUID_WICPixelFormat1bppIndexed)) ||
          IsEqualGUID(MAKE_REFGUID(pixel_format),
                      MAKE_REFGUID(GUID_WICPixelFormat2bppIndexed)) ||
          IsEqualGUID(MAKE_REFGUID(pixel_format),
                      MAKE_REFGUID(GUID_WICPixelFormat4bppIndexed)) ||
          IsEqualGUID(MAKE_REFGUID(pixel_format),
                      MAKE_REFGUID(GUID_WICPixelFormat8bppIndexed)));
}

static int HasAlpha(IWICImagingFactory* const factory,
                    IWICBitmapDecoder* const decoder,
                    IWICBitmapFrameDecode* const frame,
                    GUID pixel_format) {
  int has_alpha;
  if (HasPalette(pixel_format)) {
    IWICPalette* frame_palette = NULL;
    IWICPalette* global_palette = NULL;
    BOOL frame_palette_has_alpha = FALSE;
    BOOL global_palette_has_alpha = FALSE;

    // A palette may exist at the frame or container level,
    // check IWICPalette::HasAlpha() for both if present.
    if (SUCCEEDED(IWICImagingFactory_CreatePalette(factory, &frame_palette)) &&
        SUCCEEDED(IWICBitmapFrameDecode_CopyPalette(frame, frame_palette))) {
      IWICPalette_HasAlpha(frame_palette, &frame_palette_has_alpha);
    }
    if (SUCCEEDED(IWICImagingFactory_CreatePalette(factory, &global_palette)) &&
        SUCCEEDED(IWICBitmapDecoder_CopyPalette(decoder, global_palette))) {
      IWICPalette_HasAlpha(global_palette, &global_palette_has_alpha);
    }
    has_alpha = frame_palette_has_alpha || global_palette_has_alpha;

    if (frame_palette != NULL) IUnknown_Release(frame_palette);
    if (global_palette != NULL) IUnknown_Release(global_palette);
  } else {
    has_alpha = IsEqualGUID(MAKE_REFGUID(pixel_format),
                            MAKE_REFGUID(GUID_WICPixelFormat32bppRGBA_)) ||
                IsEqualGUID(MAKE_REFGUID(pixel_format),
                            MAKE_REFGUID(GUID_WICPixelFormat32bppBGRA_)) ||
                IsEqualGUID(MAKE_REFGUID(pixel_format),
                            MAKE_REFGUID(GUID_WICPixelFormat64bppRGBA_)) ||
                IsEqualGUID(MAKE_REFGUID(pixel_format),
                            MAKE_REFGUID(GUID_WICPixelFormat64bppBGRA_));
  }
  return has_alpha;
}

int ReadPictureWithWIC(const char* const filename,
                       WebPPicture* const pic, int keep_alpha,
                       Metadata* const metadata) {
  // From Microsoft SDK 6.0a -- ks.h
  // Define a local copy to avoid link errors under mingw.
  WEBP_DEFINE_GUID(GUID_NULL_, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  static const WICFormatImporter kAlphaFormatImporters[] = {
    { &GUID_WICPixelFormat32bppBGRA_, 4, WebPPictureImportBGRA },
    { &GUID_WICPixelFormat32bppRGBA_, 4, WebPPictureImportRGBA },
    { NULL, 0, NULL },
  };
  static const WICFormatImporter kNonAlphaFormatImporters[] = {
    { &GUID_WICPixelFormat24bppBGR_, 3, WebPPictureImportBGR },
    { &GUID_WICPixelFormat24bppRGB_, 3, WebPPictureImportRGB },
    { NULL, 0, NULL },
  };
  HRESULT hr = S_OK;
  IWICBitmapFrameDecode* frame = NULL;
  IWICFormatConverter* converter = NULL;
  IWICImagingFactory* factory = NULL;
  IWICBitmapDecoder* decoder = NULL;
  IStream* stream = NULL;
  UINT frame_count = 0;
  UINT width = 0, height = 0;
  BYTE* rgb = NULL;
  WICPixelFormatGUID src_pixel_format = GUID_WICPixelFormatUndefined;
  const WICFormatImporter* importer = NULL;
  GUID src_container_format = GUID_NULL_;
  static const GUID* kAlphaContainers[] = {
    &GUID_ContainerFormatBmp,
    &GUID_ContainerFormatPng,
    &GUID_ContainerFormatTiff,
    NULL
  };
  int has_alpha = 0;
  int64_t stride;

  if (filename == NULL || pic == NULL) return 0;

  IFS(CoInitialize(NULL));
  IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL,
                       CLSCTX_INPROC_SERVER,
                       MAKE_REFGUID(IID_IWICImagingFactory),
                       (LPVOID*)&factory));
  if (hr == REGDB_E_CLASSNOTREG) {
    fprintf(stderr,
            "Couldn't access Windows Imaging Component (are you running "
            "Windows XP SP3 or newer?). Most formats not available. "
            "Use -s for the available YUV input.\n");
  }
  // Prepare for image decoding.
  IFS(OpenInputStream(filename, &stream));
  IFS(IWICImagingFactory_CreateDecoderFromStream(
          factory, stream, NULL,
          WICDecodeMetadataCacheOnDemand, &decoder));
  IFS(IWICBitmapDecoder_GetFrameCount(decoder, &frame_count));
  if (SUCCEEDED(hr) && frame_count == 0) {
    fprintf(stderr, "No frame found in input file.\n");
    hr = E_FAIL;
  }
  IFS(IWICBitmapDecoder_GetFrame(decoder, 0, &frame));
  IFS(IWICBitmapFrameDecode_GetPixelFormat(frame, &src_pixel_format));
  IFS(IWICBitmapDecoder_GetContainerFormat(decoder, &src_container_format));

  if (SUCCEEDED(hr) && keep_alpha) {
    const GUID** guid;
    for (guid = kAlphaContainers; *guid != NULL; ++guid) {
      if (IsEqualGUID(MAKE_REFGUID(src_container_format),
                      MAKE_REFGUID(**guid))) {
        has_alpha = HasAlpha(factory, decoder, frame, src_pixel_format);
        break;
      }
    }
  }

  // Prepare for pixel format conversion (if necessary).
  IFS(IWICImagingFactory_CreateFormatConverter(factory, &converter));

  for (importer = has_alpha ? kAlphaFormatImporters : kNonAlphaFormatImporters;
       hr == S_OK && importer->import != NULL; ++importer) {
    BOOL can_convert;
    const HRESULT cchr = IWICFormatConverter_CanConvert(
        converter,
        MAKE_REFGUID(src_pixel_format),
        MAKE_REFGUID(*importer->pixel_format),
        &can_convert);
    if (SUCCEEDED(cchr) && can_convert) break;
  }
  if (importer->import == NULL) hr = E_FAIL;

  IFS(IWICFormatConverter_Initialize(converter, (IWICBitmapSource*)frame,
                                     importer->pixel_format,
                                     WICBitmapDitherTypeNone,
                                     NULL, 0.0, WICBitmapPaletteTypeCustom));

  // Decode.
  IFS(IWICFormatConverter_GetSize(converter, &width, &height));
  stride = (int64_t)importer->bytes_per_pixel * width * sizeof(*rgb);
  if (stride != (int)stride ||
      !ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) {
    hr = E_FAIL;
  }

  if (SUCCEEDED(hr)) {
    rgb = (BYTE*)malloc((size_t)stride * height);
    if (rgb == NULL)
      hr = E_OUTOFMEMORY;
  }
  IFS(IWICFormatConverter_CopyPixels(converter, NULL,
                                     (UINT)stride, (UINT)stride * height, rgb));

  // WebP conversion.
  if (SUCCEEDED(hr)) {
    int ok;
    pic->width = width;
    pic->height = height;
    pic->use_argb = 1;    // For WIC, we always force to argb
    ok = importer->import(pic, rgb, (int)stride);
    if (!ok) hr = E_FAIL;
  }
  if (SUCCEEDED(hr)) {
    if (metadata != NULL) {
      hr = ExtractMetadata(factory, frame, metadata);
      if (FAILED(hr)) {
        fprintf(stderr, "Error extracting image metadata using WIC!\n");
      }
    }
  }

  // Cleanup.
  if (converter != NULL) IUnknown_Release(converter);
  if (frame != NULL) IUnknown_Release(frame);
  if (decoder != NULL) IUnknown_Release(decoder);
  if (factory != NULL) IUnknown_Release(factory);
  if (stream != NULL) IUnknown_Release(stream);
  free(rgb);
  return SUCCEEDED(hr);
}
#else  // !HAVE_WINCODEC_H
int ReadPictureWithWIC(const char* const filename,
                       struct WebPPicture* const pic, int keep_alpha,
                       struct Metadata* const metadata) {
  (void)filename;
  (void)pic;
  (void)keep_alpha;
  (void)metadata;
  fprintf(stderr, "Windows Imaging Component (WIC) support not compiled. "
                  "Visual Studio and mingw-w64 builds support WIC. Make sure "
                  "wincodec.h detection is working correctly if using autoconf "
                  "and HAVE_WINCODEC_H is defined before building.\n");
  return 0;
}
#endif  // HAVE_WINCODEC_H

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