[gimp] app: add xcf_read_component() and xcf_write_component()



commit 4ff911f84dce9687b0a1f088abf7d9fc47db6cfe
Author: Michael Natterer <mitch gimp org>
Date:   Sat Sep 16 17:58:30 2017 +0200

    app: add xcf_read_component() and xcf_write_component()
    
    which dispatch to endian-aware xcf_read/write_int8/int16/int32/int64()

 app/xcf/xcf-read.c  |   99 +++++++++++++++++++++++++++++++++------
 app/xcf/xcf-read.h  |   40 ++++++++++------
 app/xcf/xcf-write.c |  130 ++++++++++++++++++++++++++++++++++++++++++--------
 app/xcf/xcf-write.h |   21 +++++++--
 4 files changed, 235 insertions(+), 55 deletions(-)
---
diff --git a/app/xcf/xcf-read.c b/app/xcf/xcf-read.c
index 3431265..51c1b8f 100644
--- a/app/xcf/xcf-read.c
+++ b/app/xcf/xcf-read.c
@@ -33,6 +33,42 @@
 
 
 guint
+xcf_read_int8 (XcfInfo *info,
+               guint8  *data,
+               gint     count)
+{
+  gsize bytes_read;
+
+  g_input_stream_read_all (info->input, data, count,
+                           &bytes_read, NULL, NULL);
+
+  info->cp += bytes_read;
+
+  return bytes_read;
+}
+
+guint
+xcf_read_int16 (XcfInfo *info,
+                guint16 *data,
+                gint     count)
+{
+  guint total = 0;
+
+  if (count > 0)
+    {
+      total += xcf_read_int8 (info, (guint8 *) data, count * 2);
+
+      while (count--)
+        {
+          *data = g_ntohs (*data);
+          data++;
+        }
+    }
+
+  return total;
+}
+
+guint
 xcf_read_int32 (XcfInfo *info,
                 guint32 *data,
                 gint     count)
@@ -54,6 +90,27 @@ xcf_read_int32 (XcfInfo *info,
 }
 
 guint
+xcf_read_int64 (XcfInfo *info,
+                guint64 *data,
+                gint     count)
+{
+  guint total = 0;
+
+  if (count > 0)
+    {
+      total += xcf_read_int8 (info, (guint8 *) data, count * 8);
+
+      while (count--)
+        {
+          *data = GINT64_FROM_BE (*data);
+          data++;
+        }
+    }
+
+  return total;
+}
+
+guint
 xcf_read_offset (XcfInfo *info,
                  goffset *data,
                  gint     count)
@@ -99,21 +156,6 @@ xcf_read_float (XcfInfo *info,
 }
 
 guint
-xcf_read_int8 (XcfInfo *info,
-               guint8  *data,
-               gint     count)
-{
-  gsize bytes_read;
-
-  g_input_stream_read_all (info->input, data, count,
-                           &bytes_read, NULL, NULL);
-
-  info->cp += bytes_read;
-
-  return bytes_read;
-}
-
-guint
 xcf_read_string (XcfInfo  *info,
                  gchar   **data,
                  gint      count)
@@ -156,3 +198,30 @@ xcf_read_string (XcfInfo  *info,
 
   return total;
 }
+
+guint
+xcf_read_component (XcfInfo *info,
+                    gint     bpc,
+                    guint8  *data,
+                    gint     count)
+{
+  switch (bpc)
+    {
+    case 8:
+      return xcf_read_int8 (info, data, count);
+
+    case 16:
+      return xcf_read_int16 (info, (guint16 *) data, count);
+
+    case 32:
+      return xcf_read_int32 (info, (guint32 *) data, count);
+
+    case 64:
+      return xcf_read_int64 (info, (guint64 *) data, count);
+
+    default:
+      break;
+    }
+
+  return 0;
+}
diff --git a/app/xcf/xcf-read.h b/app/xcf/xcf-read.h
index 4ae6ce2..6a95859 100644
--- a/app/xcf/xcf-read.h
+++ b/app/xcf/xcf-read.h
@@ -19,21 +19,31 @@
 #define __XCF_READ_H__
 
 
-guint   xcf_read_int32  (XcfInfo  *info,
-                         guint32  *data,
-                         gint      count);
-guint   xcf_read_offset (XcfInfo  *info,
-                         goffset  *data,
-                         gint      count);
-guint   xcf_read_float  (XcfInfo  *info,
-                         gfloat   *data,
-                         gint      count);
-guint   xcf_read_int8   (XcfInfo  *info,
-                         guint8   *data,
-                         gint      count);
-guint   xcf_read_string (XcfInfo  *info,
-                         gchar   **data,
-                         gint      count);
+guint   xcf_read_int8      (XcfInfo  *info,
+                            guint8   *data,
+                            gint      count);
+guint   xcf_read_int16     (XcfInfo  *info,
+                            guint16  *data,
+                            gint      count);
+guint   xcf_read_int32     (XcfInfo  *info,
+                            guint32  *data,
+                            gint      count);
+guint   xcf_read_int64     (XcfInfo  *info,
+                            guint64  *data,
+                            gint      count);
+guint   xcf_read_offset    (XcfInfo  *info,
+                            goffset  *data,
+                            gint      count);
+guint   xcf_read_float     (XcfInfo  *info,
+                            gfloat   *data,
+                            gint      count);
+guint   xcf_read_string    (XcfInfo  *info,
+                            gchar   **data,
+                            gint      count);
+guint   xcf_read_component (XcfInfo  *info,
+                            gint      bpc,
+                            guint8   *data,
+                            gint      count);
 
 
 #endif  /* __XCF_READ_H__ */
diff --git a/app/xcf/xcf-write.c b/app/xcf/xcf-write.c
index 313c830..113ad5a 100644
--- a/app/xcf/xcf-write.c
+++ b/app/xcf/xcf-write.c
@@ -30,6 +30,56 @@
 
 
 guint
+xcf_write_int8 (XcfInfo       *info,
+                const guint8  *data,
+                gint           count,
+                GError       **error)
+{
+  GError *my_error = NULL;
+  gsize   bytes_written;
+
+  if (! g_output_stream_write_all (info->output, data, count,
+                                   &bytes_written, NULL, &my_error))
+    {
+      g_propagate_prefixed_error (error, my_error,
+                                  _("Error writing XCF: "));
+    }
+
+  info->cp += bytes_written;
+
+  return bytes_written;
+}
+
+guint
+xcf_write_int16 (XcfInfo        *info,
+                 const guint16  *data,
+                 gint            count,
+                 GError        **error)
+{
+  GError *tmp_error = NULL;
+  gint    i;
+
+  if (count > 0)
+    {
+      for (i = 0; i < count; i++)
+        {
+          guint16 tmp = g_htons (data[i]);
+
+          xcf_write_int8 (info, (const guint8 *) &tmp, 2, &tmp_error);
+
+          if (tmp_error)
+            {
+              g_propagate_error (error, tmp_error);
+
+              return i * 2;
+            }
+        }
+    }
+
+  return count * 2;
+}
+
+guint
 xcf_write_int32 (XcfInfo        *info,
                  const guint32  *data,
                  gint            count,
@@ -59,6 +109,35 @@ xcf_write_int32 (XcfInfo        *info,
 }
 
 guint
+xcf_write_int64 (XcfInfo        *info,
+                 const guint64  *data,
+                 gint            count,
+                 GError        **error)
+{
+  GError *tmp_error = NULL;
+  gint    i;
+
+  if (count > 0)
+    {
+      for (i = 0; i < count; i++)
+        {
+          guint64 tmp = GINT64_TO_BE (data[i]);
+
+          xcf_write_int8 (info, (const guint8 *) &tmp, 8, &tmp_error);
+
+          if (tmp_error)
+            {
+              g_propagate_error (error, tmp_error);
+
+              return i * 8;
+            }
+        }
+    }
+
+  return count * 8;
+}
+
+guint
 xcf_write_offset (XcfInfo        *info,
                   const goffset  *data,
                   gint            count,
@@ -127,27 +206,6 @@ xcf_write_float (XcfInfo       *info,
 }
 
 guint
-xcf_write_int8 (XcfInfo       *info,
-                const guint8  *data,
-                gint           count,
-                GError       **error)
-{
-  GError *my_error = NULL;
-  gsize   bytes_written;
-
-  if (! g_output_stream_write_all (info->output, data, count,
-                                   &bytes_written, NULL, &my_error))
-    {
-      g_propagate_prefixed_error (error, my_error,
-                                  _("Error writing XCF: "));
-    }
-
-  info->cp += bytes_written;
-
-  return bytes_written;
-}
-
-guint
 xcf_write_string (XcfInfo  *info,
                   gchar   **data,
                   gint      count,
@@ -188,3 +246,33 @@ xcf_write_string (XcfInfo  *info,
 
   return total;
 }
+
+guint
+xcf_write_component (XcfInfo       *info,
+                     gint           bpc,
+                     const guint8  *data,
+                     gint           count,
+                     GError       **error)
+{
+  switch (bpc)
+    {
+    case 8:
+      return xcf_write_int8 (info, data, count, error);
+
+    case 16:
+      return xcf_write_int16 (info, (const guint16 *) data, count, error);
+
+    case 32:
+      return xcf_write_int32 (info, (const guint32 *) data, count, error);
+
+    case 64:
+      return xcf_write_int64 (info, (const guint64 *) data, count, error);
+
+    default:
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                   _("Error writing XCF: unsupported BPC when writing pixel: %d"),
+                   bpc);
+    }
+
+  return 0;
+}
diff --git a/app/xcf/xcf-write.h b/app/xcf/xcf-write.h
index 9913752..b456df3 100644
--- a/app/xcf/xcf-write.h
+++ b/app/xcf/xcf-write.h
@@ -19,10 +19,22 @@
 #define __XCF_WRITE_H__
 
 
+guint   xcf_write_int8        (XcfInfo        *info,
+                               const guint8   *data,
+                               gint            count,
+                               GError        **error);
+guint   xcf_write_int16       (XcfInfo        *info,
+                               const guint16  *data,
+                               gint            count,
+                               GError        **error);
 guint   xcf_write_int32       (XcfInfo        *info,
                                const guint32  *data,
                                gint            count,
                                GError        **error);
+guint   xcf_write_int64       (XcfInfo        *info,
+                               const guint64  *data,
+                               gint            count,
+                               GError        **error);
 guint   xcf_write_offset      (XcfInfo        *info,
                                const goffset  *data,
                                gint            count,
@@ -34,14 +46,15 @@ guint   xcf_write_float       (XcfInfo        *info,
                                const gfloat   *data,
                                gint            count,
                                GError        **error);
-guint   xcf_write_int8        (XcfInfo        *info,
-                               const guint8   *data,
-                               gint            count,
-                               GError        **error);
 guint   xcf_write_string      (XcfInfo        *info,
                                gchar         **data,
                                gint            count,
                                GError        **error);
+guint   xcf_write_component   (XcfInfo        *info,
+                               gint            bpc,
+                               const guint8   *data,
+                               gint            count,
+                               GError        **error);
 
 
 #endif  /* __XCF_WRITE_H__ */


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