[giv] Proper error handling for failed mallocs.



commit 1d8657d8487d4e981a589c5af9f425a026c09a5d
Author: Dov Grobgeld <dov grobgeld gmail com>
Date:   Wed Jun 20 20:40:00 2012 +0300

    Proper error handling for failed mallocs.

 src/giv-win.gob      |  103 +++++++++++++++++++++++++++++++------------------
 src/givimage.c       |   18 ++++++++-
 src/plugins/dicom.cc |    8 +++-
 src/plugins/png.c    |    6 +++
 src/plugins/tiff.c   |    6 +++
 5 files changed, 100 insertions(+), 41 deletions(-)
---
diff --git a/src/giv-win.gob b/src/giv-win.gob
index 39dfa92..15c003f 100644
--- a/src/giv-win.gob
+++ b/src/giv-win.gob
@@ -1094,38 +1094,24 @@ class Giv:Win from Gtk:Window
 
         selfp->current_slice=0;
 
+        if (selfp->img_org) {
+          giv_image_unref(selfp->img_org);
+          selfp->img_org = NULL;
+        }
+
         if (slip(filename).m("p(g|p)m","i")) {
             if (selfp->img_comment)
                 g_free(selfp->img_comment);
             selfp->img_comment = read_pnm_comment(filename);
         }
 
-        if (error) {
-            // Silently ignore image failures on auto reload
-            if (selfp->do_auto_reload && selfp->auto_reload_trigger) {
-                // Force a new test
-                selfp->cached_mtime = 0;
-                return;
-            }
-            else {
-                app_error(self,
-                          "Failed to load image %s: %s\n",
-                          filename, error->message);
-                return;
-            }
-            g_error_free(error);
-        }
-        
         selfp->auto_reload_trigger = false;
         
-        if (selfp->img_org)
-          {
-            giv_image_unref(selfp->img_org);
-            selfp->img_org = NULL;
-          }
         selfp->img_org = new_img;
 
-        if (selfp->do_auto_contrast)
+        if (!new_img)
+            ; // Ignore
+        else if (selfp->do_auto_contrast)
             giv_image_get_min_max(new_img,
                                   // output
                                   &selfp->contrast_min,
@@ -1165,8 +1151,13 @@ class Giv:Win from Gtk:Window
 
         // Create a suitable gray level formatting for the image.
         if (selfp->format)
+        {
             g_free(selfp->format);
-        if (new_img->img_type <= GIVIMAGE_I32)
+            selfp->format = NULL;
+        }
+        if (!new_img)
+            ;
+        else if (new_img->img_type <= GIVIMAGE_I32)
             selfp->format = g_strdup("%.0f");
         else if (max-min > 1e-3 && max-min <= 1e-2) 
             selfp->format = g_strdup("%.5f");
@@ -1181,10 +1172,29 @@ class Giv:Win from Gtk:Window
         else
             selfp->format = g_strdup("%.4g");
 
-        selfp->img_is_mono = giv_check_img_for_mono(selfp->img_org);
+        if (new_img)
+            selfp->img_is_mono = giv_check_img_for_mono(selfp->img_org);
 
         apply_color_map(self);
+
         //giv_win_shrink_wrap(self);
+        if (error) {
+            // Silently ignore image failures on auto reload
+            if (selfp->do_auto_reload && selfp->auto_reload_trigger) {
+                // Force a new test
+                selfp->cached_mtime = 0;
+                return;
+            }
+            else {
+                app_error(self,
+                          "Failed to load image %s: %s\n",
+                          filename, error->message);
+            }
+
+            g_error_free(error);
+
+            // Run rest of image to clear the old image
+        }
     }
 
     public void load_file(self,
@@ -1334,7 +1344,8 @@ class Giv:Win from Gtk:Window
     public void set_image_info(self)
     {
         int fli = selfp->filename_list_index;
-        if (fli >= (int)selfp->filename_list->len)
+        if (fli >= (int)selfp->filename_list->len
+            || fli < 0)
             return;
 
         GPtrArray *fn_list = (GPtrArray*)g_ptr_array_index(selfp->filename_list,
@@ -1402,19 +1413,21 @@ class Giv:Win from Gtk:Window
             }
 
             // Add all attributes
-            GHashTable *attributes = giv_image_get_attribute_map(selfp->img_org);
-            GHashTableIter iter;
-            gpointer key, value;
-
-            info += "----------------------------\nAttributes:\n";
-            g_hash_table_iter_init (&iter, attributes);
-            while (g_hash_table_iter_next (&iter, &key, &value)) {
-                info += slipprintf("%s: %s\n", (gchar*)key, (gchar*)value);
+            if (selfp->img_org) {
+                GHashTable *attributes = giv_image_get_attribute_map(selfp->img_org);
+                GHashTableIter iter;
+                gpointer key, value;
+    
+                info += "----------------------------\nAttributes:\n";
+                g_hash_table_iter_init (&iter, attributes);
+                while (g_hash_table_iter_next (&iter, &key, &value)) {
+                    info += slipprintf("%s: %s\n", (gchar*)key, (gchar*)value);
+                }
+                slip window_name = slipprintf("Info: %s", basename);
+                giv_info_set_info(GIV_INFO(selfp->w_info_dialog),
+                                  window_name,
+                                  info);
             }
-            slip window_name = slipprintf("Info: %s", basename);
-            giv_info_set_info(GIV_INFO(selfp->w_info_dialog),
-                              window_name,
-                              info);
         }
         g_free(new_title);
         g_free(basename);
@@ -1872,7 +1885,7 @@ cb_key_press_event (GtkWidget * widget,
             dir = -1;
 
         // Check if multislice
-        if (selfp->img_org->depth>1) {
+        if (selfp->img_org && selfp->img_org->depth>1) {
           selfp->current_slice += dir;
           if (selfp->current_slice < 0)
               selfp->current_slice = selfp->img_org->depth-1;
@@ -3229,6 +3242,12 @@ cb_contrast_changed(GtkWidget* widget,
 static void
 apply_color_map(GivWin *self)
 {
+    if (selfp->img_display)
+    {
+      g_object_unref(selfp->img_display);
+      selfp->img_display = NULL;
+    }
+
     if (!selfp->img_org)
         return;
 
@@ -3271,6 +3290,14 @@ apply_color_map(GivWin *self)
     GdkPixbuf *org_pixbuf = giv_image_get_pixbuf(selfp->img_org,
                                                  selfp->current_slice,
                                                  min, max);
+    if (!org_pixbuf) {
+        app_error(self,
+                  "Failed allocating a color image of size %dx%d pixels",
+                  selfp->img_org->width,
+                  selfp->img_org->height);
+        return;
+    }
+        
     if (selfp->img_display)
       g_object_unref(selfp->img_display);
 
diff --git a/src/givimage.c b/src/givimage.c
index d21cb88..87bfe54 100644
--- a/src/givimage.c
+++ b/src/givimage.c
@@ -50,7 +50,12 @@ GivImage *giv_image_new_full(GivImageType img_type,
     int buf_size = frame_stride * depth;
 
     // This should probably be aligned to be faster...
-    img->buf.buf = (guint8*)g_new0(guint8*, buf_size);
+    img->buf.buf = (guint8*)g_try_new0(guint8, buf_size);
+    if (!img->buf.buf) {
+        g_free(img);
+        return NULL;
+    }
+          
     img->attribute_map = g_hash_table_new_full(g_str_hash,
                                                g_str_equal,
                                                g_free,
@@ -132,6 +137,10 @@ GivImage *giv_image_new_from_file(const char *filename,
                                      width * height,
                                      2,
                                      1);
+            if (!img) {
+                *error = g_error_new(GIV_IMAGE_ERROR, -1, "Failed allocating memory for an image of size %dx%d pixels!", width, height);
+                return NULL;
+            }
 
             guchar *src_buf = gdk_pixbuf_get_pixels(pixbuf);
             guchar *dst_buf = img->buf.buf;
@@ -157,6 +166,10 @@ GivImage *giv_image_new_from_file(const char *filename,
                                      row_stride * height,
                                      2,
                                      1);
+            if (!img) {
+                *error = g_error_new(GIV_IMAGE_ERROR, -1, "Failed allocating memory for an image of size %dx%d pixels!", width, height);
+                return NULL;
+            }
             memcpy(img->buf.buf,
                    gdk_pixbuf_get_pixels(pixbuf),
                    row_stride * height);
@@ -605,6 +618,9 @@ GdkPixbuf *giv_image_get_pixbuf(GivImage *img,
                                        bits_per_sample,
                                        width,
                                        height);
+    // If we failed to allocate an image
+    if (!pixbuf)
+        return NULL;
     guchar *pbuf = gdk_pixbuf_get_pixels(pixbuf);
     guchar *buf = img->buf.buf;
     int pb_rowstride = gdk_pixbuf_get_rowstride(pixbuf);
diff --git a/src/plugins/dicom.cc b/src/plugins/dicom.cc
index 154217f..74ab85e 100644
--- a/src/plugins/dicom.cc
+++ b/src/plugins/dicom.cc
@@ -74,14 +74,18 @@ extern "C" GivImage *giv_plugin_load_file(const char *filename)
     switch (bpp) {
     case 8:
         img = giv_image_new(GIVIMAGE_U8,width,height);
-        memcpy(img->buf.buf, buf, width*height);
+        if (img)
+            memcpy(img->buf.buf, buf, width*height);
         break;
     case 16:
         img = giv_image_new(GIVIMAGE_U16,width,height);
-        memcpy(img->buf.buf, buf, width*height*2);
+        if (img)
+            memcpy(img->buf.buf, buf, width*height*2);
     default:
         ;
     }
+    if (!img) 
+      return NULL;
 
     // Insert attributes in the hash map
     DcmObject *dset = &dcm_img;
diff --git a/src/plugins/png.c b/src/plugins/png.c
index a639361..9ca2c92 100644
--- a/src/plugins/png.c
+++ b/src/plugins/png.c
@@ -12,6 +12,8 @@
 #include <math.h>
 #include "png.h"
 
+#define GIV_IMAGE_ERROR g_spawn_error_quark ()
+
 static giv_plugin_support_t png_support = {
     TRUE,
     0,
@@ -122,6 +124,10 @@ GivImage *giv_plugin_load_file(const char *filename,
         image_type = GIVIMAGE_RGB_U8;
 
     img = giv_image_new(image_type, width, height);
+    if (!img) {
+      *error = g_error_new(GIV_IMAGE_ERROR, -1, "Failed allocating memory for an image of size %dx%d pixels!", width, height);
+      return NULL;
+    }
 
     int png_transforms = PNG_TRANSFORM_PACKING;
     png_bytep *row_pointers = (png_bytep*)g_new0(gpointer, height);
diff --git a/src/plugins/tiff.c b/src/plugins/tiff.c
index f2a0c7c..a33ec62 100644
--- a/src/plugins/tiff.c
+++ b/src/plugins/tiff.c
@@ -13,6 +13,8 @@
 #include <math.h>
 #include "tiffio.h"
 
+#define GIV_IMAGE_ERROR g_spawn_error_quark ()
+
 static giv_plugin_support_t tiff_support = {
     TRUE,
     0,
@@ -120,6 +122,10 @@ GivImage *giv_plugin_load_file(const char *filename,
             }
 
             img = giv_image_new(image_type, w, h);
+            if (!img) {
+                *error = g_error_new(GIV_IMAGE_ERROR, -1, "Failed allocating memory for an image of size %dx%d pixels!", w, h);
+                return NULL;
+            }
             guchar *dst = img->buf.buf;
             int dst_bpp = giv_image_type_get_size(image_type);
             int dst_row_stride = giv_image_get_row_stride(img);



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