]> git.street.me.uk Git - andy/viking.git/commitdiff
SF#2831256: Allow generation of large pixel sized images.
authorRob Norris <rw_norris@hotmail.com>
Mon, 29 Oct 2012 01:04:05 +0000 (01:04 +0000)
committerRob Norris <rw_norris@hotmail.com>
Fri, 9 Nov 2012 17:23:30 +0000 (17:23 +0000)
Also actually check returned pixmap reference is valid.

Unfortunately no simple way to tell ahead of time what the maximum allowed size is.
Thus enable trapping of X errors on Linux like systems and simply ignore them.
AFAIK no simple way to trap such memory allocation errors on Windows,
 so add warning on save to image file dialog about 'large area may crash the program',
 on Windows builds only.

configure.ac
src/main.c
src/vikwindow.c

index 5cfd78503c7e7e77200ca2ea46a877fef9abffd8..28a263b561305fdb7eb8beef84c73f6d48679f82 100644 (file)
@@ -33,7 +33,7 @@ AC_SUBST(ACLOCAL_AMFLAGS)
 
 # Checks for header files.
 AC_HEADER_STDC
-AC_CHECK_HEADERS([malloc.h netdb.h netinet/in.h stdlib.h string.h sys/param.h sys/socket.h sys/types.h sys/wait.h unistd.h math.h utime.h])
+AC_CHECK_HEADERS([malloc.h netdb.h netinet/in.h stdlib.h string.h sys/param.h sys/socket.h sys/types.h sys/wait.h unistd.h math.h utime.h X11/Xlib.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
index e22b43aa2b28f9c03c9d7d0a85f9fe80377e6b43..33d614e1c0919e38c74fbbad7e28cd1ba4150e14 100644 (file)
@@ -58,6 +58,10 @@ void a_datasource_gc_init();
 #define LOCALEDIR "locale"
 #endif
 
+#ifdef HAVE_X11_XLIB_H
+#include "X11/Xlib.h"
+#endif
+
 #if GLIB_CHECK_VERSION (2, 32, 0)
 /* Callback to log message */
 static void log_debug(const gchar *log_domain,
@@ -78,6 +82,20 @@ static void mute_log(const gchar *log_domain,
 }
 #endif
 
+#if HAVE_X11_XLIB_H
+static int myXErrorHandler(Display *display, XErrorEvent *theEvent)
+{
+  g_fprintf (stderr,
+             _("Ignoring Xlib error: error code %d request code %d\n"),
+             theEvent->error_code,
+             theEvent->request_code);
+  // No exit on X errors!
+  //  mainly to handle out of memory error when requesting large pixbuf from user request
+  //  see vikwindow.c::save_image_file ()
+  return 0;
+}
+#endif
+
 /* Options */
 static GOptionEntry entries[] = 
 {
@@ -137,6 +155,10 @@ int main( int argc, char *argv[] )
     g_log_set_handler (NULL, G_LOG_LEVEL_DEBUG, mute_log, NULL);
 #endif
 
+#if HAVE_X11_XLIB_H
+  XSetErrorHandler(myXErrorHandler);
+#endif
+
   a_preferences_init ();
 
   a_vik_preferences_init ();
index 3d527332cbe30bf96451031a863c297c89c5dfc3..049e123c77d60430878266ac0b0a187d9c98188d 100644 (file)
@@ -2504,6 +2504,11 @@ static void save_image_file ( VikWindow *vw, const gchar *fn, guint w, guint h,
 
   /* save buffer as file. */
   pixbuf_to_save = gdk_pixbuf_get_from_drawable ( NULL, GDK_DRAWABLE(vik_viewport_get_pixmap ( vw->viking_vvp )), NULL, 0, 0, 0, 0, w, h);
+  if ( !pixbuf_to_save ) {
+    g_warning("Failed to generate internal pixmap");
+    goto cleanup;
+  }
+
   gdk_pixbuf_save ( pixbuf_to_save, fn, save_as_png ? "png" : "jpeg", &error, NULL );
   if (error)
   {
@@ -2512,6 +2517,7 @@ static void save_image_file ( VikWindow *vw, const gchar *fn, guint w, guint h,
   }
   g_object_unref ( G_OBJECT(pixbuf_to_save) );
 
+ cleanup:
   /* pretend like nothing happened ;) */
   vik_viewport_set_xmpp ( vw->viking_vvp, old_xmpp );
   vik_viewport_set_ympp ( vw->viking_vvp, old_ympp );
@@ -2662,10 +2668,12 @@ static void draw_to_image_file ( VikWindow *vw, const gchar *fn, gboolean one_im
 
 
   width_label = gtk_label_new ( _("Width (pixels):") );
-  width_spin = gtk_spin_button_new ( GTK_ADJUSTMENT(gtk_adjustment_new ( vw->draw_image_width, 10, 5000, 10, 100, 0 )), 10, 0 );
+  width_spin = gtk_spin_button_new ( GTK_ADJUSTMENT(gtk_adjustment_new ( vw->draw_image_width, 10, 50000, 10, 100, 0 )), 10, 0 );
   height_label = gtk_label_new ( _("Height (pixels):") );
-  height_spin = gtk_spin_button_new ( GTK_ADJUSTMENT(gtk_adjustment_new ( vw->draw_image_height, 10, 5000, 10, 100, 0 )), 10, 0 );
-
+  height_spin = gtk_spin_button_new ( GTK_ADJUSTMENT(gtk_adjustment_new ( vw->draw_image_height, 10, 50000, 10, 100, 0 )), 10, 0 );
+#ifdef WINDOWS
+  GtkWidget *win_warning_label = gtk_label_new ( _("WARNING: USING LARGE IMAGES OVER 10000x10000\nMAY CRASH THE PROGRAM!") );
+#endif
   zoom_label = gtk_label_new ( _("Zoom (meters per pixel):") );
   /* TODO: separate xzoom and yzoom factors */
   zoom_spin = gtk_spin_button_new ( GTK_ADJUSTMENT(gtk_adjustment_new ( vik_viewport_get_xmpp(vw->viking_vvp), VIK_VIEWPORT_MIN_ZOOM, VIK_VIEWPORT_MAX_ZOOM/2.0, 1, 100, 0 )), 16, 0);
@@ -2692,6 +2700,9 @@ static void draw_to_image_file ( VikWindow *vw, const gchar *fn, gboolean one_im
   gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), width_spin, FALSE, FALSE, 0);
   gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), height_label, FALSE, FALSE, 0);
   gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), height_spin, FALSE, FALSE, 0);
+#ifdef WINDOWS
+  gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), win_warning_label, FALSE, FALSE, 0);
+#endif
   gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), current_window_button, FALSE, FALSE, 0);
   gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), png_radio, FALSE, FALSE, 0);
   gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), jpeg_radio, FALSE, FALSE, 0);