gimp/app/core/gimptempbuf.c

211 lines
5.1 KiB
C
Raw Normal View History

/* GIMP - The GNU Image Manipulation Program
1997-11-25 06:05:25 +08:00
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
1997-11-25 06:05:25 +08:00
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
1997-11-25 06:05:25 +08:00
* (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/>.
1997-11-25 06:05:25 +08:00
*/
#include "config.h"
#include <string.h>
#include <cairo.h>
#include <gegl.h>
#include <glib/gstdio.h>
new directory app/base/ 2001-05-15 Michael Natterer <mitch@gimp.org> * configure.in: new directory app/base/ * app/Makefile.am * app/boundary.[ch] * app/brush_scale.[ch] * app/gimpchecks.h * app/gimplut.[ch] * app/pixel_processor.[ch] * app/pixel_region.[ch] * app/pixel_surround.[ch] * app/temp_buf.[ch] * app/tile.[ch] * app/tile_cache.[ch] * app/tile_manager.[ch] * app/tile_manager_pvt.h * app/tile_pvt.h * app/tile_swap.[ch]: moved to base/ * app/base/Makefile.am * app/base/base-types.h * app/base/*: new directory for the sub-object pixel maniplation and storage stuff. Does not include Gtk+ or anything outside base/. Did some cleanup in all files. * app/appenums.h * app/apptypes.h * app/core/gimpimage.h: removed types which are now in base/base-types.h. * app/base/base-config.[ch] * app/gimprc.[ch]: put the config variables for base/ to their own file so base/ doesn not have to include gimprc.h (does not yet work, i.e. the variables are un-configurable right now) * app/main.c: set a log handler for "Gimp-Base". * app/paint-funcs/Makefile.am * app/paint-funcs/paint-funcs.[ch]: removed the color hash which maps RGB to color indices because it's a totally standalone system which has nothing to do with the paint-funcs and introduced a GimpImage dependency. paint-funcs/ should be considered on the same sub-object (glib-only) level as base/, only in a different directory. * app/core/Makefile.am * app/core/gimpimage-colorhash.[ch]: put the color hash here. * app/gimage.c: don't invalidate the color hash here... * app/core/gimpimage.c: ... but in the colormap_changed() default inplementation. Initialize the hash in class_init(). * tools/pdbgen/Makefile.am: scan app/base/base-types.h for enums. * tools/pdbgen/enums.pl: regenerated. * app/[lots] * app/core/[of] * app/gui/[files] * app/pdb/[all] * app/tools/[over] * app/widgets/[the] * tools/pdbgen/pdb/[place]: changed #includes accordingly. And use base_config->value instead of the stuff from gimprc.h.
2001-05-15 19:25:25 +08:00
#include "core-types.h"
#include "gimptempbuf.h"
2012-04-09 02:25:49 +08:00
GimpTempBuf *
gimp_temp_buf_new (gint width,
gint height,
const Babl *format)
1997-11-25 06:05:25 +08:00
{
2012-04-09 02:25:49 +08:00
GimpTempBuf *temp;
1997-11-25 06:05:25 +08:00
Michael Natterer <mitch@gimp.org> 2001-12-03 Sven Neumann <sven@gimp.org> Michael Natterer <mitch@gimp.org> * app/paint-funcs/paint-funcs-mmx.h: removed redefiniton of HAS_ALPHA macro. * app/core/gimp.c: reverted Daniel's change; it doesn't make the code simpler, only more error-prone. * app/gui/info-dialog.h * app/gui/resize-dialog.h * app/core/gimp.h * app/core/gimpbrushgenerated.h * app/core/gimpbrushpipe.h * app/core/gimpchannel.[ch] * app/core/gimpcontainer.h * app/core/gimpcoreconfig.h * app/core/gimpdata.h * app/core/gimpdatafactory.[ch] * app/core/gimpdrawable-blend.c * app/core/gimpdrawable.[ch] * app/core/gimpimage.h * app/core/gimpimagefile.h * app/core/gimplayer.h * app/core/gimplayermask.h * app/core/gimpmoduleinfo.h * app/core/gimppalette.h * app/core/gimpundo.h * app/widgets/gimpbrushfactoryview.h * app/widgets/gimpconstrainedhwrapbox.h * app/widgets/gimpcontainermenu.h * app/widgets/gimpcontainerview.h * app/widgets/gimpdialogfactory.h * app/widgets/gimpimagedock.h * app/widgets/gimplistitem.h * app/widgets/gimpmenuitem.h * app/widgets/gimpnavigationpreview.h * app/widgets/gimppreview.h * app/gimprc.h * app/pathP.h * app/tools/gimpbezierselecttool.h * app/tools/gimpcolorbalancetool.h * app/tools/gimpcurvestool.h * app/tools/gimpdodgeburntool.c * app/tools/gimpfreeselecttool.h * app/tools/gimphuesaturationtool.h * app/tools/gimpinktool-blob.h * app/tools/gimpinktool.h * app/tools/gimpiscissorstool.h * app/tools/gimpmagnifytool.h * app/tools/gimpmeasuretool.h * app/tools/gimppainttool.h * app/tools/gimppathtool.h * app/tools/gimprectselecttool.h * app/tools/gimpthresholdtool.h * app/tools/gimptool.h * app/tools/gimptransformtool.h * app/base/base-config.h * app/base/gimplut.[ch] * app/base/pixel-region.h * app/base/pixel-surround.[ch] * app/base/temp-buf.[ch] * app/base/tile-manager-private.h * app/base/tile-manager.[ch] * app/base/tile-private.h * app/base/tile.[ch] * app/display/gimpdisplay.h * app/display/gimpdisplayshell-selection.h * app/display/gimpdisplayshell.h * app/gui/brush-select.h * app/gui/gradient-editor.h * app/gui/gradient-select.h: reverted most of Daniel's changes. There's no reason to use unsigned integers here and in lots of places it is even wrong. Then it's way too early to convert gbooleans into bitfields. This change may make sense in a few places but can happen later when the API has settled and the code is more stable. * app/gimprc.c: reverted Daniel's change. This is a GCC-ism and this code is about to die soon anyway.
2001-12-03 21:44:59 +08:00
g_return_val_if_fail (width > 0 && height > 0, NULL);
g_return_val_if_fail (format != NULL, NULL);
2012-04-09 02:25:49 +08:00
temp = g_slice_new (GimpTempBuf);
1997-11-25 06:05:25 +08:00
temp->ref_count = 1;
temp->format = format;
temp->width = width;
temp->height = height;
1997-11-25 06:05:25 +08:00
temp->data = g_new (guchar,
width * height *
babl_format_get_bytes_per_pixel (format));
1997-11-25 06:05:25 +08:00
return temp;
}
2012-04-09 02:25:49 +08:00
GimpTempBuf *
gimp_temp_buf_copy (const GimpTempBuf *src)
1997-11-25 06:05:25 +08:00
{
2012-04-09 02:25:49 +08:00
GimpTempBuf *dest;
g_return_val_if_fail (src != NULL, NULL);
dest = gimp_temp_buf_new (src->width, src->height, src->format);
1997-11-25 06:05:25 +08:00
memcpy (gimp_temp_buf_get_data (dest),
gimp_temp_buf_get_data (src),
gimp_temp_buf_get_data_size (src));
1997-11-25 06:05:25 +08:00
return dest;
1997-11-25 06:05:25 +08:00
}
GimpTempBuf *
gimp_temp_buf_ref (GimpTempBuf *buf)
{
g_return_val_if_fail (buf != NULL, NULL);
buf->ref_count++;
return buf;
}
void
gimp_temp_buf_unref (GimpTempBuf *buf)
{
g_return_if_fail (buf != NULL);
g_return_if_fail (buf->ref_count > 0);
buf->ref_count--;
if (buf->ref_count < 1)
{
if (buf->data)
g_free (buf->data);
g_slice_free (GimpTempBuf, buf);
}
}
2012-04-09 02:25:49 +08:00
GimpTempBuf *
gimp_temp_buf_scale (const GimpTempBuf *src,
gint new_width,
gint new_height)
{
2012-04-09 02:25:49 +08:00
GimpTempBuf *dest;
const guchar *src_data;
guchar *dest_data;
gdouble x_ratio;
gdouble y_ratio;
gint bytes;
gint loop1;
gint loop2;
g_return_val_if_fail (src != NULL, NULL);
g_return_val_if_fail (new_width > 0 && new_height > 0, NULL);
if (new_width == src->width && new_height == src->height)
return gimp_temp_buf_copy (src);
dest = gimp_temp_buf_new (new_width,
new_height,
src->format);
src_data = gimp_temp_buf_get_data (src);
dest_data = gimp_temp_buf_get_data (dest);
x_ratio = (gdouble) src->width / (gdouble) new_width;
y_ratio = (gdouble) src->height / (gdouble) new_height;
bytes = babl_format_get_bytes_per_pixel (src->format);
for (loop1 = 0 ; loop1 < new_height ; loop1++)
{
for (loop2 = 0 ; loop2 < new_width ; loop2++)
{
const guchar *src_pixel;
guchar *dest_pixel;
gint i;
src_pixel = src_data +
(gint) (loop2 * x_ratio) * bytes +
(gint) (loop1 * y_ratio) * bytes * src->width;
dest_pixel = dest_data +
(loop2 + loop1 * new_width) * bytes;
for (i = 0 ; i < bytes; i++)
*dest_pixel++ = *src_pixel++;
}
}
return dest;
}
guchar *
gimp_temp_buf_get_data (const GimpTempBuf *buf)
1997-11-25 06:05:25 +08:00
{
return buf->data;
1997-11-25 06:05:25 +08:00
}
gsize
gimp_temp_buf_get_data_size (const GimpTempBuf *buf)
{
return babl_format_get_bytes_per_pixel (buf->format) * buf->width * buf->height;
}
guchar *
gimp_temp_buf_data_clear (GimpTempBuf *buf)
{
memset (buf->data, 0, gimp_temp_buf_get_data_size (buf));
return buf->data;
}
1997-11-25 06:05:25 +08:00
gsize
gimp_temp_buf_get_memsize (const GimpTempBuf *buf)
{
if (buf)
return (sizeof (GimpTempBuf) + gimp_temp_buf_get_data_size (buf));
return 0;
}
GeglBuffer *
gimp_temp_buf_create_buffer (GimpTempBuf *temp_buf)
{
GeglBuffer *buffer;
g_return_val_if_fail (temp_buf != NULL, NULL);
buffer =
gegl_buffer_linear_new_from_data (gimp_temp_buf_get_data (temp_buf),
temp_buf->format,
GEGL_RECTANGLE (0, 0,
temp_buf->width,
temp_buf->height),
GEGL_AUTO_ROWSTRIDE,
(GDestroyNotify) gimp_temp_buf_unref,
gimp_temp_buf_ref (temp_buf));
g_object_set_data (G_OBJECT (buffer), "gimp-temp-buf", temp_buf);
return buffer;
}
GimpTempBuf *
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");
}