Vincent Povirk : windowscodecs: Override libjpeg's default error handling.

Alexandre Julliard julliard at winehq.org
Mon Sep 13 17:14:45 CDT 2010


Module: wine
Branch: master
Commit: 1cb7e6f87986e3990236776ef06cd43041ba029f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=1cb7e6f87986e3990236776ef06cd43041ba029f

Author: Vincent Povirk <vincent at 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;




More information about the wine-cvs mailing list