[PATCH 4/8] windowscodecs: Move PNG CopyPixels to unix lib.
Esme Povirk
esme at codeweavers.com
Fri Oct 9 14:56:19 CDT 2020
Signed-off-by: Esme Povirk <esme at codeweavers.com>
---
dlls/windowscodecs/libpng.c | 54 ++++++++++++++++++++
dlls/windowscodecs/main.c | 65 -----------------------
dlls/windowscodecs/pngformat.c | 3 +-
dlls/windowscodecs/unix_iface.c | 8 +++
dlls/windowscodecs/unix_lib.c | 3 ++
dlls/windowscodecs/wincodecs_common.h | 71 ++++++++++++++++++++++++++
dlls/windowscodecs/wincodecs_private.h | 6 +++
7 files changed, 143 insertions(+), 67 deletions(-)
diff --git a/dlls/windowscodecs/libpng.c b/dlls/windowscodecs/libpng.c
index bed7ea72d65..397d2d371ef 100644
--- a/dlls/windowscodecs/libpng.c
+++ b/dlls/windowscodecs/libpng.c
@@ -60,6 +60,8 @@ MAKE_FUNCPTR(png_get_io_ptr);
MAKE_FUNCPTR(png_get_pHYs);
MAKE_FUNCPTR(png_get_PLTE);
MAKE_FUNCPTR(png_get_tRNS);
+MAKE_FUNCPTR(png_read_end);
+MAKE_FUNCPTR(png_read_image);
MAKE_FUNCPTR(png_read_info);
MAKE_FUNCPTR(png_set_bgr);
MAKE_FUNCPTR(png_set_crc_action);
@@ -107,6 +109,8 @@ static void *load_libpng(void)
LOAD_FUNCPTR(png_get_pHYs);
LOAD_FUNCPTR(png_get_PLTE);
LOAD_FUNCPTR(png_get_tRNS);
+ LOAD_FUNCPTR(png_read_end);
+ LOAD_FUNCPTR(png_read_image);
LOAD_FUNCPTR(png_read_info);
LOAD_FUNCPTR(png_set_bgr);
LOAD_FUNCPTR(png_set_crc_action);
@@ -130,6 +134,8 @@ struct png_decoder
{
struct decoder decoder;
struct decoder_frame decoder_frame;
+ UINT stride;
+ BYTE *image_bits;
};
static inline struct png_decoder *impl_from_decoder(struct decoder* iface)
@@ -185,6 +191,8 @@ HRESULT CDECL png_decoder_initialize(struct decoder *iface, IStream *stream, str
png_colorp png_palette;
int num_palette;
int i;
+ UINT image_size;
+ png_bytep *row_pointers=NULL;
png_ptr = ppng_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
@@ -385,6 +393,33 @@ HRESULT CDECL png_decoder_initialize(struct decoder *iface, IStream *stream, str
This->decoder_frame.num_colors = 0;
}
+ This->stride = (This->decoder_frame.width * This->decoder_frame.bpp + 7) / 8;
+ image_size = This->stride * This->decoder_frame.height;
+
+ This->image_bits = malloc(image_size);
+ if (!This->image_bits)
+ {
+ hr = E_OUTOFMEMORY;
+ goto end;
+ }
+
+ row_pointers = malloc(sizeof(png_bytep)*This->decoder_frame.height);
+ if (!row_pointers)
+ {
+ hr = E_OUTOFMEMORY;
+ goto end;
+ }
+
+ for (i=0; i<This->decoder_frame.height; i++)
+ row_pointers[i] = This->image_bits + i * This->stride;
+
+ ppng_read_image(png_ptr, row_pointers);
+
+ free(row_pointers);
+ row_pointers = NULL;
+
+ ppng_read_end(png_ptr, end_info);
+
st->flags = WICBitmapDecoderCapabilityCanDecodeAllImages |
WICBitmapDecoderCapabilityCanDecodeSomeImages |
WICBitmapDecoderCapabilityCanEnumerateMetadata;
@@ -394,6 +429,12 @@ HRESULT CDECL png_decoder_initialize(struct decoder *iface, IStream *stream, str
end:
ppng_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+ free(row_pointers);
+ if (FAILED(hr))
+ {
+ free(This->image_bits);
+ This->image_bits = NULL;
+ }
return hr;
}
@@ -404,16 +445,28 @@ HRESULT CDECL png_decoder_get_frame_info(struct decoder *iface, UINT frame, stru
return S_OK;
}
+HRESULT CDECL png_decoder_copy_pixels(struct decoder *iface, UINT frame,
+ const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer)
+{
+ struct png_decoder *This = impl_from_decoder(iface);
+
+ return copy_pixels(This->decoder_frame.bpp, This->image_bits,
+ This->decoder_frame.width, This->decoder_frame.height, This->stride,
+ prc, stride, buffersize, buffer);
+}
+
void CDECL png_decoder_destroy(struct decoder* iface)
{
struct png_decoder *This = impl_from_decoder(iface);
+ free(This->image_bits);
RtlFreeHeap(GetProcessHeap(), 0, This);
}
static const struct decoder_funcs png_decoder_vtable = {
png_decoder_initialize,
png_decoder_get_frame_info,
+ png_decoder_copy_pixels,
png_decoder_destroy
};
@@ -435,6 +488,7 @@ HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **res
}
This->decoder.vtable = &png_decoder_vtable;
+ This->image_bits = NULL;
*result = &This->decoder;
info->container_format = GUID_ContainerFormatPng;
diff --git a/dlls/windowscodecs/main.c b/dlls/windowscodecs/main.c
index 2d8b0336f3f..982c8ddfada 100644
--- a/dlls/windowscodecs/main.c
+++ b/dlls/windowscodecs/main.c
@@ -60,71 +60,6 @@ HRESULT WINAPI DllCanUnloadNow(void)
return S_FALSE;
}
-HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer,
- UINT srcwidth, UINT srcheight, INT srcstride,
- const WICRect *rc, UINT dststride, UINT dstbuffersize, BYTE *dstbuffer)
-{
- UINT bytesperrow;
- UINT row_offset; /* number of bits into the source rows where the data starts */
- WICRect rect;
-
- if (!rc)
- {
- rect.X = 0;
- rect.Y = 0;
- rect.Width = srcwidth;
- rect.Height = srcheight;
- rc = ▭
- }
- else
- {
- if (rc->X < 0 || rc->Y < 0 || rc->X+rc->Width > srcwidth || rc->Y+rc->Height > srcheight)
- return E_INVALIDARG;
- }
-
- bytesperrow = ((bpp * rc->Width)+7)/8;
-
- if (dststride < bytesperrow)
- return E_INVALIDARG;
-
- if ((dststride * (rc->Height-1)) + bytesperrow > dstbuffersize)
- return E_INVALIDARG;
-
- /* if the whole bitmap is copied and the buffer format matches then it's a matter of a single memcpy */
- if (rc->X == 0 && rc->Y == 0 && rc->Width == srcwidth && rc->Height == srcheight &&
- srcstride == dststride && srcstride == bytesperrow)
- {
- memcpy(dstbuffer, srcbuffer, srcstride * srcheight);
- return S_OK;
- }
-
- row_offset = rc->X * bpp;
-
- if (row_offset % 8 == 0)
- {
- /* everything lines up on a byte boundary */
- INT row;
- const BYTE *src;
- BYTE *dst;
-
- src = srcbuffer + (row_offset / 8) + srcstride * rc->Y;
- dst = dstbuffer;
- for (row=0; row < rc->Height; row++)
- {
- memcpy(dst, src, bytesperrow);
- src += srcstride;
- dst += dststride;
- }
- return S_OK;
- }
- else
- {
- /* we have to do a weird bitwise copy. eww. */
- FIXME("cannot reliably copy bitmap data if bpp < 8\n");
- return E_FAIL;
- }
-}
-
HRESULT configure_write_source(IWICBitmapFrameEncode *iface,
IWICBitmapSource *source, const WICRect *prc,
const WICPixelFormatGUID *format,
diff --git a/dlls/windowscodecs/pngformat.c b/dlls/windowscodecs/pngformat.c
index d10afcedbc3..834cc81d306 100644
--- a/dlls/windowscodecs/pngformat.c
+++ b/dlls/windowscodecs/pngformat.c
@@ -1051,8 +1051,7 @@ static HRESULT WINAPI PngDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface,
PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer);
- return copy_pixels(This->bpp, This->image_bits,
- This->width, This->height, This->stride,
+ return decoder_copy_pixels(This->png_decoder, 0,
prc, cbStride, cbBufferSize, pbBuffer);
}
diff --git a/dlls/windowscodecs/unix_iface.c b/dlls/windowscodecs/unix_iface.c
index cf66fbd964d..46bcacff941 100644
--- a/dlls/windowscodecs/unix_iface.c
+++ b/dlls/windowscodecs/unix_iface.c
@@ -78,6 +78,13 @@ HRESULT CDECL decoder_wrapper_get_frame_info(struct decoder* iface, UINT frame,
return unix_funcs->decoder_get_frame_info(This->unix_decoder, frame, info);
}
+HRESULT CDECL decoder_wrapper_copy_pixels(struct decoder* iface, UINT frame,
+ const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer)
+{
+ struct decoder_wrapper* This = impl_from_decoder(iface);
+ return unix_funcs->decoder_copy_pixels(This->unix_decoder, frame, prc, stride, buffersize, buffer);
+}
+
void CDECL decoder_wrapper_destroy(struct decoder* iface)
{
struct decoder_wrapper* This = impl_from_decoder(iface);
@@ -88,6 +95,7 @@ void CDECL decoder_wrapper_destroy(struct decoder* iface)
static const struct decoder_funcs decoder_wrapper_vtable = {
decoder_wrapper_initialize,
decoder_wrapper_get_frame_info,
+ decoder_wrapper_copy_pixels,
decoder_wrapper_destroy
};
diff --git a/dlls/windowscodecs/unix_lib.c b/dlls/windowscodecs/unix_lib.c
index 111a82dc637..5ab1cb342e6 100644
--- a/dlls/windowscodecs/unix_lib.c
+++ b/dlls/windowscodecs/unix_lib.c
@@ -41,6 +41,8 @@
#include "wine/debug.h"
+WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
+
#include "wincodecs_common.h"
static const struct win32_funcs *win32_funcs;
@@ -67,6 +69,7 @@ static const struct unix_funcs unix_funcs = {
decoder_create,
decoder_initialize,
decoder_get_frame_info,
+ decoder_copy_pixels,
decoder_destroy
};
diff --git a/dlls/windowscodecs/wincodecs_common.h b/dlls/windowscodecs/wincodecs_common.h
index ac8ae015c76..f116fb6fd8f 100644
--- a/dlls/windowscodecs/wincodecs_common.h
+++ b/dlls/windowscodecs/wincodecs_common.h
@@ -26,8 +26,79 @@ HRESULT CDECL decoder_get_frame_info(struct decoder *decoder, UINT frame, struct
return decoder->vtable->get_frame_info(decoder, frame, info);
}
+HRESULT CDECL decoder_copy_pixels(struct decoder *decoder, UINT frame,
+ const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer)
+{
+ return decoder->vtable->copy_pixels(decoder, frame, prc, stride, buffersize, buffer);
+}
+
void CDECL decoder_destroy(struct decoder *decoder)
{
decoder->vtable->destroy(decoder);
}
+HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer,
+ UINT srcwidth, UINT srcheight, INT srcstride,
+ const WICRect *rc, UINT dststride, UINT dstbuffersize, BYTE *dstbuffer)
+{
+ UINT bytesperrow;
+ UINT row_offset; /* number of bits into the source rows where the data starts */
+ WICRect rect;
+
+ if (!rc)
+ {
+ rect.X = 0;
+ rect.Y = 0;
+ rect.Width = srcwidth;
+ rect.Height = srcheight;
+ rc = ▭
+ }
+ else
+ {
+ if (rc->X < 0 || rc->Y < 0 || rc->X+rc->Width > srcwidth || rc->Y+rc->Height > srcheight)
+ return E_INVALIDARG;
+ }
+
+ bytesperrow = ((bpp * rc->Width)+7)/8;
+
+ if (dststride < bytesperrow)
+ return E_INVALIDARG;
+
+ if ((dststride * (rc->Height-1)) + bytesperrow > dstbuffersize)
+ return E_INVALIDARG;
+
+ /* if the whole bitmap is copied and the buffer format matches then it's a matter of a single memcpy */
+ if (rc->X == 0 && rc->Y == 0 && rc->Width == srcwidth && rc->Height == srcheight &&
+ srcstride == dststride && srcstride == bytesperrow)
+ {
+ memcpy(dstbuffer, srcbuffer, srcstride * srcheight);
+ return S_OK;
+ }
+
+ row_offset = rc->X * bpp;
+
+ if (row_offset % 8 == 0)
+ {
+ /* everything lines up on a byte boundary */
+ INT row;
+ const BYTE *src;
+ BYTE *dst;
+
+ src = srcbuffer + (row_offset / 8) + srcstride * rc->Y;
+ dst = dstbuffer;
+ for (row=0; row < rc->Height; row++)
+ {
+ memcpy(dst, src, bytesperrow);
+ src += srcstride;
+ dst += dststride;
+ }
+ return S_OK;
+ }
+ else
+ {
+ /* we have to do a weird bitwise copy. eww. */
+ FIXME("cannot reliably copy bitmap data if bpp < 8\n");
+ return E_FAIL;
+ }
+}
+
diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h
index 6d12b98bfc4..24cae3652f4 100644
--- a/dlls/windowscodecs/wincodecs_private.h
+++ b/dlls/windowscodecs/wincodecs_private.h
@@ -286,6 +286,8 @@ struct decoder_funcs
{
HRESULT (CDECL *initialize)(struct decoder* This, IStream *stream, struct decoder_stat *st);
HRESULT (CDECL *get_frame_info)(struct decoder* This, UINT frame, struct decoder_frame *info);
+ HRESULT (CDECL *copy_pixels)(struct decoder* This, UINT frame, const WICRect *prc,
+ UINT stride, UINT buffersize, BYTE *buffer);
void (CDECL *destroy)(struct decoder* This);
};
@@ -301,6 +303,8 @@ struct win32_funcs
HRESULT CDECL decoder_create(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result);
HRESULT CDECL decoder_initialize(struct decoder *This, IStream *stream, struct decoder_stat *st);
HRESULT CDECL decoder_get_frame_info(struct decoder* This, UINT frame, struct decoder_frame *info);
+HRESULT CDECL decoder_copy_pixels(struct decoder* This, UINT frame, const WICRect *prc,
+ UINT stride, UINT buffersize, BYTE *buffer);
void CDECL decoder_destroy(struct decoder *This);
HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result);
@@ -310,6 +314,8 @@ struct unix_funcs
HRESULT (CDECL *decoder_create)(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result);
HRESULT (CDECL *decoder_initialize)(struct decoder *This, IStream *stream, struct decoder_stat *st);
HRESULT (CDECL *decoder_get_frame_info)(struct decoder* This, UINT frame, struct decoder_frame *info);
+ HRESULT (CDECL *decoder_copy_pixels)(struct decoder* This, UINT frame, const WICRect *prc,
+ UINT stride, UINT buffersize, BYTE *buffer);
void (CDECL *decoder_destroy)(struct decoder* This);
};
--
2.17.1
More information about the wine-devel
mailing list