[gimp/gimp-2-10] app: add gimp_temp_buf_{lock,unlock}()



commit 8f31f8fa3c4c0c0610ac721edd5861225bc3a3fe
Author: Ell <ell_se yahoo com>
Date:   Wed Feb 6 14:10:05 2019 -0500

    app: add gimp_temp_buf_{lock,unlock}()
    
    In GimpTempBuf, add gimp_temp_buf_lock() and gimp_temp_buf_unlock()
    functions, which lock/unlock the buffer for data access.  Unlike
    gimp_temp_buf_get_data(), which returns a direct pointer to the
    buffer's data, the new functions take a format parameter and may
    return a temporary buffer, allowing the buffer to be accessed using
    an arbitrary format.
    
    (cherry picked from commit 12dde445c4f51c2e45376d934c37cedff3a40e40)

 app/core/gimptempbuf.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/core/gimptempbuf.h |  6 ++++
 2 files changed, 86 insertions(+)
---
diff --git a/app/core/gimptempbuf.c b/app/core/gimptempbuf.c
index 80d35ef3a0..f06579ad67 100644
--- a/app/core/gimptempbuf.c
+++ b/app/core/gimptempbuf.c
@@ -32,6 +32,9 @@
 #include "gimptempbuf.h"
 
 
+#define LOCK_DATA_ALIGNMENT 16
+
+
 struct _GimpTempBuf
 {
   gint        ref_count;
@@ -41,6 +44,14 @@ struct _GimpTempBuf
   guchar     *data;
 };
 
+typedef struct
+{
+  const Babl     *format;
+  GeglAccessMode  access_mode;
+} LockData;
+
+G_STATIC_ASSERT (sizeof (LockData) <= LOCK_DATA_ALIGNMENT);
+
 
 GimpTempBuf *
 gimp_temp_buf_new (gint        width,
@@ -262,6 +273,75 @@ gimp_temp_buf_data_clear (GimpTempBuf *buf)
   return buf->data;
 }
 
+gpointer
+gimp_temp_buf_lock (const GimpTempBuf *buf,
+                    const Babl        *format,
+                    GeglAccessMode     access_mode)
+{
+  guchar   *data;
+  LockData *lock_data;
+  gint      n_pixels;
+  gint      bpp;
+
+  g_return_val_if_fail (buf != NULL, NULL);
+
+  if (! format || format == buf->format)
+    return gimp_temp_buf_get_data (buf);
+
+  n_pixels = buf->width * buf->height;
+  bpp      = babl_format_get_bytes_per_pixel (format);
+
+  data = gegl_scratch_alloc (LOCK_DATA_ALIGNMENT + n_pixels * bpp);
+
+  if ((guintptr) data % LOCK_DATA_ALIGNMENT)
+    {
+      g_free (data);
+
+      g_return_val_if_reached (NULL);
+    }
+
+  lock_data              = (LockData *) data;
+  lock_data->format      = format;
+  lock_data->access_mode = access_mode;
+
+  data += LOCK_DATA_ALIGNMENT;
+
+  if (access_mode & GEGL_ACCESS_READ)
+    {
+      babl_process (babl_fish (buf->format, format),
+                    gimp_temp_buf_get_data (buf),
+                    data,
+                    n_pixels);
+    }
+
+  return data;
+}
+
+void
+gimp_temp_buf_unlock (const GimpTempBuf *buf,
+                      gconstpointer      data)
+{
+  LockData *lock_data;
+
+  g_return_if_fail (buf != NULL);
+  g_return_if_fail (data != NULL);
+
+  if (data == buf->data)
+    return;
+
+  lock_data = (LockData *) ((const guint8 *) data - LOCK_DATA_ALIGNMENT);
+
+  if (lock_data->access_mode & GEGL_ACCESS_WRITE)
+    {
+      babl_process (babl_fish (lock_data->format, buf->format),
+                    data,
+                    gimp_temp_buf_get_data (buf),
+                    buf->width * buf->height);
+    }
+
+  gegl_scratch_free (lock_data);
+}
+
 gsize
 gimp_temp_buf_get_memsize (const GimpTempBuf *buf)
 {
diff --git a/app/core/gimptempbuf.h b/app/core/gimptempbuf.h
index 9ab13155a9..af4e8c4cf4 100644
--- a/app/core/gimptempbuf.h
+++ b/app/core/gimptempbuf.h
@@ -45,6 +45,12 @@ gsize         gimp_temp_buf_get_data_size   (const GimpTempBuf *buf);
 
 guchar      * gimp_temp_buf_data_clear      (GimpTempBuf       *buf);
 
+gpointer      gimp_temp_buf_lock            (const GimpTempBuf *buf,
+                                             const Babl        *format,
+                                             GeglAccessMode     access_mode) G_GNUC_WARN_UNUSED_RESULT;
+void          gimp_temp_buf_unlock          (const GimpTempBuf *buf,
+                                             gconstpointer      data);
+
 gsize         gimp_temp_buf_get_memsize     (const GimpTempBuf *buf);
 
 GeglBuffer  * gimp_temp_buf_create_buffer   (GimpTempBuf       *temp_buf) G_GNUC_WARN_UNUSED_RESULT;


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