]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/imagjpeg.cpp
Avoid crash when releasing the mouse in wxRibbonToolBar.
[wxWidgets.git] / src / common / imagjpeg.cpp
index 8260ad683fa16bd38ea65b6a3885973ca96be9bc..1f3ed86da6fde5051d627921559ce8d042dd636d 100644 (file)
@@ -28,7 +28,7 @@
 
 // A hack based on one from tif_jpeg.c to overcome the problem on Windows
 // of rpcndr.h defining boolean with a different type to the jpeg headers.
-// 
+//
 // This hack is only necessary for an external jpeg library, the builtin one
 // usually used on Windows doesn't use the type boolean, so always works.
 //
@@ -228,11 +228,17 @@ static inline void wx_cmyk_to_rgb(unsigned char* rgb, const unsigned char* cmyk)
 
 bool wxJPEGHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
 {
+    wxCHECK_MSG( image, false, "NULL image pointer" );
+
     struct jpeg_decompress_struct cinfo;
     wx_error_mgr jerr;
     unsigned char *ptr;
 
+    // save this before calling Destroy()
+    const unsigned maxWidth = image->GetOptionInt(wxIMAGE_OPTION_MAX_WIDTH),
+                   maxHeight = image->GetOptionInt(wxIMAGE_OPTION_MAX_HEIGHT);
     image->Destroy();
+
     cinfo.err = jpeg_std_error( &jerr );
     jerr.error_exit = wx_error_exit;
 
@@ -245,7 +251,9 @@ bool wxJPEGHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos
        * We need to clean up the JPEG object, close the input file, and return.
        */
       if (verbose)
+      {
         wxLogError(_("JPEG: Couldn't load - file is probably corrupted."));
+      }
       (cinfo.src->term_source)(&cinfo);
       jpeg_destroy_decompress(&cinfo);
       if (image->Ok()) image->Destroy();
@@ -268,9 +276,20 @@ bool wxJPEGHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos
         bytesPerPixel = 3;
     }
 
+    // scale the picture to fit in the specified max size if necessary
+    if ( maxWidth > 0 || maxHeight > 0 )
+    {
+        unsigned& scale = cinfo.scale_denom;
+        while ( (maxWidth && (cinfo.image_width / scale > maxWidth)) ||
+                    (maxHeight && (cinfo.image_height / scale > maxHeight)) )
+        {
+            scale *= 2;
+        }
+    }
+
     jpeg_start_decompress( &cinfo );
 
-    image->Create( cinfo.image_width, cinfo.image_height );
+    image->Create( cinfo.output_width, cinfo.output_height );
     if (!image->Ok()) {
         jpeg_finish_decompress( &cinfo );
         jpeg_destroy_decompress( &cinfo );
@@ -404,7 +423,9 @@ bool wxJPEGHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo
          * We need to clean up the JPEG object, close the input file, and return.
          */
          if (verbose)
+         {
             wxLogError(_("JPEG: Couldn't save image."));
+         }
          jpeg_destroy_compress(&cinfo);
          return false;
     }
@@ -462,7 +483,7 @@ bool wxJPEGHandler::DoCanRead( wxInputStream& stream )
 {
     unsigned char hdr[2];
 
-    if ( !stream.Read(hdr, WXSIZEOF(hdr)) )
+    if ( !stream.Read(hdr, WXSIZEOF(hdr)) )     // it's ok to modify the stream position here
         return false;
 
     return hdr[0] == 0xFF && hdr[1] == 0xD8;