]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/imagjpeg.cpp
Made changes to allow build with new mingw32/gcc-2.95
[wxWidgets.git] / src / common / imagjpeg.cpp
index e91863170c85b5eec550aa0fff0d3433738ab6c6..04de921c97cba301be8d44df4583eacb8b007ff6 100644 (file)
@@ -1,19 +1,15 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        imagjpeg.cpp
 // Purpose:     wxImage JPEG handler
-// Author:      Robert Roebling
+// Author:      Vaclav Slavik
 // RCS-ID:      $Id$
-// Copyright:   (c) Robert Roebling
+// Copyright:   (c) Vaclav Slavik
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 /*
    We don't put pragma implement in this file because it is already present in
    src/common/image.cpp
-
-#ifdef __GNUG__
-#pragma implementation "image.h"
-#endif
 */
 
 // For compilers that support precompilation, includes "wx.h".
 #pragma hdrstop
 #endif
 
+#include "wx/defs.h"
+
+#if wxUSE_LIBJPEG
+
 #include "wx/image.h"
 #include "wx/bitmap.h"
 #include "wx/debug.h"
 #include "wx/log.h"
 #include "wx/app.h"
-#if wxUSE_LIBJPEG
-extern "C" {
-#include <jpeglib.h>
+extern "C" { 
+#include "jpeglib.h"
 }
-#endif
 #include "wx/filefn.h"
 #include "wx/wfstream.h"
 #include "wx/intl.h"
@@ -40,6 +38,8 @@ extern "C" {
 
 // For memcpy
 #include <string.h>
+// For JPEG library error handling
+#include <setjmp.h>
 
 #ifdef __SALFORDC__
 #ifdef FAR
@@ -55,15 +55,12 @@ extern "C" {
 // wxJPEGHandler
 //-----------------------------------------------------------------------------
 
-#if wxUSE_LIBJPEG
-
 #if !USE_SHARED_LIBRARIES
 IMPLEMENT_DYNAMIC_CLASS(wxJPEGHandler,wxImageHandler)
 #endif
 
 #if wxUSE_STREAMS
 
-
 //------------- JPEG Data Source Manager
 
 typedef struct {
@@ -74,11 +71,11 @@ typedef struct {
 
 typedef my_source_mgr * my_src_ptr;
 
-METHODDEF(void) my_init_source ( j_decompress_ptr cinfo )
+METHODDEF(void) my_init_source ( j_decompress_ptr WXUNUSED(cinfo) )
 {
 }
 
-METHODDEF(boolean) my_fill_input_buffer ( j_decompress_ptr cinfo )
+METHODDEF(boolean) my_fill_input_buffer ( j_decompress_ptr WXUNUSED(cinfo) )
 {
     return TRUE;
 }
@@ -109,10 +106,10 @@ void jpeg_wxio_src( j_decompress_ptr cinfo, wxInputStream& infile )
         src = (my_src_ptr) cinfo->src;
     }
     src = (my_src_ptr) cinfo->src;
-    src->pub.bytes_in_buffer = infile.StreamSize(); /* forces fill_input_buffer on first read */
-    src->buffer = (JOCTET *) malloc (infile.StreamSize());
+    src->pub.bytes_in_buffer = infile.GetSize(); /* forces fill_input_buffer on first read */
+    src->buffer = (JOCTET *) malloc (infile.GetSize());
     src->pub.next_input_byte = src->buffer; /* until buffer loaded */
-    infile.Read(src->buffer, infile.StreamSize());
+    infile.Read(src->buffer, infile.GetSize());
     
     src->pub.init_source = my_init_source;
     src->pub.fill_input_buffer = my_fill_input_buffer;
@@ -122,17 +119,59 @@ void jpeg_wxio_src( j_decompress_ptr cinfo, wxInputStream& infile )
 }
 
 
+// JPEG error manager:
+
+struct my_error_mgr {
+  struct jpeg_error_mgr pub;   /* "public" fields */
+
+  jmp_buf setjmp_buffer;       /* for return to caller */
+};
+
+typedef struct my_error_mgr * my_error_ptr;
+
+/*
+ * Here's the routine that will replace the standard error_exit method:
+ */
+
+METHODDEF(void)
+my_error_exit (j_common_ptr cinfo)
+{
+  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
+  my_error_ptr myerr = (my_error_ptr) cinfo->err;
+
+  /* Always display the message. */
+  /* We could postpone this until after returning, if we chose. */
+  (*cinfo->err->output_message) (cinfo);
+
+  /* Return control to the setjmp point */
+  longjmp(myerr->setjmp_buffer, 1);
+}
+
+
 
 bool wxJPEGHandler::LoadFile( wxImage *image, wxInputStream& stream )
 {
     struct jpeg_decompress_struct cinfo;
-    struct jpeg_error_mgr jerr;
+    struct my_error_mgr jerr;
     JSAMPARRAY tempbuf;
     unsigned char *ptr;
     unsigned stride;
     
     image->Destroy();
-    cinfo.err = jpeg_std_error( &jerr );
+    cinfo.err = jpeg_std_error( &jerr.pub );
+    jerr.pub.error_exit = my_error_exit;
+
+    /* Establish the setjmp return context for my_error_exit to use. */
+    if (setjmp(jerr.setjmp_buffer)) {
+      /* If we get here, the JPEG code has signaled an error.
+       * We need to clean up the JPEG object, close the input file, and return.
+       */
+      wxLogError(_("Couldn't load a JPEG image - probably file is corrupted."));
+      jpeg_destroy_decompress(&cinfo);
+      if (image->Ok()) image->Destroy();
+      return FALSE;
+    }
+
     jpeg_create_decompress( &cinfo );
     jpeg_wxio_src( &cinfo, stream );
     jpeg_read_header( &cinfo, TRUE );
@@ -227,12 +266,24 @@ GLOBAL(void) jpeg_wxio_dest (j_compress_ptr cinfo, wxOutputStream& outfile)
 bool wxJPEGHandler::SaveFile( wxImage *image, wxOutputStream& stream )
 {
     struct jpeg_compress_struct cinfo;
-    struct jpeg_error_mgr jerr;
+    struct my_error_mgr jerr;
     JSAMPROW row_pointer[1];   /* pointer to JSAMPLE row[s] */
     JSAMPLE *image_buffer;
     int stride;                        /* physical row width in image buffer */
     
-    cinfo.err = jpeg_std_error(&jerr);
+    cinfo.err = jpeg_std_error(&jerr.pub);
+    jerr.pub.error_exit = my_error_exit;
+
+    /* Establish the setjmp return context for my_error_exit to use. */
+    if (setjmp(jerr.setjmp_buffer)) {
+      /* If we get here, the JPEG code has signaled an error.
+       * We need to clean up the JPEG object, close the input file, and return.
+       */
+      wxLogError(_("Couldn't save a JPEG image - probably file is corrupted."));
+      jpeg_destroy_compress(&cinfo);
+      return FALSE;
+    }
+
     jpeg_create_compress(&cinfo);
     jpeg_wxio_dest(&cinfo, stream);
     
@@ -254,9 +305,15 @@ bool wxJPEGHandler::SaveFile( wxImage *image, wxOutputStream& stream )
     
     return TRUE;
 }
-#endif // wxUSE_STREAMS
 
-#endif
+#endif 
+  // wxUSE_STREAMS
+
+#endif 
+  // wxUSE_LIBJPEG
+
+
+
+
 
-// wxUSE_LIBJPEG