[KimDaBa] Patch to check and return useful status on image load failure

Robert L Krawitz rlk at alum.mit.edu
Sun Jan 9 00:48:28 GMT 2005


The following patch handles failure to load an image by returning a
status.  This status is passed to the pixmapLoaded() method, which may
handle it as it sees fit.  I've taken a minimal cut at handling it in
some of the classes, and handled it for real in the thumbnail loader
by displaying a broken gray image instead of whatever garbage it
happened to find in memory (in my case, I found it was failing to load
.xbm files, and it was displaying pieces of other thumbnails, clearly
a result of memory corruption).
-------------- next part --------------
diff -ru kimdaba-2005-01-02-old/kimdaba/displayarea.cpp kimdaba-2005-01-02-noi18n/kimdaba/displayarea.cpp
--- kimdaba-2005-01-02-old/kimdaba/displayarea.cpp	2004-12-31 07:55:10.000000000 -0500
+++ kimdaba-2005-01-02-noi18n/kimdaba/displayarea.cpp	2005-01-08 18:36:13.896393430 -0500
@@ -440,9 +440,9 @@
         return _croppedAndScaledImg.smoothScale( 128, 128, QImage::ScaleMin );
 }
 
-void DisplayArea::pixmapLoaded( const QString& fileName, const QSize& imgSize, const QSize& fullSize, int angle, const QImage& img )
+void DisplayArea::pixmapLoaded( const QString& fileName, const QSize& imgSize, const QSize& fullSize, int angle, const QImage& img, bool status )
 {
-    if ( fileName == _info->fileName() ) {
+    if ( status == TRUE && fileName == _info->fileName() ) {
         _loadedImage = img;
         _cachedView = !( imgSize == fullSize || imgSize == QSize(-1,-1) );
         if ( !_reloadImageInProgress ) {
diff -ru kimdaba-2005-01-02-old/kimdaba/displayarea.h kimdaba-2005-01-02-noi18n/kimdaba/displayarea.h
--- kimdaba-2005-01-02-old/kimdaba/displayarea.h	2005-01-02 15:38:10.000000000 -0500
+++ kimdaba-2005-01-02-noi18n/kimdaba/displayarea.h	2005-01-08 18:34:49.803526568 -0500
@@ -53,7 +53,7 @@
     void setImage( ImageInfo* info, bool forward );
     DrawHandler* drawHandler();
     QImage currentViewAsThumbnail() const;
-    virtual void pixmapLoaded( const QString& fileName, const QSize& size, const QSize& fullSize, int angle, const QImage& );
+    virtual void pixmapLoaded( const QString& fileName, const QSize& size, const QSize& fullSize, int angle, const QImage&, bool status );
     void setImageList( const ImageInfoList& list );
 
 public slots:
diff -ru kimdaba-2005-01-02-old/kimdaba/export.cpp kimdaba-2005-01-02-noi18n/kimdaba/export.cpp
--- kimdaba-2005-01-02-old/kimdaba/export.cpp	2005-01-02 15:38:10.000000000 -0500
+++ kimdaba-2005-01-02-noi18n/kimdaba/export.cpp	2005-01-08 18:36:55.825338224 -0500
@@ -293,8 +293,10 @@
     }
 }
 
-void Export::pixmapLoaded( const QString& fileName, const QSize& /*size*/, const QSize& /*fullSize*/, int /*angle*/, const QImage& image )
+void Export::pixmapLoaded( const QString& fileName, const QSize& /*size*/, const QSize& /*fullSize*/, int /*angle*/, const QImage& image, bool status )
 {
+    if (status == FALSE)
+        return;
     // Add the file to the zip archive
     QString zipFileName = QString::fromLatin1( "%1/%2.%3" ).arg( Util::stripSlash(_subdir)).arg(QFileInfo( _nameMap[fileName] ).baseName())
                           .arg(QFileInfo( _nameMap[fileName] ).extension() );
diff -ru kimdaba-2005-01-02-old/kimdaba/export.h kimdaba-2005-01-02-noi18n/kimdaba/export.h
--- kimdaba-2005-01-02-old/kimdaba/export.h	2005-01-02 15:38:10.000000000 -0500
+++ kimdaba-2005-01-02-noi18n/kimdaba/export.h	2005-01-08 18:34:55.378987331 -0500
@@ -34,7 +34,7 @@
 
 public:
     static void imageExport( const ImageInfoList& list);
-    virtual void pixmapLoaded( const QString& fileName, const QSize& size, const QSize& fullSize, int angle, const QImage& );
+    virtual void pixmapLoaded( const QString& fileName, const QSize& size, const QSize& fullSize, int angle, const QImage&, bool status );
     Export( const ImageInfoList& list, const QString& zipFile, bool compress, int maxSize,
             ImageFileLocation, const QString& baseUrl, bool& ok, bool generateThumbnails );
     static void showUsageDialog();
diff -ru kimdaba-2005-01-02-old/kimdaba/htmlexportdialog.cpp kimdaba-2005-01-02-noi18n/kimdaba/htmlexportdialog.cpp
--- kimdaba-2005-01-02-old/kimdaba/htmlexportdialog.cpp	2005-01-02 15:38:10.000000000 -0500
+++ kimdaba-2005-01-02-noi18n/kimdaba/htmlexportdialog.cpp	2005-01-08 18:37:56.863434855 -0500
@@ -600,16 +600,16 @@
 }
 
 void HTMLExportDialog::pixmapLoaded( const QString& fileName, const QSize& imgSize,
-                                     const QSize& /*fullSize*/, int /*angle*/, const QImage& image )
+                                     const QSize& /*fullSize*/, int /*angle*/, const QImage& image, bool status )
 {
-    int size = imgSize.width();
     _progress->setProgress( _total - _waitCounter );
 
     _waitCounter--;
 
+    int size = imgSize.width();
     QString file = _tempDir + QString::fromLatin1( "/" ) + nameImage( fileName, size );
 
-    bool success = image.save( file, "JPEG" );
+    bool success = status && image.save( file, "JPEG" );
     if ( !success ) {
         // We better stop the imageloading. In case this is a full disk, we will just get all images loaded, while this
         // error box is showing, resulting in a bunch of error messages, and memory running out due to all the hanging
diff -ru kimdaba-2005-01-02-old/kimdaba/htmlexportdialog.h kimdaba-2005-01-02-noi18n/kimdaba/htmlexportdialog.h
--- kimdaba-2005-01-02-old/kimdaba/htmlexportdialog.h	2005-01-02 15:38:10.000000000 -0500
+++ kimdaba-2005-01-02-noi18n/kimdaba/htmlexportdialog.h	2005-01-08 18:35:00.302511146 -0500
@@ -46,7 +46,7 @@
 protected:
     QString createImage( ImageInfo* info, int size );
     QString imageName( const QString& fileName, int size );
-    virtual void pixmapLoaded( const QString& fileName, const QSize& size, const QSize& fullSize, int angle, const QImage& );
+    virtual void pixmapLoaded( const QString& fileName, const QSize& size, const QSize& fullSize, int angle, const QImage&, bool status );
     bool generate();
     bool generateIndexPage( int width, int height );
     bool generateContextPage( int width, int height, ImageInfo* prevInfo,
diff -ru kimdaba-2005-01-02-old/kimdaba/iconviewtooltip.cpp kimdaba-2005-01-02-noi18n/kimdaba/iconviewtooltip.cpp
--- kimdaba-2005-01-02-old/kimdaba/iconviewtooltip.cpp	2005-01-02 15:38:10.000000000 -0500
+++ kimdaba-2005-01-02-noi18n/kimdaba/iconviewtooltip.cpp	2005-01-08 18:38:09.525210257 -0500
@@ -179,7 +179,7 @@
 }
 
 void IconViewToolTip::pixmapLoaded( const QString& fileName, const QSize& /*size*/,
-                                    const QSize& /*fullSize*/, int /*angle*/, const QImage& image )
+                                    const QSize& /*fullSize*/, int /*angle*/, const QImage& image, bool status )
 {
     QMimeSourceFactory::defaultFactory()->setImage( fileName, image );
     if ( fileName == _currentFileName )
diff -ru kimdaba-2005-01-02-old/kimdaba/iconviewtooltip.h kimdaba-2005-01-02-noi18n/kimdaba/iconviewtooltip.h
--- kimdaba-2005-01-02-old/kimdaba/iconviewtooltip.h	2004-08-23 11:52:27.000000000 -0400
+++ kimdaba-2005-01-02-noi18n/kimdaba/iconviewtooltip.h	2005-01-08 18:35:05.116045600 -0500
@@ -34,7 +34,7 @@
     void showToolTips( bool force );
     virtual void setActive(bool);
     void clear();
-    virtual void pixmapLoaded( const QString& fileName, const QSize& size, const QSize& fullSize, int angle, const QImage& );
+    virtual void pixmapLoaded( const QString& fileName, const QSize& size, const QSize& fullSize, int angle, const QImage&, bool status );
 
 protected:
     virtual bool eventFilter( QObject*, QEvent* e );
diff -ru kimdaba-2005-01-02-old/kimdaba/imageclient.h kimdaba-2005-01-02-noi18n/kimdaba/imageclient.h
--- kimdaba-2005-01-02-old/kimdaba/imageclient.h	2004-08-23 11:52:27.000000000 -0400
+++ kimdaba-2005-01-02-noi18n/kimdaba/imageclient.h	2005-01-08 18:35:12.943288579 -0500
@@ -25,7 +25,7 @@
 class ImageClient {
 public:
     virtual ~ImageClient();
-    virtual void pixmapLoaded( const QString& fileName, const QSize& size, const QSize& fullSize, int angle, const QImage& ) = 0;
+    virtual void pixmapLoaded( const QString& fileName, const QSize& size, const QSize& fullSize, int angle, const QImage&, bool status ) = 0;
 };
 
 #endif /* IMAGECLIENT_H */
diff -ru kimdaba-2005-01-02-old/kimdaba/imageloader.cpp kimdaba-2005-01-02-noi18n/kimdaba/imageloader.cpp
--- kimdaba-2005-01-02-old/kimdaba/imageloader.cpp	2005-01-02 11:48:14.000000000 -0500
+++ kimdaba-2005-01-02-noi18n/kimdaba/imageloader.cpp	2005-01-08 18:59:39.037493606 -0500
@@ -52,6 +52,7 @@
         LoadInfo li = ImageManager::instance()->next();
 
         if ( !li.isNull() ) {
+	    bool status = FALSE;
             QImage img;
             bool imageLoaded = false;
 
@@ -61,49 +62,56 @@
             if ( QFileInfo( cacheFile ).exists() ) {
                 if ( img.load( cacheFile ) )  {
                     imageLoaded = true;
+		    status = TRUE;
                 }
             }
 
             if ( !imageLoaded && QFile( li.fileName() ).exists() ) {
                 if (Util::isJPEG(li.fileName())) {
                     QSize fullSize;
-                    Util::loadJPEG(&img, li.fileName(),  &fullSize, li.width(), li.height());
-                    li.setFullSize( fullSize );
+                    status = Util::loadJPEG(&img, li.fileName(),  &fullSize, li.width(), li.height());
+		    if (status == TRUE)
+		        li.setFullSize( fullSize );
                 } else if( Util::isCRW(li.fileName())) {
                     QSize fullSize;
-                    Util::loadCRW(&img, li.fileName(),  &fullSize, li.width(), li.height());
-                    li.setFullSize( fullSize );
+                    status = Util::loadCRW(&img, li.fileName(),  &fullSize, li.width(), li.height());
+		    if (status == TRUE)
+		        li.setFullSize( fullSize );
                 } else {
-                    img.load( li.fileName() );
-                    li.setFullSize( img.size() );
+                    status = img.load( li.fileName() );
+		    if (status == TRUE)
+		        li.setFullSize( img.size() );
                 }
 
-                if ( li.angle() != 0 )  {
-                    QWMatrix matrix;
-                    matrix.rotate( li.angle() );
-                    img = img.xForm( matrix );
-                    int angle = (li.angle() + 360)%360;
-                    Q_ASSERT( angle >= 0 && angle <= 360 );
-                    if ( angle == 90 || angle == 270 )
-                        li.setFullSize( QSize( li.fullSize().height(), li.fullSize().width() ) );
-
-                }
-
-                // If we are looking for a scaled version, then scale
-                if ( li.width() != -1 && li.height() != -1 )
-                    img = img.smoothScale( li.width(), li.height(), QImage::ScaleMin );
-
-                // Save thumbnail to disk
-                if ( li.cache() ) {
-                    if ( ! QDir( cacheDir ).exists() ) {
-                        QDir().mkdir( cacheDir, true );
-                    }
-                    img.save( cacheFile, "JPEG" );
-                }
+		if (status == TRUE) {
+		    if ( li.angle() != 0 )  {
+			QWMatrix matrix;
+			matrix.rotate( li.angle() );
+			img = img.xForm( matrix );
+			int angle = (li.angle() + 360)%360;
+			Q_ASSERT( angle >= 0 && angle <= 360 );
+			if ( angle == 90 || angle == 270 )
+			    li.setFullSize( QSize( li.fullSize().height(), li.fullSize().width() ) );
+
+		    }
+
+		    // If we are looking for a scaled version, then scale
+		    if ( li.width() != -1 && li.height() != -1 )
+			img = img.smoothScale( li.width(), li.height(), QImage::ScaleMin );
+
+		    // Save thumbnail to disk
+		    if ( li.cache() ) {
+			if ( ! QDir( cacheDir ).exists() ) {
+			    QDir().mkdir( cacheDir, true );
+			}
+			img.save( cacheFile, "JPEG" );
+		    }
+		}
 
                 imageLoaded = true;
             }
 
+	    li.setStatus( status );
             ImageEvent* iew = new ImageEvent( li, img );
             QApplication::postEvent( ImageManager::instance(),  iew );
         }
diff -ru kimdaba-2005-01-02-old/kimdaba/imagemanager.cpp kimdaba-2005-01-02-noi18n/kimdaba/imagemanager.cpp
--- kimdaba-2005-01-02-old/kimdaba/imagemanager.cpp	2004-09-16 08:10:56.000000000 -0400
+++ kimdaba-2005-01-02-noi18n/kimdaba/imagemanager.cpp	2005-01-08 18:53:55.759694110 -0500
@@ -102,7 +102,8 @@
 
 LoadInfo::LoadInfo( const QString& fileName, int width, int height, int angle, bool priority, ImageClient* client )
     : _null( false ),  _fileName( fileName ),  _width( width ),  _height( height ),
-      _cache( true ),  _client( client ),  _angle( angle ), _priority( priority )
+      _cache( true ),  _client( client ),  _angle( angle ), _priority( priority ),
+      _status( false )
 {
 }
 
@@ -125,7 +126,7 @@
             // If it is not in the map, then it has been deleted since the request.
             ImageClient* client = _clientMap[li];
 
-            client->pixmapLoaded( li.fileName(), QSize(li.width(), li.height()), li.fullSize(), li.angle(), image );
+            client->pixmapLoaded( li.fileName(), QSize(li.width(), li.height()), li.fullSize(), li.angle(), image, li.status() );
             _clientMap.remove(li);
         }
     }
@@ -141,6 +142,11 @@
     return _info;
 }
 
+bool LoadInfo::status() const
+{
+    return _status;
+}
+
 bool LoadInfo::isNull() const
 {
     return _null;
@@ -254,6 +260,11 @@
     _fullSize = size;
 }
 
+void LoadInfo::setStatus( bool status )
+{
+    _status = status;
+}
+
 bool LoadInfo::priority() const
 {
     return _priority;
diff -ru kimdaba-2005-01-02-old/kimdaba/imagemanager.h kimdaba-2005-01-02-noi18n/kimdaba/imagemanager.h
--- kimdaba-2005-01-02-old/kimdaba/imagemanager.h	2004-09-04 14:08:34.000000000 -0400
+++ kimdaba-2005-01-02-noi18n/kimdaba/imagemanager.h	2005-01-08 18:53:02.342860380 -0500
@@ -49,6 +49,8 @@
 
     QSize fullSize() const;
     void setFullSize( const QSize& );
+    void setStatus( bool status );
+    bool status() const;
 
     bool priority() const;
 
@@ -65,6 +67,7 @@
     int _angle;
     QSize _fullSize;
     bool _priority;
+    bool _status;
 };
 
 class ImageEvent :public QCustomEvent {
diff -ru kimdaba-2005-01-02-old/kimdaba/imagepreview.cpp kimdaba-2005-01-02-noi18n/kimdaba/imagepreview.cpp
--- kimdaba-2005-01-02-old/kimdaba/imagepreview.cpp	2004-08-23 11:52:27.000000000 -0400
+++ kimdaba-2005-01-02-noi18n/kimdaba/imagepreview.cpp	2005-01-08 18:39:01.598173961 -0500
@@ -110,9 +110,9 @@
         _preloader.preloadImage(_anticipated._fileName, width(), height(), _anticipated._angle);
 }
 
-void ImagePreview::pixmapLoaded( const QString& fileName, const QSize& /*size*/, const QSize& /*fullSize*/, int, const QImage& image)
+void ImagePreview::pixmapLoaded( const QString& fileName, const QSize& /*size*/, const QSize& /*fullSize*/, int, const QImage& image, bool status)
 {
-    if ( !_info.isNull() ) {
+    if ( status == TRUE && !_info.isNull() ) {
         if (_info.fileName() == fileName)
             setCurrentImage(image);
     }
@@ -172,9 +172,10 @@
 
 
 void ImagePreview::PreviewLoader::pixmapLoaded( const QString& fileName, const QSize& /*size*/,
-                                                const QSize& /*fullSize*/, int, const QImage& image)
+                                                const QSize& /*fullSize*/, int, const QImage& image, bool status)
 {
-    set(fileName, image);
+    if (status == TRUE)
+        set(fileName, image);
 }
 
 
diff -ru kimdaba-2005-01-02-old/kimdaba/imagepreview.h kimdaba-2005-01-02-noi18n/kimdaba/imagepreview.h
--- kimdaba-2005-01-02-old/kimdaba/imagepreview.h	2004-08-23 11:52:27.000000000 -0400
+++ kimdaba-2005-01-02-noi18n/kimdaba/imagepreview.h	2005-01-08 18:39:57.089807025 -0500
@@ -33,7 +33,7 @@
     void setImage( const QString& fileName );
     int angle() const;
     void anticipate(ImageInfo &info1);
-    virtual void pixmapLoaded( const QString& fileName, const QSize& size, const QSize& fullSize, int angle, const QImage& );
+    virtual void pixmapLoaded( const QString& fileName, const QSize& size, const QSize& fullSize, int angle, const QImage&, bool status );
 
 protected:
     virtual void resizeEvent( QResizeEvent* );
@@ -64,7 +64,7 @@
     public:
         void preloadImage( const QString& fileName, int width, int height, int angle);
         void cancelPreload();
-        virtual void pixmapLoaded( const QString& fileName, const QSize& size, const QSize& fullSize, int angle, const QImage& );
+        virtual void pixmapLoaded( const QString& fileName, const QSize& size, const QSize& fullSize, int angle, const QImage&, bool statusx );
     };
     PreviewLoader _preloader;
 
diff -ru kimdaba-2005-01-02-old/kimdaba/thumbnail.cpp kimdaba-2005-01-02-noi18n/kimdaba/thumbnail.cpp
--- kimdaba-2005-01-02-old/kimdaba/thumbnail.cpp	2005-01-02 15:38:10.000000000 -0500
+++ kimdaba-2005-01-02-noi18n/kimdaba/thumbnail.cpp	2005-01-08 19:31:51.002463848 -0500
@@ -66,14 +66,16 @@
     return _imageInfo;
 }
 
-void ThumbNail::pixmapLoaded( const QString&, const QSize& size, const QSize& /*fullSize*/, int, const QImage& image  )
+void ThumbNail::pixmapLoaded( const QString&, const QSize& size, const QSize& /*fullSize*/, int, const QImage& image, bool status  )
 {
     QPixmap* pixmap = new QPixmap( size );
-    if ( !image.isNull() )
+    if ( status && !image.isNull() )
         pixmap->convertFromImage( image );
+    else if ( !status)
+        pixmap->fill(Qt::gray);
 
 
-    if ( !_imageInfo->imageOnDisk() ) {
+    if ( !status || !_imageInfo->imageOnDisk() ) {
         QPainter p( pixmap );
         p.setBrush( white );
         p.setWindow( 0, 0, 100, 100 );
@@ -208,7 +210,13 @@
 QPixmapCache& ThumbNail::pixmapCache()
 {
     static QPixmapCache cache;
+    static int lastSize = -1;
     cache.setCacheLimit( 4* 1024 );
+    int currentThumbSize = Options::instance()->thumbSize();
+    if (lastSize != currentThumbSize) {
+        cache.clear();
+        lastSize = currentThumbSize;
+    }
     return cache;
 }
 
diff -ru kimdaba-2005-01-02-old/kimdaba/thumbnail.h kimdaba-2005-01-02-noi18n/kimdaba/thumbnail.h
--- kimdaba-2005-01-02-old/kimdaba/thumbnail.h	2004-12-29 12:19:09.000000000 -0500
+++ kimdaba-2005-01-02-noi18n/kimdaba/thumbnail.h	2005-01-08 18:35:25.767048315 -0500
@@ -32,7 +32,7 @@
     ThumbNail( ImageInfo* imageInfo,  ThumbNailView* parent );
     ThumbNail( ImageInfo* imageInfo,  ThumbNail* after, ThumbNailView* parent );
 
-    virtual void pixmapLoaded( const QString&, const QSize& size, const QSize& fullSize, int, const QImage& );
+    virtual void pixmapLoaded( const QString&, const QSize& size, const QSize& fullSize, int, const QImage&, bool status );
     QString fileName() const;
     ImageInfo* imageInfo();
     virtual bool acceptDrop ( const QMimeSource * mime ) const;
diff -ru kimdaba-2005-01-02-old/kimdaba/thumbnailbuilder.cpp kimdaba-2005-01-02-noi18n/kimdaba/thumbnailbuilder.cpp
--- kimdaba-2005-01-02-old/kimdaba/thumbnailbuilder.cpp	2005-01-02 15:38:10.000000000 -0500
+++ kimdaba-2005-01-02-noi18n/kimdaba/thumbnailbuilder.cpp	2005-01-08 18:39:36.082838738 -0500
@@ -44,7 +44,7 @@
     ImageManager::instance()->load( info->fileName(),  this, info->angle(), size, size, true, true );
 }
 
-void ThumbnailBuilder::pixmapLoaded( const QString&, const QSize& /*size*/, const QSize& /*fullSize*/, int, const QImage& )
+void ThumbnailBuilder::pixmapLoaded( const QString&, const QSize& /*size*/, const QSize& /*fullSize*/, int, const QImage&, bool status )
 {
     if ( wasCanceled() )
         delete this;
diff -ru kimdaba-2005-01-02-old/kimdaba/thumbnailbuilder.h kimdaba-2005-01-02-noi18n/kimdaba/thumbnailbuilder.h
--- kimdaba-2005-01-02-old/kimdaba/thumbnailbuilder.h	2005-01-02 15:38:10.000000000 -0500
+++ kimdaba-2005-01-02-noi18n/kimdaba/thumbnailbuilder.h	2005-01-08 18:35:30.159623482 -0500
@@ -29,7 +29,7 @@
 public:
     ThumbnailBuilder( QWidget* parent, const char* name = 0 );
     void generateNext();
-    virtual void pixmapLoaded( const QString& fileName, const QSize& size, const QSize& fullSize, int angle, const QImage& );
+    virtual void pixmapLoaded( const QString& fileName, const QSize& size, const QSize& fullSize, int angle, const QImage&, bool status );
 
 private:
     ImageInfoList _images;


More information about the Kphotoalbum mailing list