windowscodecs: Move PNG CopyPixels to unix lib.
Signed-off-by: Esme Povirk <esme@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
8b849e814b
commit
53ce545e69
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue