[3/5] windowscodecs: Implement JpegEncoder_Frame_WritePixels.
Vincent Povirk
madewokherd at gmail.com
Mon Apr 16 10:59:17 CDT 2012
-------------- next part --------------
From 98c0e66452e04c082db3182cec60e1ee54d02fae Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Wed, 11 Apr 2012 16:37:56 -0500
Subject: [PATCH 3/8] windowscodecs: Implement JpegEncoder_Frame_WritePixels.
---
dlls/windowscodecs/jpegformat.c | 109 ++++++++++++++++++++++++++++++++++++++-
1 files changed, 107 insertions(+), 2 deletions(-)
diff --git a/dlls/windowscodecs/jpegformat.c b/dlls/windowscodecs/jpegformat.c
index 2ae1fc7..ac11654 100644
--- a/dlls/windowscodecs/jpegformat.c
+++ b/dlls/windowscodecs/jpegformat.c
@@ -69,8 +69,11 @@ MAKE_FUNCPTR(jpeg_destroy_decompress);
MAKE_FUNCPTR(jpeg_read_header);
MAKE_FUNCPTR(jpeg_read_scanlines);
MAKE_FUNCPTR(jpeg_resync_to_restart);
+MAKE_FUNCPTR(jpeg_set_defaults);
+MAKE_FUNCPTR(jpeg_start_compress);
MAKE_FUNCPTR(jpeg_start_decompress);
MAKE_FUNCPTR(jpeg_std_error);
+MAKE_FUNCPTR(jpeg_write_scanlines);
#undef MAKE_FUNCPTR
static void *load_libjpeg(void)
@@ -90,8 +93,11 @@ static void *load_libjpeg(void)
LOAD_FUNCPTR(jpeg_read_header);
LOAD_FUNCPTR(jpeg_read_scanlines);
LOAD_FUNCPTR(jpeg_resync_to_restart);
+ LOAD_FUNCPTR(jpeg_set_defaults);
+ LOAD_FUNCPTR(jpeg_start_compress);
LOAD_FUNCPTR(jpeg_start_decompress);
LOAD_FUNCPTR(jpeg_std_error);
+ LOAD_FUNCPTR(jpeg_write_scanlines);
#undef LOAD_FUNCPTR
}
return libjpeg_handle;
@@ -727,6 +733,7 @@ typedef struct JpegEncoder {
int frame_count;
int frame_initialized;
int started_compress;
+ int lines_written;
UINT width, height;
double xres, yres;
const jpeg_compress_format *format;
@@ -949,8 +956,105 @@ static HRESULT WINAPI JpegEncoder_Frame_SetThumbnail(IWICBitmapFrameEncode *ifac
static HRESULT WINAPI JpegEncoder_Frame_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;
+ JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
+ jmp_buf jmpbuf;
+ BYTE *swapped_data = NULL, *current_row;
+ int line, row_size;
+ TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels);
+
+ EnterCriticalSection(&This->lock);
+
+ if (!This->frame_initialized || !This->width || !This->height || !This->format)
+ {
+ LeaveCriticalSection(&This->lock);
+ return WINCODEC_ERR_WRONGSTATE;
+ }
+
+ if (lineCount == 0 || lineCount + This->lines_written > This->height)
+ {
+ LeaveCriticalSection(&This->lock);
+ return E_INVALIDARG;
+ }
+
+ /* set up setjmp/longjmp error handling */
+ if (setjmp(jmpbuf))
+ {
+ LeaveCriticalSection(&This->lock);
+ HeapFree(GetProcessHeap(), 0, swapped_data);
+ return E_FAIL;
+ }
+ This->cinfo.client_data = &jmpbuf;
+
+ if (!This->started_compress)
+ {
+ This->cinfo.image_width = This->width;
+ This->cinfo.image_height = This->height;
+ This->cinfo.input_components = This->format->num_components;
+ This->cinfo.in_color_space = This->format->color_space;
+
+ pjpeg_set_defaults(&This->cinfo);
+
+ if (This->xres != 0.0 && This->yres != 0.0)
+ {
+ This->cinfo.density_unit = 1; /* dots per inch */
+ This->cinfo.X_density = This->xres;
+ This->cinfo.Y_density = This->yres;
+ }
+
+ pjpeg_start_compress(&This->cinfo, TRUE);
+
+ This->started_compress = 1;
+ }
+
+ row_size = This->format->bpp / 8 * This->width;
+
+ if (This->format->swap_rgb)
+ {
+ swapped_data = HeapAlloc(GetProcessHeap(), 0, row_size);
+ if (!swapped_data)
+ {
+ LeaveCriticalSection(&This->lock);
+ return E_OUTOFMEMORY;
+ }
+ }
+
+ for (line=0; line < lineCount; line++)
+ {
+ if (This->format->swap_rgb)
+ {
+ int x;
+
+ memcpy(swapped_data, pbPixels + (cbStride * line), row_size);
+
+ for (x=0; x < This->width; x++)
+ {
+ BYTE b;
+
+ b = swapped_data[x*3];
+ swapped_data[x*3] = swapped_data[x*3+2];
+ swapped_data[x*3+2] = b;
+ }
+
+ current_row = swapped_data;
+ }
+ else
+ current_row = pbPixels + (cbStride * line);
+
+ if (!pjpeg_write_scanlines(&This->cinfo, ¤t_row, 1))
+ {
+ ERR("failed writing scanlines\n");
+ LeaveCriticalSection(&This->lock);
+ HeapFree(GetProcessHeap(), 0, swapped_data);
+ return E_FAIL;
+ }
+
+ This->lines_written++;
+ }
+
+ LeaveCriticalSection(&This->lock);
+ HeapFree(GetProcessHeap(), 0, swapped_data);
+
+ return S_OK;
}
static HRESULT WINAPI JpegEncoder_Frame_WriteSource(IWICBitmapFrameEncode *iface,
@@ -1228,6 +1332,7 @@ HRESULT JpegEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
This->frame_count = 0;
This->frame_initialized = 0;
This->started_compress = 0;
+ This->lines_written = 0;
This->width = This->height = 0;
This->xres = This->yres = 0.0;
This->format = NULL;
--
1.7.9.1
More information about the wine-patches
mailing list