Vincent Povirk : windowscodecs: Implement WritePixels for the PNG encoder.
Alexandre Julliard
julliard at winehq.org
Fri Oct 9 09:24:16 CDT 2009
Module: wine
Branch: master
Commit: 2e14644937031f045072d925df3c0a3e543320ca
URL: http://source.winehq.org/git/wine.git/?a=commit;h=2e14644937031f045072d925df3c0a3e543320ca
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Wed Sep 23 17:15:36 2009 -0500
windowscodecs: Implement WritePixels for the PNG encoder.
---
dlls/windowscodecs/pngformat.c | 68 ++++++++++++++++++++++++++++++++++++++-
1 files changed, 66 insertions(+), 2 deletions(-)
diff --git a/dlls/windowscodecs/pngformat.c b/dlls/windowscodecs/pngformat.c
index 48295b2..1ac4772 100644
--- a/dlls/windowscodecs/pngformat.c
+++ b/dlls/windowscodecs/pngformat.c
@@ -58,8 +58,11 @@ MAKE_FUNCPTR(png_get_pHYs);
MAKE_FUNCPTR(png_get_PLTE);
MAKE_FUNCPTR(png_get_tRNS);
MAKE_FUNCPTR(png_set_bgr);
+MAKE_FUNCPTR(png_set_filler);
MAKE_FUNCPTR(png_set_gray_1_2_4_to_8);
MAKE_FUNCPTR(png_set_gray_to_rgb);
+MAKE_FUNCPTR(png_set_IHDR);
+MAKE_FUNCPTR(png_set_pHYs);
MAKE_FUNCPTR(png_set_read_fn);
MAKE_FUNCPTR(png_set_strip_16);
MAKE_FUNCPTR(png_set_tRNS_to_alpha);
@@ -67,6 +70,8 @@ MAKE_FUNCPTR(png_set_write_fn);
MAKE_FUNCPTR(png_read_end);
MAKE_FUNCPTR(png_read_image);
MAKE_FUNCPTR(png_read_info);
+MAKE_FUNCPTR(png_write_info);
+MAKE_FUNCPTR(png_write_rows);
#undef MAKE_FUNCPTR
static void *load_libpng(void)
@@ -93,8 +98,11 @@ static void *load_libpng(void)
LOAD_FUNCPTR(png_get_PLTE);
LOAD_FUNCPTR(png_get_tRNS);
LOAD_FUNCPTR(png_set_bgr);
+ LOAD_FUNCPTR(png_set_filler);
LOAD_FUNCPTR(png_set_gray_1_2_4_to_8);
LOAD_FUNCPTR(png_set_gray_to_rgb);
+ LOAD_FUNCPTR(png_set_IHDR);
+ LOAD_FUNCPTR(png_set_pHYs);
LOAD_FUNCPTR(png_set_read_fn);
LOAD_FUNCPTR(png_set_strip_16);
LOAD_FUNCPTR(png_set_tRNS_to_alpha);
@@ -102,6 +110,8 @@ static void *load_libpng(void)
LOAD_FUNCPTR(png_read_end);
LOAD_FUNCPTR(png_read_image);
LOAD_FUNCPTR(png_read_info);
+ LOAD_FUNCPTR(png_write_info);
+ LOAD_FUNCPTR(png_write_rows);
#undef LOAD_FUNCPTR
}
@@ -701,6 +711,7 @@ typedef struct PngEncoder {
BOOL info_written;
UINT width, height;
double xres, yres;
+ UINT lines_written;
} PngEncoder;
static inline PngEncoder *encoder_from_frame(IWICBitmapFrameEncode *iface)
@@ -831,8 +842,60 @@ static HRESULT WINAPI PngFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface,
static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels)
{
- FIXME("(%p,%u,%u,%u,%p): stub\n", iface, lineCount, cbStride, cbBufferSize, pbPixels);
- return E_NOTIMPL;
+ PngEncoder *This = encoder_from_frame(iface);
+ png_byte **row_pointers=NULL;
+ UINT i;
+ TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels);
+
+ if (!This->frame_initialized || !This->width || !This->height || !This->format)
+ return WINCODEC_ERR_WRONGSTATE;
+
+ if (lineCount == 0 || lineCount + This->lines_written > This->height)
+ return E_INVALIDARG;
+
+ /* set up setjmp/longjmp error handling */
+ if (setjmp(png_jmpbuf(This->png_ptr)))
+ {
+ if (row_pointers) HeapFree(GetProcessHeap(), 0, row_pointers);
+ return E_FAIL;
+ }
+
+ if (!This->info_written)
+ {
+ ppng_set_IHDR(This->png_ptr, This->info_ptr, This->width, This->height,
+ This->format->bit_depth, This->format->color_type, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+
+ if (This->xres != 0.0 && This->yres != 0.0)
+ {
+ ppng_set_pHYs(This->png_ptr, This->info_ptr, (This->xres+0.0127) / 0.0254,
+ (This->yres+0.0127) / 0.0254, PNG_RESOLUTION_METER);
+ }
+
+ ppng_write_info(This->png_ptr, This->info_ptr);
+
+ if (This->format->remove_filler)
+ ppng_set_filler(This->png_ptr, 0, PNG_FILLER_AFTER);
+
+ if (This->format->swap_rgb)
+ ppng_set_bgr(This->png_ptr);
+
+ This->info_written = TRUE;
+ }
+
+ row_pointers = HeapAlloc(GetProcessHeap(), 0, lineCount * sizeof(png_byte*));
+ if (!row_pointers)
+ return E_OUTOFMEMORY;
+
+ for (i=0; i<lineCount; i++)
+ row_pointers[i] = pbPixels + cbStride * i;
+
+ ppng_write_rows(This->png_ptr, row_pointers, lineCount);
+ This->lines_written += lineCount;
+
+ HeapFree(GetProcessHeap(), 0, row_pointers);
+
+ return S_OK;
}
static HRESULT WINAPI PngFrameEncode_WriteSource(IWICBitmapFrameEncode *iface,
@@ -1109,6 +1172,7 @@ HRESULT PngEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
This->height = 0;
This->xres = 0.0;
This->yres = 0.0;
+ This->lines_written = 0;
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
More information about the wine-cvs
mailing list