gimp-gegl-utils.c 6.76 KB
Newer Older
1 2 3 4 5 6
/* GIMP - The GNU Image Manipulation Program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * gimp-gegl-utils.h
 * Copyright (C) 2007 Michael Natterer <mitch@gimp.org>
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10 11 12 13 14 15 16 17
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 20 21 22 23 24
 */

#include "config.h"

#include <gegl.h>

25
#include "gimp-gegl-types.h"
26

27 28
#include "base/tile-manager.h"

29 30
#include "core/gimpprogress.h"

31
#include "gimp-gegl-utils.h"
32
#include "gimptilebackendtilemanager.h"
33 34


35 36 37 38 39
GimpImageType
gimp_babl_format_get_image_type (const Babl *format)
{
  g_return_val_if_fail (format != NULL, -1);

40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
  if (format == babl_format ("Y u8")  ||
      format == babl_format ("Y' u8") ||
      format == babl_format ("Y float"))
    {
      return GIMP_GRAY_IMAGE;
    }
  else if (format == babl_format ("Y'A u8") ||
           format == babl_format ("YA float"))
    {
      return GIMP_GRAYA_IMAGE;
    }
  else if (format == babl_format ("R'G'B' u8") ||
           format == babl_format ("RGB float"))
    {
      return GIMP_RGB_IMAGE;
    }
  else if (format == babl_format ("R'G'B'A u8") ||
           format == babl_format ("RGBA float"))
    {
      return GIMP_RGBA_IMAGE;
    }
61 62 63 64 65 66 67 68 69 70 71
  else if (babl_format_is_palette (format))
    {
      if (babl_format_has_alpha (format))
        return GIMP_INDEXEDA_IMAGE;
      else
        return GIMP_INDEXED_IMAGE;
    }

  g_return_val_if_reached (-1);
}

72 73 74 75 76 77 78 79
const gchar *
gimp_interpolation_to_gegl_filter (GimpInterpolationType interpolation)
{
  switch (interpolation)
    {
    case GIMP_INTERPOLATION_NONE:    return "nearest";
    case GIMP_INTERPOLATION_LINEAR:  return "linear";
    case GIMP_INTERPOLATION_CUBIC:   return "cubic";
80
    case GIMP_INTERPOLATION_LOHALO:  return "lohalo";
81 82 83 84 85 86
    default:
      break;
    }

  return "nearest";
}
87

88 89 90 91 92 93 94 95 96 97 98 99 100 101
const Babl *
gimp_pixbuf_get_format (GdkPixbuf *pixbuf)
{
  g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);

  switch (gdk_pixbuf_get_n_channels (pixbuf))
    {
    case 3: return babl_format ("R'G'B' u8");
    case 4: return babl_format ("R'G'B'A u8");
    }

  g_return_val_if_reached (NULL);
}

102 103 104
GeglBuffer *
gimp_pixbuf_create_buffer (GdkPixbuf *pixbuf)
{
105 106 107
  gint width;
  gint height;
  gint rowstride;
108 109 110 111 112 113 114 115

  g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);

  width     = gdk_pixbuf_get_width (pixbuf);
  height    = gdk_pixbuf_get_height (pixbuf);
  rowstride = gdk_pixbuf_get_rowstride (pixbuf);

  return gegl_buffer_linear_new_from_data (gdk_pixbuf_get_pixels (pixbuf),
116 117
                                           gimp_pixbuf_get_format (pixbuf),
                                           GEGL_RECTANGLE (0, 0, width, height),
118
                                           rowstride,
119
                                           (GDestroyNotify) g_object_unref,
120
                                           g_object_ref (pixbuf));
121 122
}

123 124 125 126 127 128 129 130 131 132 133 134
GeglBuffer *
gimp_gegl_buffer_new (const GeglRectangle *rect,
                      const Babl          *format)
{
  TileManager *tiles;
  GeglBuffer  *buffer;

  g_return_val_if_fail (rect != NULL, NULL);
  g_return_val_if_fail (format != NULL, NULL);

  tiles = tile_manager_new (rect->width, rect->height,
                            babl_format_get_bytes_per_pixel (format));
135
  buffer = gimp_tile_manager_create_buffer (tiles, format);
136 137 138 139 140
  tile_manager_unref (tiles);

  return buffer;
}

141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
GeglBuffer *
gimp_gegl_buffer_dup (GeglBuffer *buffer)
{
  const Babl  *format = gegl_buffer_get_format (buffer);
  TileManager *tiles;
  GeglBuffer  *dup;

  tiles = tile_manager_new (gegl_buffer_get_width (buffer),
                            gegl_buffer_get_height (buffer),
                            babl_format_get_bytes_per_pixel (format));

  dup = gimp_tile_manager_create_buffer (tiles, format);
  tile_manager_unref (tiles);

  gegl_buffer_copy (buffer, NULL, dup, NULL);

  return dup;
}

160
GeglBuffer *
161
gimp_tile_manager_create_buffer (TileManager *tm,
162
                                 const Babl  *format)
163 164 165 166
{
  GeglTileBackend *backend;
  GeglBuffer      *buffer;

167
  backend = gimp_tile_backend_tile_manager_new (tm, format);
168 169 170 171 172
  buffer = gegl_buffer_new_for_backend (NULL, backend);
  g_object_unref (backend);

  return buffer;
}
173

174 175 176 177 178 179 180 181 182 183 184 185 186 187
/* temp hack */
GeglTileBackend * gegl_buffer_backend (GeglBuffer *buffer);

TileManager *
gimp_gegl_buffer_get_tiles (GeglBuffer *buffer)
{
  GeglTileBackend *backend;

  g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);

  backend = gegl_buffer_backend (buffer);

  g_return_val_if_fail (GIMP_IS_TILE_BACKEND_TILE_MANAGER (backend), NULL);

188 189
  gegl_buffer_flush (buffer);

190 191 192
  return gimp_tile_backend_tile_manager_get_tiles (backend);
}

193 194 195 196 197 198 199
void
gimp_gegl_buffer_refetch_tiles (GeglBuffer *buffer)
{
  g_return_if_fail (GEGL_IS_BUFFER (buffer));

  gegl_tile_source_reinit (GEGL_TILE_SOURCE (buffer));
}
200

201 202
GeglColor *
gimp_gegl_color_new (const GimpRGB *rgb)
203
{
204 205 206
  GeglColor *color;

  g_return_val_if_fail (rgb != NULL, NULL);
207

208
  color = gegl_color_new (NULL);
209
  gegl_color_set_pixel (color, babl_format ("R'G'B'A double"), rgb);
210 211

  return color;
212
}
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267

static void
gimp_gegl_progress_notify (GObject          *object,
                           const GParamSpec *pspec,
                           GimpProgress     *progress)
{
  const gchar *text;
  gdouble      value;

  g_object_get (object, "progress", &value, NULL);

  text = g_object_get_data (object, "gimp-progress-text");

  if (text)
    {
      if (value == 0.0)
        {
          gimp_progress_start (progress, text, FALSE);
          return;
        }
      else if (value == 1.0)
        {
          gimp_progress_end (progress);
          return;
        }
    }

  gimp_progress_set_value (progress, value);
}

void
gimp_gegl_progress_connect (GeglNode     *node,
                            GimpProgress *progress,
                            const gchar  *text)
{
  GObject *operation = NULL;

  g_return_if_fail (GEGL_IS_NODE (node));
  g_return_if_fail (GIMP_IS_PROGRESS (progress));

  g_object_get (node, "gegl-operation", &operation, NULL);

  g_return_if_fail (operation != NULL);

  g_signal_connect (operation, "notify::progress",
                    G_CALLBACK (gimp_gegl_progress_notify),
                    progress);

  if (text)
    g_object_set_data_full (operation,
                            "gimp-progress-text", g_strdup (text),
                            (GDestroyNotify) g_free);

  g_object_unref (operation);
}