Commit 53ce545e authored by Esme Povirk's avatar Esme Povirk Committed by Alexandre Julliard

windowscodecs: Move PNG CopyPixels to unix lib.

parent 8b849e81
...@@ -60,6 +60,8 @@ MAKE_FUNCPTR(png_get_io_ptr); ...@@ -60,6 +60,8 @@ MAKE_FUNCPTR(png_get_io_ptr);
MAKE_FUNCPTR(png_get_pHYs); MAKE_FUNCPTR(png_get_pHYs);
MAKE_FUNCPTR(png_get_PLTE); MAKE_FUNCPTR(png_get_PLTE);
MAKE_FUNCPTR(png_get_tRNS); MAKE_FUNCPTR(png_get_tRNS);
MAKE_FUNCPTR(png_read_end);
MAKE_FUNCPTR(png_read_image);
MAKE_FUNCPTR(png_read_info); MAKE_FUNCPTR(png_read_info);
MAKE_FUNCPTR(png_set_bgr); MAKE_FUNCPTR(png_set_bgr);
MAKE_FUNCPTR(png_set_crc_action); MAKE_FUNCPTR(png_set_crc_action);
...@@ -107,6 +109,8 @@ static void *load_libpng(void) ...@@ -107,6 +109,8 @@ static void *load_libpng(void)
LOAD_FUNCPTR(png_get_pHYs); LOAD_FUNCPTR(png_get_pHYs);
LOAD_FUNCPTR(png_get_PLTE); LOAD_FUNCPTR(png_get_PLTE);
LOAD_FUNCPTR(png_get_tRNS); LOAD_FUNCPTR(png_get_tRNS);
LOAD_FUNCPTR(png_read_end);
LOAD_FUNCPTR(png_read_image);
LOAD_FUNCPTR(png_read_info); LOAD_FUNCPTR(png_read_info);
LOAD_FUNCPTR(png_set_bgr); LOAD_FUNCPTR(png_set_bgr);
LOAD_FUNCPTR(png_set_crc_action); LOAD_FUNCPTR(png_set_crc_action);
...@@ -130,6 +134,8 @@ struct png_decoder ...@@ -130,6 +134,8 @@ struct png_decoder
{ {
struct decoder decoder; struct decoder decoder;
struct decoder_frame decoder_frame; struct decoder_frame decoder_frame;
UINT stride;
BYTE *image_bits;
}; };
static inline struct png_decoder *impl_from_decoder(struct decoder* iface) 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 ...@@ -185,6 +191,8 @@ HRESULT CDECL png_decoder_initialize(struct decoder *iface, IStream *stream, str
png_colorp png_palette; png_colorp png_palette;
int num_palette; int num_palette;
int i; int i;
UINT image_size;
png_bytep *row_pointers=NULL;
png_ptr = ppng_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_ptr = ppng_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) if (!png_ptr)
...@@ -385,6 +393,33 @@ HRESULT CDECL png_decoder_initialize(struct decoder *iface, IStream *stream, str ...@@ -385,6 +393,33 @@ HRESULT CDECL png_decoder_initialize(struct decoder *iface, IStream *stream, str
This->decoder_frame.num_colors = 0; 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 | st->flags = WICBitmapDecoderCapabilityCanDecodeAllImages |
WICBitmapDecoderCapabilityCanDecodeSomeImages | WICBitmapDecoderCapabilityCanDecodeSomeImages |
WICBitmapDecoderCapabilityCanEnumerateMetadata; WICBitmapDecoderCapabilityCanEnumerateMetadata;
...@@ -394,6 +429,12 @@ HRESULT CDECL png_decoder_initialize(struct decoder *iface, IStream *stream, str ...@@ -394,6 +429,12 @@ HRESULT CDECL png_decoder_initialize(struct decoder *iface, IStream *stream, str
end: end:
ppng_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 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; return hr;
} }
...@@ -404,16 +445,28 @@ HRESULT CDECL png_decoder_get_frame_info(struct decoder *iface, UINT frame, stru ...@@ -404,16 +445,28 @@ HRESULT CDECL png_decoder_get_frame_info(struct decoder *iface, UINT frame, stru
return S_OK; 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) void CDECL png_decoder_destroy(struct decoder* iface)
{ {
struct png_decoder *This = impl_from_decoder(iface); struct png_decoder *This = impl_from_decoder(iface);
free(This->image_bits);
RtlFreeHeap(GetProcessHeap(), 0, This); RtlFreeHeap(GetProcessHeap(), 0, This);
} }
static const struct decoder_funcs png_decoder_vtable = { static const struct decoder_funcs png_decoder_vtable = {
png_decoder_initialize, png_decoder_initialize,
png_decoder_get_frame_info, png_decoder_get_frame_info,
png_decoder_copy_pixels,
png_decoder_destroy png_decoder_destroy
}; };
...@@ -435,6 +488,7 @@ HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **res ...@@ -435,6 +488,7 @@ HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **res
} }
This->decoder.vtable = &png_decoder_vtable; This->decoder.vtable = &png_decoder_vtable;
This->image_bits = NULL;
*result = &This->decoder; *result = &This->decoder;
info->container_format = GUID_ContainerFormatPng; info->container_format = GUID_ContainerFormatPng;
......
...@@ -60,71 +60,6 @@ HRESULT WINAPI DllCanUnloadNow(void) ...@@ -60,71 +60,6 @@ HRESULT WINAPI DllCanUnloadNow(void)
return S_FALSE; 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 = &rect;
}
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, HRESULT configure_write_source(IWICBitmapFrameEncode *iface,
IWICBitmapSource *source, const WICRect *prc, IWICBitmapSource *source, const WICRect *prc,
const WICPixelFormatGUID *format, const WICPixelFormatGUID *format,
......
...@@ -1051,8 +1051,7 @@ static HRESULT WINAPI PngDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface, ...@@ -1051,8 +1051,7 @@ static HRESULT WINAPI PngDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface,
PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer); TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer);
return copy_pixels(This->bpp, This->image_bits, return decoder_copy_pixels(This->png_decoder, 0,
This->width, This->height, This->stride,
prc, cbStride, cbBufferSize, pbBuffer); prc, cbStride, cbBufferSize, pbBuffer);
} }
......
...@@ -78,6 +78,13 @@ HRESULT CDECL decoder_wrapper_get_frame_info(struct decoder* iface, UINT frame, ...@@ -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); 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) void CDECL decoder_wrapper_destroy(struct decoder* iface)
{ {
struct decoder_wrapper* This = impl_from_decoder(iface); struct decoder_wrapper* This = impl_from_decoder(iface);
...@@ -88,6 +95,7 @@ void CDECL decoder_wrapper_destroy(struct decoder* iface) ...@@ -88,6 +95,7 @@ void CDECL decoder_wrapper_destroy(struct decoder* iface)
static const struct decoder_funcs decoder_wrapper_vtable = { static const struct decoder_funcs decoder_wrapper_vtable = {
decoder_wrapper_initialize, decoder_wrapper_initialize,
decoder_wrapper_get_frame_info, decoder_wrapper_get_frame_info,
decoder_wrapper_copy_pixels,
decoder_wrapper_destroy decoder_wrapper_destroy
}; };
......
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
#include "wincodecs_common.h" #include "wincodecs_common.h"
static const struct win32_funcs *win32_funcs; static const struct win32_funcs *win32_funcs;
...@@ -67,6 +69,7 @@ static const struct unix_funcs unix_funcs = { ...@@ -67,6 +69,7 @@ static const struct unix_funcs unix_funcs = {
decoder_create, decoder_create,
decoder_initialize, decoder_initialize,
decoder_get_frame_info, decoder_get_frame_info,
decoder_copy_pixels,
decoder_destroy decoder_destroy
}; };
......
...@@ -26,7 +26,78 @@ HRESULT CDECL decoder_get_frame_info(struct decoder *decoder, UINT frame, struct ...@@ -26,7 +26,78 @@ HRESULT CDECL decoder_get_frame_info(struct decoder *decoder, UINT frame, struct
return decoder->vtable->get_frame_info(decoder, frame, info); 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) void CDECL decoder_destroy(struct decoder *decoder)
{ {
decoder->vtable->destroy(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 = &rect;
}
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;
}
}
...@@ -286,6 +286,8 @@ struct decoder_funcs ...@@ -286,6 +286,8 @@ struct decoder_funcs
{ {
HRESULT (CDECL *initialize)(struct decoder* This, IStream *stream, struct decoder_stat *st); 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 *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); void (CDECL *destroy)(struct decoder* This);
}; };
...@@ -301,6 +303,8 @@ struct win32_funcs ...@@ -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_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_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_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); void CDECL decoder_destroy(struct decoder *This);
HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result); HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result);
...@@ -310,6 +314,8 @@ struct unix_funcs ...@@ -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_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_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_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); 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