Vincent Povirk : windowscodecs: Override libjpeg's default error handling.
Module: wine Branch: master Commit: 1cb7e6f87986e3990236776ef06cd43041ba029f URL: http://source.winehq.org/git/wine.git/?a=commit;h=1cb7e6f87986e3990236776ef0... Author: Vincent Povirk <vincent(a)codeweavers.com> Date: Sat Sep 11 13:59:25 2010 -0500 windowscodecs: Override libjpeg's default error handling. --- dlls/windowscodecs/jpegformat.c | 59 ++++++++++++++++++++++++++++++++++++++- 1 files changed, 58 insertions(+), 1 deletions(-) diff --git a/dlls/windowscodecs/jpegformat.c b/dlls/windowscodecs/jpegformat.c index 4923b20..5243d94 100644 --- a/dlls/windowscodecs/jpegformat.c +++ b/dlls/windowscodecs/jpegformat.c @@ -25,6 +25,7 @@ #include <stdarg.h> #include <stdio.h> #include <string.h> +#include <setjmp.h> #ifdef SONAME_LIBJPEG /* This is a hack, so jpeglib.h does not redefine INT32 and the like*/ @@ -54,6 +55,7 @@ #include "wine/library.h" WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); +WINE_DECLARE_DEBUG_CHANNEL(jpeg); #ifdef SONAME_LIBJPEG @@ -91,6 +93,38 @@ static void *load_libjpeg(void) return libjpeg_handle; } +static void error_exit_fn(j_common_ptr cinfo) +{ + char message[JMSG_LENGTH_MAX]; + if (ERR_ON(jpeg)) + { + cinfo->err->format_message(cinfo, message); + ERR_(jpeg)("%s\n", message); + } + longjmp(*(jmp_buf*)cinfo->client_data, 1); +} + +static void emit_message_fn(j_common_ptr cinfo, int msg_level) +{ + char message[JMSG_LENGTH_MAX]; + + if (msg_level < 0 && ERR_ON(jpeg)) + { + cinfo->err->format_message(cinfo, message); + ERR_(jpeg)("%s\n", message); + } + else if (msg_level == 0 && WARN_ON(jpeg)) + { + cinfo->err->format_message(cinfo, message); + WARN_(jpeg)("%s\n", message); + } + else if (msg_level > 0 && TRACE_ON(jpeg)) + { + cinfo->err->format_message(cinfo, message); + TRACE_(jpeg)("%s\n", message); + } +} + typedef struct { const IWICBitmapDecoderVtbl *lpVtbl; const IWICBitmapFrameDecodeVtbl *lpFrameVtbl; @@ -227,6 +261,7 @@ static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream * JpegDecoder *This = (JpegDecoder*)iface; int ret; LARGE_INTEGER seek; + jmp_buf jmpbuf; TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOptions); EnterCriticalSection(&This->lock); @@ -237,7 +272,20 @@ static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream * return WINCODEC_ERR_WRONGSTATE; } - This->cinfo.err = pjpeg_std_error(&This->jerr); + pjpeg_std_error(&This->jerr); + + This->jerr.error_exit = error_exit_fn; + This->jerr.emit_message = emit_message_fn; + + This->cinfo.err = &This->jerr; + + This->cinfo.client_data = &jmpbuf; + + if (setjmp(jmpbuf)) + { + LeaveCriticalSection(&This->lock); + return E_FAIL; + } pjpeg_CreateDecompress(&This->cinfo, JPEG_LIB_VERSION, sizeof(struct jpeg_decompress_struct)); @@ -470,6 +518,7 @@ static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface, UINT stride; UINT data_size; UINT max_row_needed; + jmp_buf jmpbuf; TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer); if (This->cinfo.out_color_space == JCS_GRAYSCALE) bpp = 8; @@ -494,6 +543,14 @@ static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface, } } + This->cinfo.client_data = &jmpbuf; + + if (setjmp(jmpbuf)) + { + LeaveCriticalSection(&This->lock); + return E_FAIL; + } + while (max_row_needed > This->cinfo.output_scanline) { UINT first_scanline = This->cinfo.output_scanline;
participants (1)
-
Alexandre Julliard