Exemplo n.º 1
0
// 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 void test_color_contexts(void)
{
    HRESULT hr;
    IWICBitmapDecoder *decoder;
    IWICBitmapFrameDecode *frame;
    IWICColorContext *context;
    WICColorContextType type;
    UINT count, colorspace, size;
    WCHAR *tmpfile;
    BYTE *buffer;
    BOOL ret;

    decoder = create_decoder(png_no_color_profile, sizeof(png_no_color_profile));
    ok(decoder != 0, "Failed to load PNG image data\n");
    if (!decoder) return;

    /* global color context */
    hr = IWICBitmapDecoder_GetColorContexts(decoder, 0, NULL, NULL);
    ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#x\n", hr);

    count = 0xdeadbeef;
    hr = IWICBitmapDecoder_GetColorContexts(decoder, 0, NULL, &count);
    ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#x\n", hr);
    ok(count == 0xdeadbeef, "unexpected count %u\n", count);

    /* frame color context */
    hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
    ok(hr == S_OK, "GetFrame error %#x\n", hr);

    hr = IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, NULL);
    ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);

    count = 0xdeadbeef;
    hr = IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count);
    ok(hr == S_OK, "GetColorContexts error %#x\n", hr);
    ok(!count, "unexpected count %u\n", count);

    IWICBitmapFrameDecode_Release(frame);
    IWICBitmapDecoder_Release(decoder);

    decoder = create_decoder(png_color_profile, sizeof(png_color_profile));
    ok(decoder != 0, "Failed to load PNG image data\n");
    if (!decoder) return;

    /* global color context */
    count = 0xdeadbeef;
    hr = IWICBitmapDecoder_GetColorContexts(decoder, 0, NULL, &count);
    ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#x\n", hr);
    ok(count == 0xdeadbeef, "unexpected count %u\n", count);

    /* frame color context */
    hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
    ok(hr == S_OK, "GetFrame error %#x\n", hr);

    count = 0xdeadbeef;
    hr = IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count);
    ok(hr == S_OK, "GetColorContexts error %#x\n", hr);
    ok(count == 1, "unexpected count %u\n", count);

    hr = IWICImagingFactory_CreateColorContext(factory, NULL);
    ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);

    hr = IWICImagingFactory_CreateColorContext(factory, &context);
    ok(hr == S_OK, "CreateColorContext error %#x\n", hr);

    hr = IWICColorContext_GetType(context, NULL);
    ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);

    type = 0xdeadbeef;
    hr = IWICColorContext_GetType(context, &type);
    ok(hr == S_OK, "GetType error %#x\n", hr);
    ok(type == WICColorContextUninitialized, "unexpected type %u\n", type);

    hr = IWICColorContext_GetProfileBytes(context, 0, NULL, NULL);
    ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#x\n", hr);

    size = 0;
    hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size);
    ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#x\n", hr);
    ok(!size, "unexpected size %u\n", size);

    hr = IWICColorContext_GetExifColorSpace(context, NULL);
    ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);

    colorspace = 0xdeadbeef;
    hr = IWICColorContext_GetExifColorSpace(context, &colorspace);
    ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr);
    ok(colorspace == 0xffffffff, "unexpected color space %u\n", colorspace);

    hr = IWICColorContext_InitializeFromExifColorSpace(context, 0);
    ok(hr == S_OK, "InitializeFromExifColorSpace error %#x\n", hr);

    hr = IWICColorContext_InitializeFromExifColorSpace(context, 1);
    ok(hr == S_OK, "InitializeFromExifColorSpace error %#x\n", hr);

    hr = IWICColorContext_InitializeFromExifColorSpace(context, 2);
    ok(hr == S_OK, "InitializeFromExifColorSpace error %#x\n", hr);

    colorspace = 0xdeadbeef;
    hr = IWICColorContext_GetExifColorSpace(context, &colorspace);
    ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr);
    ok(colorspace == 2, "unexpected color space %u\n", colorspace);

    size = 0;
    hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size);
    ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#x\n", hr);
    ok(!size, "unexpected size %u\n", size);

    type = 0xdeadbeef;
    hr = IWICColorContext_GetType(context, &type);
    ok(hr == S_OK, "GetType error %#x\n", hr);
    ok(type == WICColorContextExifColorSpace, "unexpected type %u\n", type);

    hr = IWICBitmapFrameDecode_GetColorContexts(frame, count, &context, &count);
    ok(hr == WINCODEC_ERR_WRONGSTATE, "GetColorContexts error %#x\n", hr);

    IWICColorContext_Release(context);
    IWICBitmapFrameDecode_Release(frame);

    hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
    ok(hr == S_OK, "GetFrame error %#x\n", hr);

    hr = IWICImagingFactory_CreateColorContext(factory, &context);
    ok(hr == S_OK, "CreateColorContext error %#x\n", hr);

    count = 1;
    hr = IWICBitmapFrameDecode_GetColorContexts(frame, count, &context, &count);
    ok(hr == S_OK, "GetColorContexts error %#x\n", hr);

    hr = IWICColorContext_GetProfileBytes(context, 0, NULL, NULL);
    ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);

    size = 0;
    hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size);
    ok(hr == S_OK, "GetProfileBytes error %#x\n", hr);
    ok(size, "unexpected size %u\n", size);

    buffer = HeapAlloc(GetProcessHeap(), 0, size);
    hr = IWICColorContext_GetProfileBytes(context, size, buffer, &size);
    ok(hr == S_OK, "GetProfileBytes error %#x\n", hr);

    tmpfile = save_profile( buffer, size );
    HeapFree(GetProcessHeap(), 0, buffer);

    type = 0xdeadbeef;
    hr = IWICColorContext_GetType(context, &type);
    ok(hr == S_OK, "GetType error %#x\n", hr);
    ok(type == WICColorContextProfile, "unexpected type %u\n", type);

    colorspace = 0xdeadbeef;
    hr = IWICColorContext_GetExifColorSpace(context, &colorspace);
    ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr);
    ok(colorspace == 0xffffffff, "unexpected color space %u\n", colorspace);

    hr = IWICColorContext_InitializeFromExifColorSpace(context, 1);
    ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromExifColorSpace error %#x\n", hr);

    if (tmpfile)
    {
        hr = IWICColorContext_InitializeFromFilename(context, NULL);
        ok(hr == E_INVALIDARG, "InitializeFromFilename error %#x\n", hr);

        hr = IWICColorContext_InitializeFromFilename(context, tmpfile);
        ok(hr == S_OK, "InitializeFromFilename error %#x\n", hr);

        ret = DeleteFileW(tmpfile);
        ok(ret, "DeleteFileW failed %u\n", GetLastError());

        type = 0xdeadbeef;
        hr = IWICColorContext_GetType(context, &type);
        ok(hr == S_OK, "GetType error %#x\n", hr);
        ok(type == WICColorContextProfile, "unexpected type %u\n", type);

        colorspace = 0xdeadbeef;
        hr = IWICColorContext_GetExifColorSpace(context, &colorspace);
        ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr);
        ok(colorspace == 0xffffffff, "unexpected color space %u\n", colorspace);

        hr = IWICColorContext_InitializeFromExifColorSpace(context, 1);
        ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromExifColorSpace error %#x\n", hr);

        size = 0;
        hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size);
        ok(hr == S_OK, "GetProfileBytes error %#x\n", hr);
        ok(size, "unexpected size %u\n", size);

        buffer = HeapAlloc(GetProcessHeap(), 0, size);
        hr = IWICColorContext_GetProfileBytes(context, size, buffer, &size);
        ok(hr == S_OK, "GetProfileBytes error %#x\n", hr);

        HeapFree(GetProcessHeap(), 0, buffer);
        HeapFree(GetProcessHeap(), 0, tmpfile);
    }
    IWICColorContext_Release(context);
    IWICBitmapFrameDecode_Release(frame);
    IWICBitmapDecoder_Release(decoder);
}