Esempio 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;
}
Esempio n. 2
0
HRESULT WINAPI IWICBitmapFrameDecode_GetColorContexts_Proxy_W(IWICBitmapFrameDecode *iface,
    UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
{
    return IWICBitmapFrameDecode_GetColorContexts(iface, cCount, ppIColorContexts, pcActualCount);
}
Esempio n. 3
0
static void test_decode_24bpp(void)
{
    IWICBitmapDecoder *decoder, *decoder2;
    IWICBitmapFrameDecode *framedecode;
    IWICMetadataQueryReader *queryreader;
    IWICColorContext *colorcontext;
    IWICBitmapSource *thumbnail;
    HRESULT hr;
    HGLOBAL hbmpdata;
    char *bmpdata;
    IStream *bmpstream;
    DWORD capability=0;
    GUID guidresult;
    UINT count=0, width=0, height=0;
    double dpiX, dpiY;
    BYTE imagedata[36] = {1};
    const BYTE expected_imagedata[36] = {
        255,0,255, 255,255,255,
        255,0,0,   255,255,0,
        0,0,0,     0,255,0};
    WICRect rc;

    hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER,
        &IID_IWICBitmapDecoder, (void**)&decoder);
    ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
    if (FAILED(hr)) return;

    hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_24bpp));
    ok(hbmpdata != 0, "GlobalAlloc failed\n");
    if (hbmpdata)
    {
        bmpdata = GlobalLock(hbmpdata);
        memcpy(bmpdata, testbmp_24bpp, sizeof(testbmp_24bpp));
        GlobalUnlock(hbmpdata);

        hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream);
        ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr);
        if (SUCCEEDED(hr))
        {
            hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad);
            ok(hr == S_OK || broken(hr == WINCODEC_ERR_BADIMAGE) /* XP */, "Initialize failed, hr=%x\n", hr);
            if (FAILED(hr))
            {
                win_skip("BMP decoder failed to initialize\n");
                GlobalFree(hbmpdata);
                IWICBitmapDecoder_Release(decoder);
                return;
            }

            hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult);
            ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr);
            ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n");

            hr = IWICBitmapDecoder_GetMetadataQueryReader(decoder, &queryreader);
            ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr);

            hr = IWICBitmapDecoder_GetColorContexts(decoder, 1, &colorcontext, &count);
            ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr);

            hr = IWICBitmapDecoder_GetThumbnail(decoder, &thumbnail);
            ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "expected WINCODEC_ERR_CODECNOTHUMBNAIL, got %x\n", hr);

            hr = IWICBitmapDecoder_GetPreview(decoder, &thumbnail);
            ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr);

            hr = IWICBitmapDecoder_GetFrameCount(decoder, &count);
            ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr);
            ok(count == 1, "unexpected count %u\n", count);

            hr = IWICBitmapDecoder_GetFrame(decoder, 1, &framedecode);
            ok(hr == E_INVALIDARG || hr == WINCODEC_ERR_FRAMEMISSING, "GetFrame returned %x\n", hr);

            hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode);
            ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr);
            if (SUCCEEDED(hr))
            {
                IWICImagingFactory *factory;
                IWICPalette *palette;

                hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height);
                ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr);
                ok(width == 2, "expected width=2, got %u\n", width);
                ok(height == 3, "expected height=2, got %u\n", height);

                hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY);
                ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr);
                ok(dpiX == 96.0, "expected dpiX=96.0, got %f\n", dpiX);
                ok(dpiY == 96.0, "expected dpiY=96.0, got %f\n", dpiY);

                hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult);
                ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr);
                ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n");

                hr = IWICBitmapFrameDecode_GetMetadataQueryReader(framedecode, &queryreader);
                ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr);

                hr = IWICBitmapFrameDecode_GetColorContexts(framedecode, 1, &colorcontext, &count);
                ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr);

                hr = IWICBitmapFrameDecode_GetThumbnail(framedecode, &thumbnail);
                ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "expected WINCODEC_ERR_CODECNOTHUMBNAIL, got %x\n", hr);

                hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
                    &IID_IWICImagingFactory, (void**)&factory);
                ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
                if (SUCCEEDED(hr))
                {
                    hr = IWICImagingFactory_CreatePalette(factory, &palette);
                    ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr);
                    if (SUCCEEDED(hr))
                    {
                        hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
                        ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr);

                        hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette);
                        ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr);

                        IWICPalette_Release(palette);
                    }

                    IWICImagingFactory_Release(factory);
                }

                rc.X = 0;
                rc.Y = 0;
                rc.Width = 3;
                rc.Height = 3;
                hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 6, sizeof(imagedata), imagedata);
                ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);

                rc.X = -1;
                rc.Y = 0;
                rc.Width = 2;
                rc.Height = 3;
                hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 6, sizeof(imagedata), imagedata);
                ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);

                rc.X = 0;
                rc.Y = 0;
                rc.Width = 2;
                rc.Height = 3;
                hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 4, sizeof(imagedata), imagedata);
                ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);

                rc.X = 0;
                rc.Y = 0;
                rc.Width = 2;
                rc.Height = 3;
                hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 4, 5, imagedata);
                ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);

                rc.X = 0;
                rc.Y = 0;
                rc.Width = 2;
                rc.Height = 3;
                hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 6, sizeof(imagedata), imagedata);
                ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr);
                ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n");

                hr = IWICBitmapFrameDecode_CopyPixels(framedecode, NULL, 6, sizeof(imagedata), imagedata);
                ok(SUCCEEDED(hr), "CopyPixels(rect=NULL) failed, hr=%x\n", hr);
                ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n");

                IWICBitmapFrameDecode_Release(framedecode);
            }

            /* cannot initialize twice */
            hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad);
            ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr);

            /* cannot querycapability after initialize */
            hr = IWICBitmapDecoder_QueryCapability(decoder, bmpstream, &capability);
            ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr);

            hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER,
                &IID_IWICBitmapDecoder, (void**)&decoder2);
            ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
            if (SUCCEEDED(hr))
            {
                hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability);
                ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr);
                ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages),
                    "unexpected capabilities: %x\n", capability);

                /* cannot initialize after querycapability */
                hr = IWICBitmapDecoder_Initialize(decoder2, bmpstream, WICDecodeMetadataCacheOnLoad);
                ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr);

                /* cannot querycapability twice */
                hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability);
                ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr);

                IWICBitmapDecoder_Release(decoder2);
            }

            IStream_Release(bmpstream);
        }

        GlobalFree(hbmpdata);
    }

    IWICBitmapDecoder_Release(decoder);
}
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);
}