From b64eb8a8d635f519f994b6bceea2a15d8f41dc5e Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Wed, 6 Feb 2013 13:51:32 +0100 Subject: [PATCH] windowscodecs: Implement IWICColorContext::InitializeFromFilename. --- dlls/windowscodecs/colorcontext.c | 69 +++++++++++++++++++++++++--- dlls/windowscodecs/tests/pngformat.c | 61 ++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 7 deletions(-) diff --git a/dlls/windowscodecs/colorcontext.c b/dlls/windowscodecs/colorcontext.c index 457b4db7013..ca4018468eb 100644 --- a/dlls/windowscodecs/colorcontext.c +++ b/dlls/windowscodecs/colorcontext.c @@ -96,27 +96,82 @@ static ULONG WINAPI ColorContext_Release(IWICColorContext *iface) return ref; } +static HRESULT load_profile(const WCHAR *filename, BYTE **profile, UINT *len) +{ + HANDLE handle; + DWORD count; + LARGE_INTEGER size; + BOOL ret; + + *len = 0; + *profile = NULL; + handle = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + if (handle == INVALID_HANDLE_VALUE) return HRESULT_FROM_WIN32(GetLastError()); + + if (!(GetFileSizeEx(handle, &size))) + { + CloseHandle(handle); + return HRESULT_FROM_WIN32(GetLastError()); + } + if (size.u.HighPart) + { + WARN("file too large\n"); + CloseHandle(handle); + return E_FAIL; + } + if (!(*profile = HeapAlloc(GetProcessHeap(), 0, size.u.LowPart))) + { + CloseHandle(handle); + return E_OUTOFMEMORY; + } + ret = ReadFile(handle, *profile, size.u.LowPart, &count, NULL); + CloseHandle(handle); + if (!ret) return HRESULT_FROM_WIN32(GetLastError()); + if (count != size.u.LowPart) return E_FAIL; + *len = count; + return S_OK; +} + static HRESULT WINAPI ColorContext_InitializeFromFilename(IWICColorContext *iface, LPCWSTR wzFilename) { - FIXME("(%p,%s)\n", iface, debugstr_w(wzFilename)); - return E_NOTIMPL; + ColorContext *This = impl_from_IWICColorContext(iface); + BYTE *profile; + UINT len; + HRESULT hr; + TRACE("(%p,%s)\n", iface, debugstr_w(wzFilename)); + + if (This->type != WICColorContextUninitialized && This->type != WICColorContextProfile) + return WINCODEC_ERR_WRONGSTATE; + + if (!wzFilename) return E_INVALIDARG; + + hr = load_profile(wzFilename, &profile, &len); + if (FAILED(hr)) return hr; + + HeapFree(GetProcessHeap(), 0, This->profile); + This->profile = profile; + This->profile_len = len; + This->type = WICColorContextProfile; + + return S_OK; } static HRESULT WINAPI ColorContext_InitializeFromMemory(IWICColorContext *iface, const BYTE *pbBuffer, UINT cbBufferSize) { ColorContext *This = impl_from_IWICColorContext(iface); + BYTE *profile; TRACE("(%p,%p,%u)\n", iface, pbBuffer, cbBufferSize); - if (This->type != WICColorContextUninitialized) + if (This->type != WICColorContextUninitialized && This->type != WICColorContextProfile) return WINCODEC_ERR_WRONGSTATE; - HeapFree(GetProcessHeap(), 0, This->profile); - if (!(This->profile = HeapAlloc(GetProcessHeap(), 0, cbBufferSize))) - return E_OUTOFMEMORY; + if (!(profile = HeapAlloc(GetProcessHeap(), 0, cbBufferSize))) return E_OUTOFMEMORY; + memcpy(profile, pbBuffer, cbBufferSize); - memcpy(This->profile, pbBuffer, cbBufferSize); + HeapFree(GetProcessHeap(), 0, This->profile); + This->profile = profile; This->profile_len = cbBufferSize; This->type = WICColorContextProfile; diff --git a/dlls/windowscodecs/tests/pngformat.c b/dlls/windowscodecs/tests/pngformat.c index 3f4e85559a4..b21f5f7e45a 100644 --- a/dlls/windowscodecs/tests/pngformat.c +++ b/dlls/windowscodecs/tests/pngformat.c @@ -317,6 +317,27 @@ static IWICBitmapDecoder *create_decoder(const void *image_data, UINT image_size return decoder; } +static WCHAR *save_profile( BYTE *buffer, UINT size ) +{ + static const WCHAR tstW[] = {'t','s','t',0}; + WCHAR path[MAX_PATH], filename[MAX_PATH], *ret; + HANDLE handle; + DWORD count; + + GetTempPathW(MAX_PATH, path); + GetTempFileNameW(path, tstW, 0, filename); + + handle = CreateFileW(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); + if (handle == INVALID_HANDLE_VALUE) return NULL; + + WriteFile(handle, buffer, size, &count, NULL); + CloseHandle( handle ); + + ret = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1) * sizeof(WCHAR)); + lstrcpyW(ret, filename); + return ret; +} + static void test_color_contexts(void) { HRESULT hr; @@ -325,7 +346,9 @@ static void test_color_contexts(void) 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"); @@ -453,6 +476,8 @@ static void test_color_contexts(void) 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; @@ -468,6 +493,42 @@ static void test_color_contexts(void) 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);