[PATCH 6/8] windowscodecs: Use unix lib to get PNG color contexts.
Esme Povirk
esme at codeweavers.com
Fri Oct 9 14:56:21 CDT 2020
Signed-off-by: Esme Povirk <esme at codeweavers.com>
---
dlls/windowscodecs/libpng.c | 45 ++++++++++++++++++++++++++
dlls/windowscodecs/pngformat.c | 35 +++++++++-----------
dlls/windowscodecs/unix_iface.c | 8 +++++
dlls/windowscodecs/unix_lib.c | 1 +
dlls/windowscodecs/wincodecs_common.h | 6 ++++
dlls/windowscodecs/wincodecs_private.h | 7 ++++
6 files changed, 83 insertions(+), 19 deletions(-)
diff --git a/dlls/windowscodecs/libpng.c b/dlls/windowscodecs/libpng.c
index 8a4db91f2a9..36151e94f1b 100644
--- a/dlls/windowscodecs/libpng.c
+++ b/dlls/windowscodecs/libpng.c
@@ -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;
diff --git a/dlls/windowscodecs/pngformat.c b/dlls/windowscodecs/pngformat.c
index 1d696a4fe01..efd5f6ab2c1 100644
--- a/dlls/windowscodecs/pngformat.c
+++ b/dlls/windowscodecs/pngformat.c
@@ -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,
diff --git a/dlls/windowscodecs/unix_iface.c b/dlls/windowscodecs/unix_iface.c
index 8d22b49ba22..cdc92a7d160 100644
--- a/dlls/windowscodecs/unix_iface.c
+++ b/dlls/windowscodecs/unix_iface.c
@@ -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
};
diff --git a/dlls/windowscodecs/unix_lib.c b/dlls/windowscodecs/unix_lib.c
index 58c68018430..217a5a2e63a 100644
--- a/dlls/windowscodecs/unix_lib.c
+++ b/dlls/windowscodecs/unix_lib.c
@@ -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
};
diff --git a/dlls/windowscodecs/wincodecs_common.h b/dlls/windowscodecs/wincodecs_common.h
index 5489a055a27..b5d7b645638 100644
--- a/dlls/windowscodecs/wincodecs_common.h
+++ b/dlls/windowscodecs/wincodecs_common.h
@@ -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);
diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h
index 3c0b73e893f..e5294b8cf1a 100644
--- a/dlls/windowscodecs/wincodecs_private.h
+++ b/dlls/windowscodecs/wincodecs_private.h
@@ -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);
};
--
2.17.1
More information about the wine-devel
mailing list