Files
gimp/app/gegl/gimp-gegl-utils.c
Øyvind Kolås 76546f7e7c rename lanczos to lohalo
GEGL had a broken lanczos implementation, the lohalo implementation is better
anyways (at least when passed a proper scale matrix).
2012-05-02 17:50:38 +02:00

313 lines
7.9 KiB
C

/* 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>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include "gimp-gegl-types.h"
#include "base/temp-buf.h"
#include "base/tile-manager.h"
#include "core/gimpprogress.h"
#include "gimp-gegl-utils.h"
#include "gimptilebackendtilemanager.h"
/**
* gimp_bpp_to_babl_format:
* @bpp: bytes per pixel
*
* Return the Babl format to use for a given number of bytes per pixel.
* This function assumes that the data is 8bit.
*
* Return value: the Babl format to use
**/
const Babl *
gimp_bpp_to_babl_format (guint bpp)
{
g_return_val_if_fail (bpp > 0 && bpp <= 4, NULL);
switch (bpp)
{
case 1:
return babl_format ("Y' u8");
case 2:
return babl_format ("Y'A u8");
case 3:
return babl_format ("R'G'B' u8");
case 4:
return babl_format ("R'G'B'A u8");
}
return NULL;
}
/**
* gimp_bpp_to_babl_format_with_alpha:
* @bpp: bytes per pixel
*
* Return the Babl format to use for a given number of bytes per pixel.
* This function assumes that the data is 8bit.
*
* Return value: the Babl format to use
**/
const Babl *
gimp_bpp_to_babl_format_with_alpha (guint bpp)
{
g_return_val_if_fail (bpp > 0 && bpp <= 4, NULL);
switch (bpp)
{
case 1:
case 2:
return babl_format ("Y'A u8");
case 3:
case 4:
return babl_format ("R'G'B'A u8");
}
return NULL;
}
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";
case GIMP_INTERPOLATION_LOHALO: return "lohalo";
default:
break;
}
return "nearest";
}
GeglBuffer *
gimp_pixbuf_create_buffer (GdkPixbuf *pixbuf)
{
gint width;
gint height;
gint rowstride;
gint channels;
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);
channels = gdk_pixbuf_get_n_channels (pixbuf);
return gegl_buffer_linear_new_from_data (gdk_pixbuf_get_pixels (pixbuf),
gimp_bpp_to_babl_format (channels),
GIMP_GEGL_RECT (0,0,width,height),
rowstride,
(GDestroyNotify) g_object_unref,
g_object_ref (pixbuf));
}
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));
buffer = gimp_tile_manager_create_buffer (tiles, format);
tile_manager_unref (tiles);
return buffer;
}
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;
}
GeglBuffer *
gimp_tile_manager_create_buffer (TileManager *tm,
const Babl *format)
{
GeglTileBackend *backend;
GeglBuffer *buffer;
backend = gimp_tile_backend_tile_manager_new (tm, format);
buffer = gegl_buffer_new_for_backend (NULL, backend);
g_object_unref (backend);
return buffer;
}
/* 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);
gegl_buffer_flush (buffer);
return gimp_tile_backend_tile_manager_get_tiles (backend);
}
GeglBuffer *
gimp_temp_buf_create_buffer (TempBuf *temp_buf,
const Babl *format)
{
TempBuf *new;
GeglBuffer *buffer;
gint width, height;
g_return_val_if_fail (temp_buf != NULL, NULL);
g_return_val_if_fail (format != NULL, NULL);
g_return_val_if_fail (babl_format_get_bytes_per_pixel (format) ==
temp_buf->bytes, NULL);
width = temp_buf->width;
height = temp_buf->height;
new = temp_buf_copy (temp_buf, NULL);
buffer = gegl_buffer_linear_new_from_data (temp_buf_get_data (new),
format,
GIMP_GEGL_RECT (0, 0, width, height),
width * new->bytes,
(GDestroyNotify) temp_buf_free, new);
g_object_set_data (G_OBJECT (buffer), "gimp-temp-buf", new);
return buffer;
}
TempBuf *
gimp_gegl_buffer_get_temp_buf (GeglBuffer *buffer)
{
g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);
return g_object_get_data (G_OBJECT (buffer), "gimp-temp-buf");
}
void
gimp_gegl_buffer_refetch_tiles (GeglBuffer *buffer)
{
g_return_if_fail (GEGL_IS_BUFFER (buffer));
gegl_tile_source_reinit (GEGL_TILE_SOURCE (buffer));
}
GeglColor *
gimp_gegl_color_new (const GimpRGB *rgb)
{
GeglColor *color;
g_return_val_if_fail (rgb != NULL, NULL);
color = gegl_color_new (NULL);
gegl_color_set_rgba (color, rgb->r, rgb->g, rgb->b, rgb->a);
return color;
}
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);
}