[niepce] Deal properly with images in error.



commit 2bd25d7e5af84060fa2ae913a06f3ec25a676139
Author: Hubert FiguiÃre <hub figuiere net>
Date:   Mon Jul 23 23:30:15 2012 -0700

    Deal properly with images in error.

 data/icons/Makefile.am                      |    1 +
 data/icons/niepce-image-generic.png         |  Bin 0 -> 30341 bytes
 src/ncr/image.cpp                           |   25 ++++++++++++--
 src/ncr/image.hpp                           |   14 ++++++-
 src/niepce/modules/darkroom/imagecanvas.cpp |   50 ++++++++++++++++++++-------
 src/niepce/modules/darkroom/imagecanvas.hpp |    1 +
 6 files changed, 73 insertions(+), 18 deletions(-)
---
diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am
index 39a2e07..4c12415 100644
--- a/data/icons/Makefile.am
+++ b/data/icons/Makefile.am
@@ -8,4 +8,5 @@ dist_icons_DATA = niepce-jpg-fmt.png niepce-raw-fmt.png niepce-rawjpeg-fmt.png\
 	niepce-rotate-left.png niepce-rotate-right.png \
 	niepce-flag-pick.png niepce-flag-reject.png  \
 	niepce-transform-rotate.png \
+	niepce-image-generic.png \
 	$(NULL)
diff --git a/data/icons/niepce-image-generic.png b/data/icons/niepce-image-generic.png
new file mode 100644
index 0000000..8437a29
Binary files /dev/null and b/data/icons/niepce-image-generic.png differ
diff --git a/src/ncr/image.cpp b/src/ncr/image.cpp
index c19ecac..1eb19b6 100644
--- a/src/ncr/image.cpp
+++ b/src/ncr/image.cpp
@@ -34,7 +34,8 @@ namespace ncr {
 
 struct Image::Private {
     Private()
-        : m_width(0)
+        : m_status(Image::STATUS_UNSET)
+        , m_width(0)
         , m_height(0)
         , m_orientation(0), m_vertical(false)
         , m_flip(false)
@@ -54,6 +55,7 @@ struct Image::Private {
             }
         }
 
+    Image::status_t m_status;
     int m_width, m_height; /**< the native dimension, with orientation */
     int m_orientation;     /**< EXIF orientation in degrees */
     bool m_vertical;
@@ -191,6 +193,8 @@ void Image::reload(const std::string & p, bool is_raw,
 {
     GeglNode* load_file;
 
+    priv->m_status = STATUS_LOADING;
+
     priv->m_graph = gegl_node_new();
 //    priv->m_graph->set("format", babl_format("RGB u16"));
 
@@ -240,6 +244,9 @@ void Image::reload(const std::string & p, bool is_raw,
     width = rect.width;
     height = rect.height;
     DBG_OUT("width %d height %d", width, height);
+    if(!width || !height) {
+        priv->m_status = STATUS_ERROR;
+    }
     if(priv->m_vertical) {
         priv->m_width = height;
         priv->m_height = width;
@@ -313,12 +320,18 @@ void Image::rotate_by(int degree)
 
 
 
-Cairo::RefPtr<Cairo::Surface> Image::cairo_surface_for_display()
+Cairo::RefPtr<Cairo::ImageSurface> Image::cairo_surface_for_display()
 {
+    if(priv->m_status == STATUS_ERROR) {
+        // return the error
+        DBG_OUT("error");
+        return Cairo::RefPtr<Cairo::ImageSurface>();
+    }
     if(!priv->m_sink) {
         DBG_OUT("nothing loaded");
-        return Cairo::RefPtr<Cairo::Surface>();
+        return Cairo::RefPtr<Cairo::ImageSurface>();
     }
+    DBG_ASSERT(priv->m_status == STATUS_LOADING, "wrong status for image");
     DBG_OUT("processing");
     gegl_node_process(priv->m_scale);
     GeglRectangle roi = gegl_node_get_bounding_box(priv->m_scale);
@@ -339,9 +352,15 @@ Cairo::RefPtr<Cairo::Surface> Image::cairo_surface_for_display()
     // If you don't do that, it will never paint().
     // Thanks to mitch for the tip in #gegl
     surface->mark_dirty();
+    priv->m_status = STATUS_LOADED;
     return surface;
 }
 
+Image::status_t Image::get_status() const
+{
+    return priv->m_status;
+}
+
 int Image::get_original_width() const
 {
     return priv->m_width;
diff --git a/src/ncr/image.hpp b/src/ncr/image.hpp
index e3c9e56..0d6e757 100644
--- a/src/ncr/image.hpp
+++ b/src/ncr/image.hpp
@@ -29,17 +29,27 @@
 
 namespace ncr {
 
-class Image 
+class Image
 //    : public std::tr1::enable_shared_from_this<Image>
 {
 public:
     typedef std::tr1::shared_ptr<Image> Ptr;
+    typedef enum {
+        STATUS_UNSET,
+        STATUS_LOADING,
+        STATUS_LOADED,
+        STATUS_ERROR,
+        _STATUS_LAST
+    } status_t;
 
     Image();
     virtual ~Image();
 
     /* get a cairo surface to display the resulting image */
-    Cairo::RefPtr<Cairo::Surface> cairo_surface_for_display();
+    Cairo::RefPtr<Cairo::ImageSurface> cairo_surface_for_display();
+
+    /** The status of the image. */
+    status_t get_status() const;
 
     /* the dimensions of the original image */
     int get_original_width() const;
diff --git a/src/niepce/modules/darkroom/imagecanvas.cpp b/src/niepce/modules/darkroom/imagecanvas.cpp
index 8415675..4c466a5 100644
--- a/src/niepce/modules/darkroom/imagecanvas.cpp
+++ b/src/niepce/modules/darkroom/imagecanvas.cpp
@@ -28,6 +28,10 @@
 
 #include <gdkmm/general.h>
 
+#ifndef DATADIR
+#error DATADIR is not defined
+#endif
+
 namespace dr {
 
 #define IMAGE_INSET 6
@@ -84,6 +88,14 @@ void ImageCanvas::_calc_image_frame(int img_w, int img_h,
 //    DBG_OUT("image frame %f %f %f %f", x, y, width, height);  
 }
 
+Cairo::RefPtr<Cairo::ImageSurface> ImageCanvas::_get_error_placeholder()
+{
+    Cairo::RefPtr<Cairo::ImageSurface> s;
+    s = Cairo::ImageSurface::create_from_png(
+        std::string(DATADIR"/niepce/pixmaps/niepce-image-generic.png"));
+    return s;
+}
+
 bool ImageCanvas::on_draw(const Cairo::RefPtr<Cairo::Context>& context)
 {
     // no image, just pass.
@@ -95,22 +107,30 @@ bool ImageCanvas::on_draw(const Cairo::RefPtr<Cairo::Context>& context)
     if(m_need_redisplay) {
         _redisplay();
 
-        // calculate the image scale
+        Cairo::RefPtr<Cairo::ImageSurface> img_s;
+
         int img_w, img_h;
-        img_w = m_image->get_original_width();
-        img_h = m_image->get_original_height();
-        DBG_OUT("image w = %d ; h = %d", img_w, img_h);
-        double scale = _calc_image_scale(img_w, img_h);
-        DBG_OUT("scale = %f", scale);
-        m_image->set_output_scale(scale);
+        double scale = 1.0;
 
+        if(m_image->get_status() != ncr::Image::STATUS_ERROR) {
 
-        // query the image.
-        Cairo::RefPtr<Cairo::Surface> img_s
-            = m_image->cairo_surface_for_display();
+            // calculate the image scale
+            img_w = m_image->get_original_width();
+            img_h = m_image->get_original_height();
+            DBG_OUT("image w = %d ; h = %d", img_w, img_h);
+            scale = _calc_image_scale(img_w, img_h);
+            DBG_OUT("scale = %f", scale);
+            m_image->set_output_scale(scale);
+
+
+            // query the image.
+            img_s = m_image->cairo_surface_for_display();
+        }
         if(!img_s) {
             DBG_OUT("no image loaded");
-            return false;
+            img_s = _get_error_placeholder();
+            img_w = img_s->get_width();
+            img_h = img_s->get_height();
         }
 
         int canvas_h, canvas_w;
@@ -164,11 +184,15 @@ bool ImageCanvas::on_draw(const Cairo::RefPtr<Cairo::Context>& context)
 
 void ImageCanvas::_redisplay()
 {
-    int img_w, img_h; 
+    if (m_image->get_status() == ncr::Image::STATUS_ERROR) {
+        ERR_OUT("Image is in error");
+        return;
+    }
+    int img_w, img_h;
     img_w = m_image->get_original_width();
     img_h = m_image->get_original_height();
     DBG_OUT("set image w %d h %d", img_w, img_h);
-        
+
     fwk::Rect dest(0,0, get_width() - 8, get_height() - 8);
     fwk::Rect source(0,0, img_w, img_h);
     fwk::Rect frame;
diff --git a/src/niepce/modules/darkroom/imagecanvas.hpp b/src/niepce/modules/darkroom/imagecanvas.hpp
index 33f4ce8..5bea986 100644
--- a/src/niepce/modules/darkroom/imagecanvas.hpp
+++ b/src/niepce/modules/darkroom/imagecanvas.hpp
@@ -64,6 +64,7 @@ private:
     double _calc_image_scale(int img_w, int img_h);
     /** cause to "recalulate" the content. */
     void _redisplay();
+    Cairo::RefPtr<Cairo::ImageSurface> _get_error_placeholder();
 
     bool                           m_need_redisplay;
     ZoomMode                       m_zoom_mode;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]