Commit 980e6650 authored by Esme Povirk's avatar Esme Povirk Committed by Alexandre Julliard

windowscodecs: Use unix lib to get PNG color contexts.

parent 70ea6485
......@@ -54,6 +54,7 @@ MAKE_FUNCPTR(png_error);
MAKE_FUNCPTR(png_get_bit_depth);
MAKE_FUNCPTR(png_get_color_type);
MAKE_FUNCPTR(png_get_error_ptr);
MAKE_FUNCPTR(png_get_iCCP);
MAKE_FUNCPTR(png_get_image_height);
MAKE_FUNCPTR(png_get_image_width);
MAKE_FUNCPTR(png_get_io_ptr);
......@@ -105,6 +106,7 @@ static void *load_libpng(void)
LOAD_FUNCPTR(png_get_error_ptr);
LOAD_FUNCPTR(png_get_image_height);
LOAD_FUNCPTR(png_get_image_width);
LOAD_FUNCPTR(png_get_iCCP);
LOAD_FUNCPTR(png_get_io_ptr);
LOAD_FUNCPTR(png_get_pHYs);
LOAD_FUNCPTR(png_get_PLTE);
......@@ -137,6 +139,8 @@ struct png_decoder
struct decoder_frame decoder_frame;
UINT stride;
BYTE *image_bits;
BYTE *color_profile;
DWORD color_profile_len;
};
static inline struct png_decoder *impl_from_decoder(struct decoder* iface)
......@@ -194,6 +198,10 @@ HRESULT CDECL png_decoder_initialize(struct decoder *iface, IStream *stream, str
int i;
UINT image_size;
png_bytep *row_pointers=NULL;
png_charp cp_name;
png_bytep cp_profile;
png_uint_32 cp_len;
int cp_compression;
png_ptr = ppng_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
......@@ -351,6 +359,22 @@ HRESULT CDECL png_decoder_initialize(struct decoder *iface, IStream *stream, str
This->decoder_frame.dpix = This->decoder_frame.dpiy = 96.0;
}
ret = ppng_get_iCCP(png_ptr, info_ptr, &cp_name, &cp_compression, &cp_profile, &cp_len);
if (ret)
{
This->decoder_frame.num_color_contexts = 1;
This->color_profile_len = cp_len;
This->color_profile = malloc(cp_len);
if (!This->color_profile)
{
hr = E_OUTOFMEMORY;
goto end;
}
memcpy(This->color_profile, cp_profile, cp_len);
}
else
This->decoder_frame.num_color_contexts = 0;
if (color_type == PNG_COLOR_TYPE_PALETTE)
{
ret = ppng_get_PLTE(png_ptr, info_ptr, &png_palette, &num_palette);
......@@ -437,6 +461,8 @@ end:
{
free(This->image_bits);
This->image_bits = NULL;
free(This->color_profile);
This->color_profile = NULL;
}
return hr;
}
......@@ -531,11 +557,28 @@ end:
return hr;
}
HRESULT CDECL png_decoder_get_color_context(struct decoder* iface, UINT frame, UINT num,
BYTE **data, DWORD *datasize)
{
struct png_decoder *This = impl_from_decoder(iface);
*data = RtlAllocateHeap(GetProcessHeap(), 0, This->color_profile_len);
*datasize = This->color_profile_len;
if (!*data)
return E_OUTOFMEMORY;
memcpy(*data, This->color_profile, This->color_profile_len);
return S_OK;
}
void CDECL png_decoder_destroy(struct decoder* iface)
{
struct png_decoder *This = impl_from_decoder(iface);
free(This->image_bits);
free(This->color_profile);
RtlFreeHeap(GetProcessHeap(), 0, This);
}
......@@ -544,6 +587,7 @@ static const struct decoder_funcs png_decoder_vtable = {
png_decoder_get_frame_info,
png_decoder_copy_pixels,
png_decoder_get_metadata_blocks,
png_decoder_get_color_context,
png_decoder_destroy
};
......@@ -566,6 +610,7 @@ HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **res
This->decoder.vtable = &png_decoder_vtable;
This->image_bits = NULL;
This->color_profile = NULL;
*result = &This->decoder;
info->container_format = GUID_ContainerFormatPng;
......
......@@ -976,37 +976,34 @@ static HRESULT WINAPI PngDecoder_Frame_GetColorContexts(IWICBitmapFrameDecode *i
UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
{
PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
png_charp name;
HRESULT hr=S_OK;
BYTE *profile;
png_uint_32 len;
int compression_type;
HRESULT hr;
DWORD profile_len;
TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
if (!pcActualCount) return E_INVALIDARG;
EnterCriticalSection(&This->lock);
*pcActualCount = This->decoder_frame.num_color_contexts;
if (ppng_get_iCCP(This->png_ptr, This->info_ptr, &name, &compression_type, (void *)&profile, &len))
if (This->decoder_frame.num_color_contexts && cCount && ppIColorContexts)
{
if (cCount && ppIColorContexts)
EnterCriticalSection(&This->lock);
hr = decoder_get_color_context(This->png_decoder, 0, 0,
&profile, &profile_len);
LeaveCriticalSection(&This->lock);
if (SUCCEEDED(hr))
{
hr = IWICColorContext_InitializeFromMemory(*ppIColorContexts, profile, len);
if (FAILED(hr))
{
LeaveCriticalSection(&This->lock);
return hr;
}
hr = IWICColorContext_InitializeFromMemory(*ppIColorContexts, profile, profile_len);
HeapFree(GetProcessHeap(), 0, profile);
}
*pcActualCount = 1;
}
else
*pcActualCount = 0;
LeaveCriticalSection(&This->lock);
return S_OK;
return hr;
}
static HRESULT WINAPI PngDecoder_Frame_GetThumbnail(IWICBitmapFrameDecode *iface,
......
......@@ -92,6 +92,13 @@ HRESULT CDECL decoder_wrapper_get_metadata_blocks(struct decoder* iface,
return unix_funcs->decoder_get_metadata_blocks(This->unix_decoder, frame, count, blocks);
}
HRESULT CDECL decoder_wrapper_get_color_context(struct decoder* iface,
UINT frame, UINT num, BYTE **data, DWORD *datasize)
{
struct decoder_wrapper* This = impl_from_decoder(iface);
return unix_funcs->decoder_get_color_context(This->unix_decoder, frame, num, data, datasize);
}
void CDECL decoder_wrapper_destroy(struct decoder* iface)
{
struct decoder_wrapper* This = impl_from_decoder(iface);
......@@ -104,6 +111,7 @@ static const struct decoder_funcs decoder_wrapper_vtable = {
decoder_wrapper_get_frame_info,
decoder_wrapper_copy_pixels,
decoder_wrapper_get_metadata_blocks,
decoder_wrapper_get_color_context,
decoder_wrapper_destroy
};
......
......@@ -71,6 +71,7 @@ static const struct unix_funcs unix_funcs = {
decoder_get_frame_info,
decoder_copy_pixels,
decoder_get_metadata_blocks,
decoder_get_color_context,
decoder_destroy
};
......
......@@ -37,6 +37,12 @@ HRESULT CDECL decoder_get_metadata_blocks(struct decoder *decoder, UINT frame, U
return decoder->vtable->get_metadata_blocks(decoder, frame, count, blocks);
}
HRESULT CDECL decoder_get_color_context(struct decoder *decoder, UINT frame,
UINT num, BYTE **data, DWORD *datasize)
{
return decoder->vtable->get_color_context(decoder, frame, num, data, datasize);
}
void CDECL decoder_destroy(struct decoder *decoder)
{
decoder->vtable->destroy(decoder);
......
......@@ -275,6 +275,7 @@ struct decoder_frame
UINT width, height;
UINT bpp;
double dpix, dpiy;
DWORD num_color_contexts;
DWORD num_colors;
WICColor palette[256];
};
......@@ -299,6 +300,8 @@ struct decoder_funcs
UINT stride, UINT buffersize, BYTE *buffer);
HRESULT (CDECL *get_metadata_blocks)(struct decoder* This, UINT frame, UINT *count,
struct decoder_block **blocks);
HRESULT (CDECL *get_color_context)(struct decoder* This, UINT frame, UINT num,
BYTE **data, DWORD *datasize);
void (CDECL *destroy)(struct decoder* This);
};
......@@ -318,6 +321,8 @@ HRESULT CDECL decoder_copy_pixels(struct decoder* This, UINT frame, const WICRec
UINT stride, UINT buffersize, BYTE *buffer);
HRESULT CDECL decoder_get_metadata_blocks(struct decoder* This, UINT frame, UINT *count,
struct decoder_block **blocks);
HRESULT CDECL decoder_get_color_context(struct decoder* This, UINT frame, UINT num,
BYTE **data, DWORD *datasize);
void CDECL decoder_destroy(struct decoder *This);
HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result);
......@@ -331,6 +336,8 @@ struct unix_funcs
UINT stride, UINT buffersize, BYTE *buffer);
HRESULT (CDECL *decoder_get_metadata_blocks)(struct decoder* This, UINT frame, UINT *count,
struct decoder_block **blocks);
HRESULT (CDECL *decoder_get_color_context)(struct decoder* This, UINT frame, UINT num,
BYTE **data, DWORD *datasize);
void (CDECL *decoder_destroy)(struct decoder* This);
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment