[gimp] plug-ins: port file-p*m-save to GIO



commit aa7e9edc36708aacbd88d825b58d1313ec8dbd79
Author: Michael Natterer <mitch gimp org>
Date:   Thu Oct 3 21:44:24 2013 +0200

    plug-ins: port file-p*m-save to GIO

 plug-ins/common/file-pnm.c |  315 ++++++++++++++++++++++++--------------------
 1 files changed, 175 insertions(+), 140 deletions(-)
---
diff --git a/plug-ins/common/file-pnm.c b/plug-ins/common/file-pnm.c
index 62af9d8..99e9fc4 100644
--- a/plug-ins/common/file-pnm.c
+++ b/plug-ins/common/file-pnm.c
@@ -26,20 +26,8 @@
 
 #include "config.h"
 
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
 #include <setjmp.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <glib/gstdio.h>
+#include <stdlib.h>
 
 #include <libgimp/gimp.h>
 #include <libgimp/gimpui.h>
@@ -47,15 +35,6 @@
 #include "libgimp/stdplugins-intl.h"
 
 
-#ifdef G_OS_WIN32
-#include <io.h>
-#endif
-
-#ifndef _O_BINARY
-#define _O_BINARY 0
-#endif
-
-
 #define LOAD_PROC      "file-pnm-load"
 #define PNM_SAVE_PROC  "file-pnm-save"
 #define PBM_SAVE_PROC  "file-pbm-save"
@@ -101,14 +80,14 @@ struct _PNMInfo
 /* Contains the information needed to write out PNM rows */
 typedef struct _PNMRowInfo
 {
-  gint      fd;            /* File descriptor             */
-  gchar    *rowbuf;        /* Buffer for writing out rows */
-  gint      xres;          /* X resolution                */
-  gint      np;            /* Number of planes            */
-  guchar   *red;           /* Colormap red                */
-  guchar   *grn;           /* Colormap green              */
-  guchar   *blu;           /* Colormap blue               */
-  gboolean  zero_is_black; /* index zero is black (PBM only) */
+  GOutputStream *output;        /* Output stream               */
+  gchar         *rowbuf;        /* Buffer for writing out rows */
+  gint           xres;          /* X resolution                */
+  gint           np;            /* Number of planes            */
+  guchar        *red;           /* Colormap red                */
+  guchar        *grn;           /* Colormap green              */
+  guchar        *blu;           /* Colormap blue               */
+  gboolean       zero_is_black; /* index zero is black (PBM only) */
 } PNMRowInfo;
 
 /* Save info  */
@@ -127,57 +106,63 @@ typedef struct
 
 /* Declare some local functions.
  */
-static void   query      (void);
-static void   run        (const gchar      *name,
-                          gint              nparams,
-                          const GimpParam  *param,
-                          gint             *nreturn_vals,
-                          GimpParam       **return_vals);
-static gint32 load_image (GFile            *file,
-                          GError          **error);
-static gint   save_image (const gchar      *filename,
-                          gint32            image_ID,
-                          gint32            drawable_ID,
-                          gboolean          pbm,
-                          GError          **error);
-
-static gint   save_dialog              (void);
-
-static void   pnm_load_ascii           (PNMScanner   *scan,
-                                        PNMInfo      *info,
-                                        GeglBuffer   *buffer);
-static void   pnm_load_raw             (PNMScanner   *scan,
-                                        PNMInfo      *info,
-                                        GeglBuffer   *buffer);
-static void   pnm_load_rawpbm          (PNMScanner   *scan,
-                                        PNMInfo      *info,
-                                        GeglBuffer   *buffer);
-
-static void   pnmsaverow_ascii         (PNMRowInfo   *ri,
-                                        const guchar *data);
-static void   pnmsaverow_raw           (PNMRowInfo   *ri,
-                                        const guchar *data);
-static void   pnmsaverow_raw_pbm       (PNMRowInfo   *ri,
-                                        const guchar *data);
-static void   pnmsaverow_ascii_pbm     (PNMRowInfo   *ri,
-                                        const guchar *data);
-static void   pnmsaverow_ascii_indexed (PNMRowInfo   *ri,
-                                        const guchar *data);
-static void   pnmsaverow_raw_indexed   (PNMRowInfo   *ri,
-                                        const guchar *data);
-
-static void   pnmscanner_destroy       (PNMScanner   *s);
-static void   pnmscanner_createbuffer  (PNMScanner   *s,
-                                        gint          bufsize);
-static void   pnmscanner_getchar       (PNMScanner   *s);
-static void   pnmscanner_eatwhitespace (PNMScanner   *s);
-static void   pnmscanner_gettoken      (PNMScanner   *s,
-                                        gchar        *buf,
-                                        gint          bufsize);
-static void   pnmscanner_getsmalltoken (PNMScanner   *s,
-                                        gchar        *buf);
-
-static PNMScanner * pnmscanner_create  (GInputStream *input);
+static void       query      (void);
+static void       run        (const gchar      *name,
+                              gint              nparams,
+                              const GimpParam  *param,
+                              gint             *nreturn_vals,
+                              GimpParam       **return_vals);
+static gint32     load_image (GFile            *file,
+                              GError          **error);
+static gint       save_image (GFile            *file,
+                              gint32            image_ID,
+                              gint32            drawable_ID,
+                              gboolean          pbm,
+                              GError          **error);
+
+static gint       save_dialog              (void);
+
+static void       pnm_load_ascii           (PNMScanner    *scan,
+                                            PNMInfo       *info,
+                                            GeglBuffer    *buffer);
+static void       pnm_load_raw             (PNMScanner    *scan,
+                                            PNMInfo       *info,
+                                            GeglBuffer    *buffer);
+static void       pnm_load_rawpbm          (PNMScanner    *scan,
+                                            PNMInfo       *info,
+                                            GeglBuffer    *buffer);
+
+static gboolean   pnmsaverow_ascii         (PNMRowInfo    *ri,
+                                            const guchar  *data,
+                                            GError       **error);
+static gboolean   pnmsaverow_raw           (PNMRowInfo    *ri,
+                                            const guchar  *data,
+                                            GError       **error);
+static gboolean   pnmsaverow_raw_pbm       (PNMRowInfo    *ri,
+                                            const guchar  *data,
+                                            GError       **error);
+static gboolean   pnmsaverow_ascii_pbm     (PNMRowInfo    *ri,
+                                            const guchar  *data,
+                                            GError       **error);
+static gboolean   pnmsaverow_ascii_indexed (PNMRowInfo    *ri,
+                                            const guchar  *data,
+                                            GError       **error);
+static gboolean   pnmsaverow_raw_indexed   (PNMRowInfo    *ri,
+                                            const guchar  *data,
+                                            GError       **error);
+
+static void       pnmscanner_destroy       (PNMScanner    *s);
+static void       pnmscanner_createbuffer  (PNMScanner    *s,
+                                            gint           bufsize);
+static void       pnmscanner_getchar       (PNMScanner    *s);
+static void       pnmscanner_eatwhitespace (PNMScanner    *s);
+static void       pnmscanner_gettoken      (PNMScanner    *s,
+                                            gchar         *buf,
+                                            gint           bufsize);
+static void       pnmscanner_getsmalltoken (PNMScanner    *s,
+                                            gchar         *buf);
+
+static PNMScanner * pnmscanner_create      (GInputStream  *input);
 
 
 #define pnmscanner_eof(s)   ((s)->eof)
@@ -320,6 +305,11 @@ query (void)
   gimp_register_file_handler_mime (PGM_SAVE_PROC, "image/x-portable-graymap");
   gimp_register_file_handler_mime (PPM_SAVE_PROC, "image/x-portable-pixmap");
 
+  gimp_register_file_handler_uri (PNM_SAVE_PROC);
+  gimp_register_file_handler_uri (PBM_SAVE_PROC);
+  gimp_register_file_handler_uri (PGM_SAVE_PROC);
+  gimp_register_file_handler_uri (PPM_SAVE_PROC);
+
   gimp_register_save_handler (PNM_SAVE_PROC, "pnm", "");
   gimp_register_save_handler (PBM_SAVE_PROC, "pbm", "");
   gimp_register_save_handler (PGM_SAVE_PROC, "pgm", "");
@@ -454,7 +444,8 @@ run (const gchar      *name,
 
       if (status == GIMP_PDB_SUCCESS)
         {
-          if (save_image (param[3].data.d_string, image_ID, drawable_ID, pbm,
+          if (save_image (g_file_new_for_uri (param[3].data.d_string),
+                          image_ID, drawable_ID, pbm,
                           &error))
             {
               /*  Store psvals data  */
@@ -868,10 +859,29 @@ pnm_load_rawpbm (PNMScanner *scan,
   gimp_progress_update (1.0);
 }
 
+static gboolean
+output_write (GOutputStream *output,
+              gconstpointer  buffer,
+              gsize          count,
+              GError       **error)
+{
+  gsize bytes_written;
+
+  if (! g_output_stream_write_all (output, buffer, count,
+                                   &bytes_written, NULL, error) ||
+      bytes_written != count)
+    {
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
 /* Writes out mono raw rows */
-static void
-pnmsaverow_raw_pbm (PNMRowInfo   *ri,
-                    const guchar *data)
+static gboolean
+pnmsaverow_raw_pbm (PNMRowInfo    *ri,
+                    const guchar  *data,
+                    GError       **error)
 {
   gint    b, p  = 0;
   gchar  *rbcur = ri->rowbuf;
@@ -895,13 +905,14 @@ pnmsaverow_raw_pbm (PNMRowInfo   *ri,
         }
     }
 
-  write (ri->fd, ri->rowbuf, len);
+  return output_write (ri->output, ri->rowbuf, len, error);
 }
 
 /* Writes out mono ascii rows */
-static void
-pnmsaverow_ascii_pbm (PNMRowInfo   *ri,
-                      const guchar *data)
+static gboolean
+pnmsaverow_ascii_pbm (PNMRowInfo    *ri,
+                      const guchar  *data,
+                      GError       **error)
 {
   static gint  line_len = 0;  /* ascii pbm lines must be <= 70 chars long */
   gint32       len = 0;
@@ -929,21 +940,23 @@ pnmsaverow_ascii_pbm (PNMRowInfo   *ri,
 
   *(rbcur+i) = '\n';
 
-  write (ri->fd, ri->rowbuf, len);
+  return output_write (ri->output, ri->rowbuf, len, error);
 }
 
 /* Writes out RGB and grayscale raw rows */
-static void
-pnmsaverow_raw (PNMRowInfo   *ri,
-                const guchar *data)
+static gboolean
+pnmsaverow_raw (PNMRowInfo    *ri,
+                const guchar  *data,
+                GError       **error)
 {
-  write (ri->fd, data, ri->xres * ri->np);
+  return output_write (ri->output, data, ri->xres * ri->np, error);
 }
 
 /* Writes out indexed raw rows */
-static void
-pnmsaverow_raw_indexed (PNMRowInfo   *ri,
-                        const guchar *data)
+static gboolean
+pnmsaverow_raw_indexed (PNMRowInfo    *ri,
+                        const guchar  *data,
+                        GError       **error)
 {
   gint   i;
   gchar *rbcur = ri->rowbuf;
@@ -955,30 +968,33 @@ pnmsaverow_raw_indexed (PNMRowInfo   *ri,
       *(rbcur++) = ri->blu[*(data++)];
     }
 
-  write (ri->fd, ri->rowbuf, ri->xres * 3);
+  return output_write (ri->output, ri->rowbuf, ri->xres * 3, error);
 }
 
 /* Writes out RGB and grayscale ascii rows */
-static void
-pnmsaverow_ascii (PNMRowInfo   *ri,
-                  const guchar *data)
+static gboolean
+pnmsaverow_ascii (PNMRowInfo    *ri,
+                  const guchar  *data,
+                  GError       **error)
 {
   gint   i;
   gchar *rbcur = ri->rowbuf;
 
-  for (i = 0; i < ri->xres*ri->np; i++)
+  for (i = 0; i < ri->xres * ri->np; i++)
     {
       sprintf ((gchar *) rbcur,"%d\n", 0xff & *(data++));
       rbcur += strlen (rbcur);
     }
 
-  write (ri->fd, ri->rowbuf, strlen ((gchar *) ri->rowbuf));
+  return output_write (ri->output, ri->rowbuf, strlen ((gchar *) ri->rowbuf),
+                       error);
 }
 
 /* Writes out RGB and grayscale ascii rows */
-static void
-pnmsaverow_ascii_indexed (PNMRowInfo   *ri,
-                          const guchar *data)
+static gboolean
+pnmsaverow_ascii_indexed (PNMRowInfo    *ri,
+                          const guchar  *data,
+                          GError       **error)
 {
   gint   i;
   gchar *rbcur = ri->rowbuf;
@@ -993,21 +1009,24 @@ pnmsaverow_ascii_indexed (PNMRowInfo   *ri,
       rbcur += strlen (rbcur);
     }
 
-  write (ri->fd, ri->rowbuf, strlen ((char *) ri->rowbuf));
+  return output_write (ri->output, ri->rowbuf, strlen ((char *) ri->rowbuf),
+                       error);
 }
 
 static gboolean
-save_image (const gchar  *filename,
-            gint32        image_ID,
-            gint32        drawable_ID,
-            gboolean      pbm,
-            GError      **error)
+save_image (GFile     *file,
+            gint32     image_ID,
+            gint32     drawable_ID,
+            gboolean   pbm,
+            GError   **error)
 {
+  GOutputStream *output;
   GeglBuffer    *buffer;
   const Babl    *format;
+  const gchar   *header_string = NULL;
   GimpImageType  drawable_type;
   PNMRowInfo     rowinfo;
-  void (*saverow) (PNMRowInfo *, const guchar *) = NULL;
+  gboolean (*saverow) (PNMRowInfo *, const guchar *, GError **) = NULL;
   guchar         red[256];
   guchar         grn[256];
   guchar         blu[256];
@@ -1019,7 +1038,6 @@ save_image (const gchar  *filename,
   gint           bpp;
   gint           ypos, yend;
   gint           rowbufsize = 0;
-  gint           fd;
 
   /*  Make sure we're not saving an image with an alpha channel  */
   if (gimp_drawable_has_alpha (drawable_ID))
@@ -1029,18 +1047,12 @@ save_image (const gchar  *filename,
     }
 
   /* open the file */
-  fd = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC | _O_BINARY, 0666);
-
-  if (fd == -1)
-    {
-      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
-                   _("Could not open '%s' for writing: %s"),
-                   gimp_filename_to_utf8 (filename), g_strerror (errno));
-      return FALSE;
-    }
+  output = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE, 0, NULL, error));
+  if (! output)
+    return FALSE;
 
   gimp_progress_init_printf (_("Saving '%s'"),
-                             gimp_filename_to_utf8 (filename));
+                             g_file_get_parse_name (file));
 
   buffer = gimp_drawable_get_buffer (drawable_ID);
 
@@ -1054,7 +1066,7 @@ save_image (const gchar  *filename,
     {
       if (pbm)
         {
-          write (fd, "P1\n", 3);
+          header_string = "P1\n";
           format = babl_format ("Y' u8");
           np = 0;
           rowbufsize = xres + (int) (xres / 70) + 1;
@@ -1065,7 +1077,7 @@ save_image (const gchar  *filename,
           switch (drawable_type)
             {
             case GIMP_GRAY_IMAGE:
-              write (fd, "P2\n", 3);
+              header_string = "P2\n";
               format = babl_format ("Y' u8");
               np = 1;
               rowbufsize = xres * 4;
@@ -1073,7 +1085,7 @@ save_image (const gchar  *filename,
               break;
 
             case GIMP_RGB_IMAGE:
-              write (fd, "P3\n", 3);
+              header_string = "P3\n";
               format = babl_format ("R'G'B' u8");
               np = 3;
               rowbufsize = xres * 12;
@@ -1081,7 +1093,7 @@ save_image (const gchar  *filename,
               break;
 
             case GIMP_INDEXED_IMAGE:
-              write (fd, "P3\n", 3);
+              header_string = "P3\n";
               format = gegl_buffer_get_format (buffer);
               np = 1;
               rowbufsize = xres * 12;
@@ -1098,7 +1110,7 @@ save_image (const gchar  *filename,
     {
       if (pbm)
         {
-          write (fd, "P4\n", 3);
+          header_string = "P4\n";
           format = babl_format ("Y' u8");
           np = 0;
           rowbufsize = (int)ceil ((double)(xres)/8.0);
@@ -1109,7 +1121,7 @@ save_image (const gchar  *filename,
           switch (drawable_type)
             {
             case GIMP_GRAY_IMAGE:
-              write (fd, "P5\n", 3);
+              header_string = "P5\n";
               format = babl_format ("Y' u8");
               np = 1;
               rowbufsize = xres;
@@ -1117,7 +1129,7 @@ save_image (const gchar  *filename,
               break;
 
             case GIMP_RGB_IMAGE:
-              write (fd, "P6\n", 3);
+              header_string = "P6\n";
               format = babl_format ("R'G'B' u8");
               np = 3;
               rowbufsize = xres * 3;
@@ -1125,7 +1137,7 @@ save_image (const gchar  *filename,
               break;
 
             case GIMP_INDEXED_IMAGE:
-              write (fd, "P6\n", 3);
+              header_string = "P6\n";
               format = gegl_buffer_get_format (buffer);
               np = 1;
               rowbufsize = xres * 3;
@@ -1139,6 +1151,13 @@ save_image (const gchar  *filename,
         }
     }
 
+  if (! output_write (output, header_string, strlen (header_string), error))
+    {
+      g_object_unref (output);
+      g_object_unref (buffer);
+      return FALSE;
+    }
+
   rowinfo.zero_is_black = FALSE;
 
   if (drawable_type == GIMP_INDEXED_IMAGE)
@@ -1199,19 +1218,30 @@ save_image (const gchar  *filename,
   data = g_new (guchar, gimp_tile_height () * xres * bpp);
 
   /* write out comment string */
-  write (fd, SAVE_COMMENT_STRING, strlen (SAVE_COMMENT_STRING));
+  if (! output_write (output, SAVE_COMMENT_STRING, strlen (SAVE_COMMENT_STRING),
+                      error))
+    {
+      g_object_unref (output);
+      g_object_unref (buffer);
+      return FALSE;
+    }
 
   /* write out resolution and maxval */
   if (pbm)
-    sprintf (buf, "%d %d\n", xres, yres);
+    g_snprintf (buf, sizeof (buf), "%d %d\n", xres, yres);
   else
-    sprintf (buf, "%d %d\n255\n", xres, yres);
+    g_snprintf (buf, sizeof (buf), "%d %d\n255\n", xres, yres);
 
-  write (fd, buf, strlen(buf));
+  if (! output_write (output, buf, strlen (buf), error))
+    {
+      g_object_unref (output);
+      g_object_unref (buffer);
+      return FALSE;
+    }
 
   rowbuf = g_new (gchar, rowbufsize + 1);
 
-  rowinfo.fd     = fd;
+  rowinfo.output = output;
   rowinfo.rowbuf = rowbuf;
   rowinfo.xres   = xres;
   rowinfo.np     = np;
@@ -1234,19 +1264,24 @@ save_image (const gchar  *filename,
           d = data;
         }
 
-      saverow (&rowinfo, d);
+      if (! saverow (&rowinfo, d, error))
+        {
+          g_object_unref (output);
+          g_object_unref (buffer);
+          return FALSE;
+        }
+
       d += xres * (np ? np : 1);
 
       if ((ypos % 20) == 0)
         gimp_progress_update ((double) ypos / (double) yres);
     }
 
-  close (fd);
-
   g_free (rowbuf);
   g_free (data);
 
   g_object_unref (buffer);
+  g_object_unref (output);
 
   gimp_progress_update (1.0);
 


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