]> Pileus Git - ~andy/gtk/blobdiff - gdk-pixbuf/io-png.c
allow to specify the PNG compression level by passing a "compression"
[~andy/gtk] / gdk-pixbuf / io-png.c
index df5417db3011fc09cdef1178685c67d6afe48b39..25a2bb6060340f5078c77b5e7e506c0eb2e79fc1 100644 (file)
@@ -789,40 +789,69 @@ static gboolean real_save_png (GdkPixbuf        *pixbuf,
        int has_alpha;
        int bpc;
        int num_keys;
+       int compression = -1;
        gboolean success = TRUE;
        SaveToFunctionIoPtr to_callback_ioptr;
 
        num_keys = 0;
 
        if (keys && *keys) {
-               gchar **kiter;
-               gchar  *key;
-               int     len;
+               gchar **kiter = keys;
+               gchar **viter = values;
+
+               while (*kiter) {
+                       if (strncmp (*kiter, "tEXt::", 6) == 0) {
+                               gchar  *key = *kiter + 6;
+                               int     len = strlen (key);
+                               if (len <= 1 || len > 79) {
+                                       g_set_error (error,
+                                                    GDK_PIXBUF_ERROR,
+                                                    GDK_PIXBUF_ERROR_BAD_OPTION,
+                                                    _("Keys for PNG text chunks must have at least 1 and at most 79 characters."));
+                                       return FALSE;
+                               }
+                               for (i = 0; i < len; i++) {
+                                       if ((guchar) key[i] > 127) {
+                                               g_set_error (error,
+                                                            GDK_PIXBUF_ERROR,
+                                                            GDK_PIXBUF_ERROR_BAD_OPTION,
+                                                            _("Keys for PNG text chunks must be ASCII characters."));
+                                               return FALSE;
+                                       }
+                               }
+                               num_keys++;
+                       } else if (strcmp (*kiter, "compression") == 0) {
+                               char *endptr = NULL;
+                               compression = strtol (*viter, &endptr, 10);
 
-               for (kiter = keys; *kiter; kiter++) {
-                       if (strncmp (*kiter, "tEXt::", 6) != 0) {
-                               g_warning ("Bad option name '%s' passed to PNG saver", *kiter);
-                               return FALSE;
-                       }
-                       key = *kiter + 6;
-                       len = strlen (key);
-                       if (len <= 1 || len > 79) {
-                               g_set_error (error,
-                                            GDK_PIXBUF_ERROR,
-                                            GDK_PIXBUF_ERROR_BAD_OPTION,
-                                            _("Keys for PNG text chunks must have at least 1 and at most 79 characters."));
-                               return FALSE;
-                       }
-                       for (i = 0; i < len; i++) {
-                               if ((guchar) key[i] > 127) {
+                               if (endptr == *viter) {
+                                       g_set_error (error,
+                                                    GDK_PIXBUF_ERROR,
+                                                    GDK_PIXBUF_ERROR_BAD_OPTION,
+                                                    _("PNG compression level must be a value between 0 and 9; value '%s' could not be parsed."),
+                                                    *viter);
+                                       return FALSE;
+                               }
+                               if (compression < 0 || compression > 9) {
+                                       /* This is a user-visible error;
+                                        * lets people skip the range-checking
+                                        * in their app.
+                                        */
                                        g_set_error (error,
                                                     GDK_PIXBUF_ERROR,
                                                     GDK_PIXBUF_ERROR_BAD_OPTION,
-                                                    _("Keys for PNG text chunks must be ASCII characters."));
+                                                    _("PNG compression level must be a value between 0 and 9; value '%d' is not allowed."),
+                                                    compression);
                                        return FALSE;
                                }
+                       } else {
+                               g_warning ("Bad option name '%s' passed to PNG saver",
+                                          *kiter);
+                               return FALSE;
                        }
-                       num_keys++;
+
+                       ++kiter;
+                       ++viter;
                }
        }
 
@@ -851,7 +880,7 @@ static gboolean real_save_png (GdkPixbuf        *pixbuf,
                                g_set_error (error,
                                             GDK_PIXBUF_ERROR,
                                             GDK_PIXBUF_ERROR_BAD_OPTION,
-                                            _("Value for PNG text chunk %s can not be converted to ISO-8859-1 encoding."), keys[i] + 6);
+                                            _("Value for PNG text chunk %s cannot be converted to ISO-8859-1 encoding."), keys[i] + 6);
                                num_keys = i;
                                for (i = 0; i < num_keys; i++)
                                        g_free (text_ptr[i].text);
@@ -900,6 +929,9 @@ static gboolean real_save_png (GdkPixbuf        *pixbuf,
                png_init_io (png_ptr, f);
        }
 
+       if (compression >= 0)
+               png_set_compression_level (png_ptr, compression);
+
        if (has_alpha) {
                png_set_IHDR (png_ptr, info_ptr, w, h, bpc,
                              PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
@@ -994,6 +1026,6 @@ MODULE_ENTRY (png, fill_info) (GdkPixbufFormat *info)
        info->description = N_("The PNG image format");
        info->mime_types = mime_types;
        info->extensions = extensions;
-       info->flags = GDK_PIXBUF_FORMAT_WRITABLE;
+       info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
        info->license = "LGPL";
 }