/* LIBGIMP - The GIMP Library
 * Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball
 *
 * gimpimage_pdb.c
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/* NOTE: This file is autogenerated by pdbgen.pl */

#include "config.h"

#include <string.h>

#include "gimp.h"

/**
 * gimp_image_list:
 * @num_images: The number of images currently open.
 *
 * Returns the list of images currently open.
 *
 * This procedure returns the list of images currently open in the
 * GIMP.
 *
 * Returns: The list of images currently open.
 */
gint *
gimp_image_list (gint *num_images)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint *image_ids = NULL;

  return_vals = gimp_run_procedure ("gimp_image_list",
				    &nreturn_vals,
				    GIMP_PDB_END);

  *num_images = 0;

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    {
      *num_images = return_vals[1].data.d_int32;
      image_ids = g_new (gint32, *num_images);
      memcpy (image_ids, return_vals[2].data.d_int32array,
	      *num_images * sizeof (gint32));
    }

  gimp_destroy_params (return_vals, nreturn_vals);

  return image_ids;
}

/**
 * gimp_image_new:
 * @width: The width of the image.
 * @height: The height of the image.
 * @type: The type of image.
 *
 * Creates a new image with the specified width, height, and type.
 *
 * Creates a new image, undisplayed with the specified extents and
 * type. A layer should be created and added before this image is
 * displayed, or subsequent calls to 'gimp_display_new' with this image
 * as an argument will fail. Layers can be created using the
 * 'gimp_layer_new' commands. They can be added to an image using the
 * 'gimp_image_add_layer' command.
 *
 * Returns: The ID of the newly created image.
 */
gint32
gimp_image_new (gint              width,
		gint              height,
		GimpImageBaseType type)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint32 image_ID = -1;

  return_vals = gimp_run_procedure ("gimp_image_new",
				    &nreturn_vals,
				    GIMP_PDB_INT32, width,
				    GIMP_PDB_INT32, height,
				    GIMP_PDB_INT32, type,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    image_ID = return_vals[1].data.d_image;

  gimp_destroy_params (return_vals, nreturn_vals);

  return image_ID;
}

/**
 * gimp_image_duplicate:
 * @image_ID: The image.
 *
 * Duplicate the specified image
 *
 * This procedure duplicates the specified image, copying all layers,
 * channels, and image information.
 *
 * Returns: The new, duplicated image.
 */
gint32
gimp_image_duplicate (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint32 new_image_ID = -1;

  return_vals = gimp_run_procedure ("gimp_image_duplicate",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    new_image_ID = return_vals[1].data.d_image;

  gimp_destroy_params (return_vals, nreturn_vals);

  return new_image_ID;
}

/**
 * gimp_image_delete:
 * @image_ID: The image.
 *
 * Delete the specified image.
 *
 * If there are no displays associated with this image it will be
 * deleted. This means that you can not delete an image through the PDB
 * that was created by the user. If the associated display was however
 * created through the PDB and you know the display ID, you may delete
 * the display. Removal of the last associated display will then delete
 * the image.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_delete (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_delete",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_base_type:
 * @image_ID: The image.
 *
 * Get the base type of the image.
 *
 * This procedure returns the image's base type. Layers in the image
 * must be of this subtype, but can have an optional alpha channel.
 *
 * Returns: The image's base type.
 */
GimpImageBaseType
gimp_image_base_type (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  GimpImageBaseType base_type = 0;

  return_vals = gimp_run_procedure ("gimp_image_base_type",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    base_type = return_vals[1].data.d_int32;

  gimp_destroy_params (return_vals, nreturn_vals);

  return base_type;
}

/**
 * gimp_image_width:
 * @image_ID: The image.
 *
 * Return the width of the image
 *
 * This procedure returns the image's width. This value is independent
 * of any of the layers in this image. This is the \"canvas\" width.
 *
 * Returns: The image's width.
 */
gint
gimp_image_width (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint width = 0;

  return_vals = gimp_run_procedure ("gimp_image_width",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    width = return_vals[1].data.d_int32;

  gimp_destroy_params (return_vals, nreturn_vals);

  return width;
}

/**
 * gimp_image_height:
 * @image_ID: The image.
 *
 * Return the height of the image
 *
 * This procedure returns the image's height. This value is independent
 * of any of the layers in this image. This is the \"canvas\" height.
 *
 * Returns: The image's height.
 */
gint
gimp_image_height (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint height = 0;

  return_vals = gimp_run_procedure ("gimp_image_height",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    height = return_vals[1].data.d_int32;

  gimp_destroy_params (return_vals, nreturn_vals);

  return height;
}

/**
 * gimp_image_free_shadow:
 * @image_ID: The image.
 *
 * Free the specified image's shadow data (if it exists).
 *
 * This procedure is intended as a memory saving device. If any shadow
 * memory has been allocated, it will be freed automatically on a call
 * to 'gimp_image_delete'.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_free_shadow (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_free_shadow",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_resize:
 * @image_ID: The image.
 * @new_width: New image width.
 * @new_height: New image height.
 * @offx: x offset between upper left corner of old and new images: (new - old).
 * @offy: y offset between upper left corner of old and new images: (new - old).
 *
 * Resize the image to the specified extents.
 *
 * This procedure resizes the image so that it's new width and height
 * are equal to the supplied parameters. Offsets are also provided
 * which describe the position of the previous image's content. No
 * bounds checking is currently provided, so don't supply parameters
 * that are out of bounds. All channels within the image are resized
 * according to the specified parameters; this includes the image
 * selection mask. All layers within the image are repositioned
 * according to the specified offsets.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_resize (gint32 image_ID,
		   gint   new_width,
		   gint   new_height,
		   gint   offx,
		   gint   offy)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_resize",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, new_width,
				    GIMP_PDB_INT32, new_height,
				    GIMP_PDB_INT32, offx,
				    GIMP_PDB_INT32, offy,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_scale:
 * @image_ID: The image.
 * @new_width: New image width.
 * @new_height: New image height.
 *
 * Scale the image to the specified extents.
 *
 * This procedure scales the image so that it's new width and height
 * are equal to the supplied parameters. Offsets are also provided
 * which describe the position of the previous image's content. No
 * bounds checking is currently provided, so don't supply parameters
 * that are out of bounds. All channels within the image are scaled
 * according to the specified parameters; this includes the image
 * selection mask. All layers within the image are repositioned
 * according to the specified offsets.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_scale (gint32 image_ID,
		  gint   new_width,
		  gint   new_height)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_scale",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, new_width,
				    GIMP_PDB_INT32, new_height,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_crop:
 * @image_ID: The image.
 * @new_width: New image width: (0 < new_width <= width).
 * @new_height: New image height: (0 < new_height <= height).
 * @offx: x offset: (0 <= offx <= (width - new_width)).
 * @offy: y offset: (0 <= offy <= (height - new_height)).
 *
 * Crop the image to the specified extents.
 *
 * This procedure crops the image so that it's new width and height are
 * equal to the supplied parameters. Offsets are also provided which
 * describe the position of the previous image's content. All channels
 * and layers within the image are cropped to the new image extents;
 * this includes the image selection mask. If any parameters are out of
 * range, an error is returned.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_crop (gint32 image_ID,
		 gint   new_width,
		 gint   new_height,
		 gint   offx,
		 gint   offy)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_crop",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, new_width,
				    GIMP_PDB_INT32, new_height,
				    GIMP_PDB_INT32, offx,
				    GIMP_PDB_INT32, offy,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_flip:
 * @image_ID: The image.
 * @flip_type: Type of flip.
 *
 * Flips the image horizontally or vertically.
 *
 * This procedure flips (mirrors) the image.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_flip (gint32              image_ID,
		 GimpOrientationType flip_type)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_flip",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, flip_type,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_rotate:
 * @image_ID: The image.
 * @rotate_type: Angle of rotation.
 *
 * Rotates the image by the specified degrees.
 *
 * This procedure rotates the image.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_rotate (gint32           image_ID,
		   GimpRotationType rotate_type)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_rotate",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, rotate_type,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_get_layers:
 * @image_ID: The image.
 * @num_layers: The number of layers contained in the image.
 *
 * Returns the list of layers contained in the specified image.
 *
 * This procedure returns the list of layers contained in the specified
 * image. The order of layers is from topmost to bottommost.
 *
 * Returns: The list of layers contained in the image.
 */
gint *
gimp_image_get_layers (gint32  image_ID,
		       gint   *num_layers)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint *layer_ids = NULL;

  return_vals = gimp_run_procedure ("gimp_image_get_layers",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  *num_layers = 0;

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    {
      *num_layers = return_vals[1].data.d_int32;
      layer_ids = g_new (gint32, *num_layers);
      memcpy (layer_ids, return_vals[2].data.d_int32array,
	      *num_layers * sizeof (gint32));
    }

  gimp_destroy_params (return_vals, nreturn_vals);

  return layer_ids;
}

/**
 * gimp_image_get_channels:
 * @image_ID: The image.
 * @num_channels: The number of channels contained in the image.
 *
 * Returns the list of channels contained in the specified image.
 *
 * This procedure returns the list of channels contained in the
 * specified image. This does not include the selection mask, or layer
 * masks. The order is from topmost to bottommost.
 *
 * Returns: The list of channels contained in the image.
 */
gint *
gimp_image_get_channels (gint32  image_ID,
			 gint   *num_channels)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint *channel_ids = NULL;

  return_vals = gimp_run_procedure ("gimp_image_get_channels",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  *num_channels = 0;

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    {
      *num_channels = return_vals[1].data.d_int32;
      channel_ids = g_new (gint32, *num_channels);
      memcpy (channel_ids, return_vals[2].data.d_int32array,
	      *num_channels * sizeof (gint32));
    }

  gimp_destroy_params (return_vals, nreturn_vals);

  return channel_ids;
}

/**
 * gimp_image_get_active_drawable:
 * @image_ID: The image.
 *
 * Get the image's active drawable
 *
 * This procedure returns the ID of the image's active drawable. This
 * can be either a layer, a channel, or a layer mask. The active
 * drawable is specified by the active image channel. If that is -1,
 * then by the active image layer. If the active image layer has a
 * layer mask and the layer mask is in edit mode, then the layer mask
 * is the active drawable.
 *
 * Returns: The active drawable.
 */
gint32
gimp_image_get_active_drawable (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint32 drawable_ID = -1;

  return_vals = gimp_run_procedure ("gimp_image_get_active_drawable",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    drawable_ID = return_vals[1].data.d_drawable;

  gimp_destroy_params (return_vals, nreturn_vals);

  return drawable_ID;
}

/**
 * gimp_image_unset_active_channel:
 * @image_ID: The image.
 *
 * Unsets the active channel in the specified image.
 *
 * If an active channel exists, it is unset. There then exists no
 * active channel, and if desired, one can be set through a call to
 * 'Set Active Channel'. No error is returned in the case of no
 * existing active channel.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_unset_active_channel (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_unset_active_channel",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_get_floating_sel:
 * @image_ID: The image.
 *
 * Return the floating selection of the image.
 *
 * This procedure returns the image's floating selection, if it exists.
 * If it doesn't exist, -1 is returned as the layer ID.
 *
 * Returns: The image's floating selection.
 */
gint32
gimp_image_get_floating_sel (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint32 floating_sel_ID = -1;

  return_vals = gimp_run_procedure ("gimp_image_get_floating_sel",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    floating_sel_ID = return_vals[1].data.d_layer;

  gimp_destroy_params (return_vals, nreturn_vals);

  return floating_sel_ID;
}

/**
 * gimp_image_floating_sel_attached_to:
 * @image_ID: The image.
 *
 * Return the drawable the floating selection is attached to.
 *
 * This procedure returns the drawable the image's floating selection
 * is attached to, if it exists. If it doesn't exist, -1 is returned as
 * the drawable ID.
 *
 * Returns: The drawable the floating selection is attached to.
 */
gint32
gimp_image_floating_sel_attached_to (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint32 drawable_ID = -1;

  return_vals = gimp_run_procedure ("gimp_image_floating_sel_attached_to",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    drawable_ID = return_vals[1].data.d_drawable;

  gimp_destroy_params (return_vals, nreturn_vals);

  return drawable_ID;
}

/**
 * gimp_image_pick_color:
 * @image_ID: The image.
 * @drawable_ID: The drawable to pick from.
 * @x: x coordinate of upper-left corner of rectangle.
 * @y: y coordinate of upper-left corner of rectangle.
 * @sample_merged: Use the composite image, not the drawable.
 * @sample_average: Average the color of all the pixels in a specified radius.
 * @average_radius: The radius of pixels to average.
 * @color: The return color.
 *
 * Determine the color at the given drawable coordinates
 *
 * This tool determines the color at the specified coordinates. The
 * returned color is an RGB triplet even for grayscale and indexed
 * drawables. If the coordinates lie outside of the extents of the
 * specified drawable, then an error is returned. If the drawable has
 * an alpha channel, the algorithm examines the alpha value of the
 * drawable at the coordinates. If the alpha value is completely
 * transparent (0), then an error is returned. If the sample_merged
 * parameter is non-zero, the data of the composite image will be used
 * instead of that for the specified drawable. This is equivalent to
 * sampling for colors after merging all visible layers. In the case of
 * a merged sampling, the supplied drawable is ignored except for
 * finding the image it belongs to.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_pick_color (gint32    image_ID,
		       gint32    drawable_ID,
		       gdouble   x,
		       gdouble   y,
		       gboolean  sample_merged,
		       gboolean  sample_average,
		       gdouble   average_radius,
		       GimpRGB  *color)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_pick_color",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_DRAWABLE, drawable_ID,
				    GIMP_PDB_FLOAT, x,
				    GIMP_PDB_FLOAT, y,
				    GIMP_PDB_INT32, sample_merged,
				    GIMP_PDB_INT32, sample_average,
				    GIMP_PDB_FLOAT, average_radius,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  if (success)
    *color = return_vals[1].data.d_color;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_pick_correlate_layer:
 * @image_ID: The image.
 * @x: The x coordinate for the pick.
 * @y: The y coordinate for the pick.
 *
 * Find the layer visible at the specified coordinates.
 *
 * This procedure finds the layer which is visible at the specified
 * coordinates. Layers which do not qualify are those whose extents do
 * not pass within the specified coordinates, or which are transparent
 * at the specified coordinates. This procedure will return -1 if no
 * layer is found.
 *
 * Returns: The layer found at the specified coordinates.
 */
gint32
gimp_image_pick_correlate_layer (gint32 image_ID,
				 gint   x,
				 gint   y)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint32 layer_ID = -1;

  return_vals = gimp_run_procedure ("gimp_image_pick_correlate_layer",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, x,
				    GIMP_PDB_INT32, y,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    layer_ID = return_vals[1].data.d_layer;

  gimp_destroy_params (return_vals, nreturn_vals);

  return layer_ID;
}

/**
 * gimp_image_add_layer:
 * @image_ID: The image.
 * @layer_ID: The layer.
 * @position: The layer position.
 *
 * Add the specified layer to the image.
 *
 * This procedure adds the specified layer to the gimage at the given
 * position. If the position is specified as -1, then the layer is
 * inserted at the top of the layer stack. If the layer to be added has
 * no alpha channel, it must be added at position 0. The layer type
 * must be compatible with the image base type.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_add_layer (gint32 image_ID,
		      gint32 layer_ID,
		      gint   position)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_add_layer",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_LAYER, layer_ID,
				    GIMP_PDB_INT32, position,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_remove_layer:
 * @image_ID: The image.
 * @layer_ID: The layer.
 *
 * Remove the specified layer from the image.
 *
 * This procedure removes the specified layer from the image. If the
 * layer doesn't exist, an error is returned. If there are no layers
 * left in the image, this call will fail. If this layer is the last
 * layer remaining, the image will become empty and have no active
 * layer.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_remove_layer (gint32 image_ID,
			 gint32 layer_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_remove_layer",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_LAYER, layer_ID,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_raise_layer:
 * @image_ID: The image.
 * @layer_ID: The layer to raise.
 *
 * Raise the specified layer in the image's layer stack
 *
 * This procedure raises the specified layer one step in the existing
 * layer stack. It will not move the layer if there is no layer above
 * it, or the layer has no alpha channel.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_raise_layer (gint32 image_ID,
			gint32 layer_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_raise_layer",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_LAYER, layer_ID,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_lower_layer:
 * @image_ID: The image.
 * @layer_ID: The layer to lower.
 *
 * Lower the specified layer in the image's layer stack
 *
 * This procedure lowers the specified layer one step in the existing
 * layer stack. It will not move the layer if there is no layer below
 * it, or the layer has no alpha channel.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_lower_layer (gint32 image_ID,
			gint32 layer_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_lower_layer",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_LAYER, layer_ID,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_raise_layer_to_top:
 * @image_ID: The image.
 * @layer_ID: The layer to raise to top.
 *
 * Raise the specified layer in the image's layer stack to top of stack
 *
 * This procedure raises the specified layer to top of the existing
 * layer stack. It will not move the layer if there is no layer above
 * it, or the layer has no alpha channel.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_raise_layer_to_top (gint32 image_ID,
			       gint32 layer_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_raise_layer_to_top",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_LAYER, layer_ID,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_lower_layer_to_bottom:
 * @image_ID: The image.
 * @layer_ID: The layer to lower to bottom.
 *
 * Lower the specified layer in the image's layer stack to bottom of
 * stack
 *
 * This procedure lowers the specified layer to bottom of the existing
 * layer stack. It will not move the layer if there is no layer below
 * it, or the layer has no alpha channel.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_lower_layer_to_bottom (gint32 image_ID,
				  gint32 layer_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_lower_layer_to_bottom",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_LAYER, layer_ID,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_add_channel:
 * @image_ID: The image.
 * @channel_ID: The channel.
 * @position: The channel position.
 *
 * Add the specified channel to the image.
 *
 * This procedure adds the specified channel to the image. The position
 * channel is not currently used, so the channel is always inserted at
 * the top of the channel stack.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_add_channel (gint32 image_ID,
			gint32 channel_ID,
			gint   position)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_add_channel",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_CHANNEL, channel_ID,
				    GIMP_PDB_INT32, position,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_remove_channel:
 * @image_ID: The image.
 * @channel_ID: The channel.
 *
 * Remove the specified channel from the image.
 *
 * This procedure removes the specified channel from the image. If the
 * channel doesn't exist, an error is returned.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_remove_channel (gint32 image_ID,
			   gint32 channel_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_remove_channel",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_CHANNEL, channel_ID,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_raise_channel:
 * @image_ID: The image.
 * @channel_ID: The channel to raise.
 *
 * Raise the specified channel in the image's channel stack
 *
 * This procedure raises the specified channel one step in the existing
 * channel stack. It will not move the channel if there is no channel
 * above it.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_raise_channel (gint32 image_ID,
			  gint32 channel_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_raise_channel",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_CHANNEL, channel_ID,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_lower_channel:
 * @image_ID: The image.
 * @layer_ID: The layer to lower.
 *
 * Lower the specified layer in the image's layer stack
 *
 * This procedure lowers the specified layer one step in the existing
 * layer stack. It will not move the layer if there is no layer below
 * it, or the layer has no alpha channel.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_lower_channel (gint32 image_ID,
			  gint32 layer_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_lower_channel",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_LAYER, layer_ID,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_flatten:
 * @image_ID: The image.
 *
 * Flatten all visible layers into a single layer. Discard all
 * invisible layers.
 *
 * This procedure combines the visible layers in a manner analogous to
 * merging with the CLIP_TO_IMAGE merge type. Non-visible layers are
 * discarded, and the resulting image is stripped of its alpha channel.
 *
 * Returns: The resulting layer.
 */
gint32
gimp_image_flatten (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint32 layer_ID = -1;

  return_vals = gimp_run_procedure ("gimp_image_flatten",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    layer_ID = return_vals[1].data.d_layer;

  gimp_destroy_params (return_vals, nreturn_vals);

  return layer_ID;
}

/**
 * gimp_image_merge_visible_layers:
 * @image_ID: The image.
 * @merge_type: The type of merge.
 *
 * Merge the visible image layers into one.
 *
 * This procedure combines the visible layers into a single layer using
 * the specified merge type. A merge type of EXPAND_AS_NECESSARY
 * expands the final layer to encompass the areas of the visible
 * layers. A merge type of CLIP_TO_IMAGE clips the final layer to the
 * extents of the image. A merge type of CLIP_TO_BOTTOM_LAYER clips the
 * final layer to the size of the bottommost layer.
 *
 * Returns: The resulting layer.
 */
gint32
gimp_image_merge_visible_layers (gint32        image_ID,
				 GimpMergeType merge_type)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint32 layer_ID = -1;

  return_vals = gimp_run_procedure ("gimp_image_merge_visible_layers",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, merge_type,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    layer_ID = return_vals[1].data.d_layer;

  gimp_destroy_params (return_vals, nreturn_vals);

  return layer_ID;
}

/**
 * gimp_image_merge_down:
 * @image_ID: The image.
 * @merge_layer_ID: The layer to merge down from.
 * @merge_type: The type of merge.
 *
 * Merge the layer passed and the first visible layer below.
 *
 * This procedure combines the passed layer and the first visible layer
 * below it using the specified merge type. A merge type of
 * EXPAND_AS_NECESSARY expands the final layer to encompass the areas
 * of the visible layers. A merge type of CLIP_TO_IMAGE clips the final
 * layer to the extents of the image. A merge type of
 * CLIP_TO_BOTTOM_LAYER clips the final layer to the size of the
 * bottommost layer.
 *
 * Returns: The resulting layer.
 */
gint32
gimp_image_merge_down (gint32        image_ID,
		       gint32        merge_layer_ID,
		       GimpMergeType merge_type)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint32 layer_ID = -1;

  return_vals = gimp_run_procedure ("gimp_image_merge_down",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_LAYER, merge_layer_ID,
				    GIMP_PDB_INT32, merge_type,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    layer_ID = return_vals[1].data.d_layer;

  gimp_destroy_params (return_vals, nreturn_vals);

  return layer_ID;
}

/**
 * _gimp_image_get_cmap:
 * @image_ID: The image.
 * @num_bytes: Number of bytes in the colormap array.
 *
 * Returns the image's colormap
 *
 * This procedure returns an actual pointer to the image's colormap, as
 * well as the number of bytes contained in the colormap. The actual
 * number of colors in the transmitted colormap will be \"num_bytes\" /
 * 3. If the image is not of base type GIMP_INDEXED, this pointer will
 * be NULL.
 *
 * Returns: The image's colormap.
 */
guint8 *
_gimp_image_get_cmap (gint32  image_ID,
		      gint   *num_bytes)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  guint8 *cmap = NULL;

  return_vals = gimp_run_procedure ("gimp_image_get_cmap",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  *num_bytes = 0;

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    {
      *num_bytes = return_vals[1].data.d_int32;
      cmap = g_new (guint8, *num_bytes);
      memcpy (cmap, return_vals[2].data.d_int8array,
	      *num_bytes * sizeof (guint8));
    }

  gimp_destroy_params (return_vals, nreturn_vals);

  return cmap;
}

/**
 * _gimp_image_set_cmap:
 * @image_ID: The image.
 * @num_bytes: Number of bytes in the colormap array.
 * @cmap: The new colormap values.
 *
 * Sets the entries in the image's colormap.
 *
 * This procedure sets the entries in the specified image's colormap.
 * The number of entries is specified by the \"num_bytes\" parameter
 * and corresponds to the number of INT8 triples that must be contained
 * in the \"cmap\" array. The actual number of colors in the
 * transmitted colormap is \"num_bytes\" / 3.
 *
 * Returns: TRUE on success.
 */
gboolean
_gimp_image_set_cmap (gint32        image_ID,
		      gint          num_bytes,
		      const guint8 *cmap)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_set_cmap",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, num_bytes,
				    GIMP_PDB_INT8ARRAY, cmap,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_clean_all:
 * @image_ID: The image.
 *
 * Set the image dirty count to 0.
 *
 * This procedure sets the specified image's dirty count to 0, allowing
 * operations to occur without having a 'dirtied' image. This is
 * especially useful for creating and loading images which should not
 * initially be considered dirty, even though layers must be created,
 * filled, and installed in the image.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_clean_all (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_clean_all",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_is_dirty:
 * @image_ID: The image.
 *
 * Checks if the image has unsaved changes.
 *
 * This procedure checks the specified image's dirty count to see if it
 * needs to be saved.
 *
 * Returns: True if the image has unsaved changed.
 */
gboolean
gimp_image_is_dirty (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean dirty = FALSE;

  return_vals = gimp_run_procedure ("gimp_image_is_dirty",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    dirty = return_vals[1].data.d_int32;

  gimp_destroy_params (return_vals, nreturn_vals);

  return dirty;
}

/**
 * _gimp_image_thumbnail:
 * @image_ID: The image.
 * @width: The thumbnail width.
 * @height: The thumbnail height.
 * @ret_width: The previews width.
 * @ret_height: The previews height.
 * @bpp: The previews bpp.
 * @thumbnail_data_count: The number of bytes in thumbnail data.
 * @thumbnail_data: The thumbnail data.
 *
 * Get a thumbnail of an image.
 *
 * This function gets data from which a thumbnail of an image preview
 * can be created. Maximum x or y dimension is 1024 pixels. The pixels
 * are returned in the RGB[A] format. The bpp return value gives the
 * number of bits per pixel in the image. If the image has an alpha
 * channel, it is also returned.
 *
 * Returns: TRUE on success.
 */
gboolean
_gimp_image_thumbnail (gint32   image_ID,
		       gint     width,
		       gint     height,
		       gint    *ret_width,
		       gint    *ret_height,
		       gint    *bpp,
		       gint    *thumbnail_data_count,
		       guint8 **thumbnail_data)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_thumbnail",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, width,
				    GIMP_PDB_INT32, height,
				    GIMP_PDB_END);

  *ret_width = 0;
  *ret_height = 0;
  *bpp = 0;
  *thumbnail_data_count = 0;
  *thumbnail_data = NULL;

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  if (success)
    {
      *ret_width = return_vals[1].data.d_int32;
      *ret_height = return_vals[2].data.d_int32;
      *bpp = return_vals[3].data.d_int32;
      *thumbnail_data_count = return_vals[4].data.d_int32;
      *thumbnail_data = g_new (guint8, *thumbnail_data_count);
      memcpy (*thumbnail_data, return_vals[5].data.d_int8array,
	      *thumbnail_data_count * sizeof (guint8));
    }

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_get_active_layer:
 * @image_ID: The image.
 *
 * Returns the specified image's active layer.
 *
 * If there is an active layer, its ID will be returned, otherwise, -1.
 * If a channel is currently active, then no layer will be. If a layer
 * mask is active, then this will return the associated layer.
 *
 * Returns: The active layer.
 */
gint32
gimp_image_get_active_layer (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint32 active_layer_ID = -1;

  return_vals = gimp_run_procedure ("gimp_image_get_active_layer",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    active_layer_ID = return_vals[1].data.d_layer;

  gimp_destroy_params (return_vals, nreturn_vals);

  return active_layer_ID;
}

/**
 * gimp_image_set_active_layer:
 * @image_ID: The image.
 * @active_layer_ID: The new image active layer.
 *
 * Sets the specified image's active layer.
 *
 * If the layer exists, it is set as the active layer in the image. Any
 * previous active layer or channel is set to inactive. An exception is
 * a previously existing floating selection, in which case this
 * procedure will return an execution error.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_set_active_layer (gint32 image_ID,
			     gint32 active_layer_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_set_active_layer",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_LAYER, active_layer_ID,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_get_active_channel:
 * @image_ID: The image.
 *
 * Returns the specified image's active channel.
 *
 * If there is an active channel, this will return the channel ID,
 * otherwise, -1.
 *
 * Returns: The active channel.
 */
gint32
gimp_image_get_active_channel (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint32 active_channel_ID = -1;

  return_vals = gimp_run_procedure ("gimp_image_get_active_channel",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    active_channel_ID = return_vals[1].data.d_channel;

  gimp_destroy_params (return_vals, nreturn_vals);

  return active_channel_ID;
}

/**
 * gimp_image_set_active_channel:
 * @image_ID: The image.
 * @active_channel_ID: The new image active channel.
 *
 * Sets the specified image's active channel.
 *
 * If the channel exists, it is set as the active channel in the image.
 * Any previous active channel or channel is set to inactive. An
 * exception is a previously existing floating selection, in which case
 * this procedure will return an execution error.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_set_active_channel (gint32 image_ID,
			       gint32 active_channel_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_set_active_channel",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_CHANNEL, active_channel_ID,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_get_selection:
 * @image_ID: The image.
 *
 * Returns the specified image's selection.
 *
 * This will always return a valid ID for a selection -- which is
 * represented as a channel internally.
 *
 * Returns: The selection channel.
 */
gint32
gimp_image_get_selection (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint32 selection_ID = -1;

  return_vals = gimp_run_procedure ("gimp_image_get_selection",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    selection_ID = return_vals[1].data.d_selection;

  gimp_destroy_params (return_vals, nreturn_vals);

  return selection_ID;
}

/**
 * gimp_image_get_component_active:
 * @image_ID: The image.
 * @component: The image component.
 *
 * Returns if the specified image's image component is active.
 *
 * This procedure returns if the specified image's image component
 * (i.e. Red, Green, Blue intensity channels in an RGB image) is active
 * or inactive -- whether or not it can be modified. If the specified
 * component is not valid for the image type, an error is returned.
 *
 * Returns: Component is active.
 */
gboolean
gimp_image_get_component_active (gint32          image_ID,
				 GimpChannelType component)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean active = FALSE;

  return_vals = gimp_run_procedure ("gimp_image_get_component_active",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, component,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    active = return_vals[1].data.d_int32;

  gimp_destroy_params (return_vals, nreturn_vals);

  return active;
}

/**
 * gimp_image_set_component_active:
 * @image_ID: The image.
 * @component: The image component.
 * @active: Component is active.
 *
 * Sets if the specified image's image component is active.
 *
 * This procedure sets if the specified image's image component (i.e.
 * Red, Green, Blue intensity channels in an RGB image) is active or
 * inactive -- whether or not it can be modified. If the specified
 * component is not valid for the image type, an error is returned.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_set_component_active (gint32          image_ID,
				 GimpChannelType component,
				 gboolean        active)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_set_component_active",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, component,
				    GIMP_PDB_INT32, active,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_get_component_visible:
 * @image_ID: The image.
 * @component: The image component.
 *
 * Returns if the specified image's image component is visible.
 *
 * This procedure returns if the specified image's image component
 * (i.e. Red, Green, Blue intensity channels in an RGB image) is
 * visible or invisible -- whether or not it can be seen. If the
 * specified component is not valid for the image type, an error is
 * returned.
 *
 * Returns: Component is visible.
 */
gboolean
gimp_image_get_component_visible (gint32          image_ID,
				  GimpChannelType component)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean visible = FALSE;

  return_vals = gimp_run_procedure ("gimp_image_get_component_visible",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, component,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    visible = return_vals[1].data.d_int32;

  gimp_destroy_params (return_vals, nreturn_vals);

  return visible;
}

/**
 * gimp_image_set_component_visible:
 * @image_ID: The image.
 * @component: The image component.
 * @visible: Component is visible.
 *
 * Sets if the specified image's image component is visible.
 *
 * This procedure sets if the specified image's image component (i.e.
 * Red, Green, Blue intensity channels in an RGB image) is visible or
 * invisible -- whether or not it can be seen. If the specified
 * component is not valid for the image type, an error is returned.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_set_component_visible (gint32          image_ID,
				  GimpChannelType component,
				  gboolean        visible)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_set_component_visible",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, component,
				    GIMP_PDB_INT32, visible,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_get_filename:
 * @image_ID: The image.
 *
 * Returns the specified image's filename.
 *
 * This procedure returns the specified image's filename -- if it was
 * loaded or has since been saved. Otherwise, returns NULL.
 *
 * Returns: The filename.
 */
gchar *
gimp_image_get_filename (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gchar *filename = NULL;

  return_vals = gimp_run_procedure ("gimp_image_get_filename",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    filename = g_strdup (return_vals[1].data.d_string);

  gimp_destroy_params (return_vals, nreturn_vals);

  return filename;
}

/**
 * gimp_image_set_filename:
 * @image_ID: The image.
 * @filename: The new image filename.
 *
 * Sets the specified image's filename.
 *
 * This procedure sets the specified image's filename.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_set_filename (gint32       image_ID,
			 const gchar *filename)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_set_filename",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_STRING, filename,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_get_name:
 * @image_ID: The image.
 *
 * Returns the specified image's name.
 *
 * This procedure returns the specified image's name.
 *
 * Returns: The name.
 */
gchar *
gimp_image_get_name (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gchar *name = NULL;

  return_vals = gimp_run_procedure ("gimp_image_get_name",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    name = g_strdup (return_vals[1].data.d_string);

  gimp_destroy_params (return_vals, nreturn_vals);

  return name;
}

/**
 * gimp_image_get_resolution:
 * @image_ID: The image.
 * @xresolution: The resolutionin the x-axis, in dots per inch.
 * @yresolution: The resolutionin the y-axis, in dots per inch.
 *
 * Returns the specified image's resolution.
 *
 * This procedure returns the specified image's resolution in dots per
 * inch. This value is independent of any of the layers in this image.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_get_resolution (gint32   image_ID,
			   gdouble *xresolution,
			   gdouble *yresolution)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_get_resolution",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  *xresolution = 0.0;
  *yresolution = 0.0;

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  if (success)
    {
      *xresolution = return_vals[1].data.d_float;
      *yresolution = return_vals[2].data.d_float;
    }

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_set_resolution:
 * @image_ID: The image.
 * @xresolution: The new image resolution in the x-axis, in dots per inch.
 * @yresolution: The new image resolution in the y-axis, in dots per inch.
 *
 * Sets the specified image's resolution.
 *
 * This procedure sets the specified image's resolution in dots per
 * inch. This value is independent of any of the layers in this image.
 * No scaling or resizing is performed.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_set_resolution (gint32  image_ID,
			   gdouble xresolution,
			   gdouble yresolution)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_set_resolution",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_FLOAT, xresolution,
				    GIMP_PDB_FLOAT, yresolution,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_get_unit:
 * @image_ID: The image.
 *
 * Returns the specified image's unit.
 *
 * This procedure returns the specified image's unit. This value is
 * independent of any of the layers in this image. See the gimp_unit_*
 * procedure definitions for the valid range of unit IDs and a
 * description of the unit system.
 *
 * Returns: The unit.
 */
GimpUnit
gimp_image_get_unit (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  GimpUnit unit = 0;

  return_vals = gimp_run_procedure ("gimp_image_get_unit",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    unit = return_vals[1].data.d_unit;

  gimp_destroy_params (return_vals, nreturn_vals);

  return unit;
}

/**
 * gimp_image_set_unit:
 * @image_ID: The image.
 * @unit: The new image unit.
 *
 * Sets the specified image's unit.
 *
 * This procedure sets the specified image's unit. No scaling or
 * resizing is performed. This value is independent of any of the
 * layers in this image. See the gimp_unit_* procedure definitions for
 * the valid range of unit IDs and a description of the unit system.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_set_unit (gint32   image_ID,
		     GimpUnit unit)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_set_unit",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, unit,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_get_tattoo_state:
 * @image_ID: The image.
 *
 * Returns the tattoo state associated with the image.
 *
 * This procedure returns the tattoo state of the image. Use only by
 * save/load plugins that wish to preserve an images tattoo state.
 * Using this function at other times will produce unexpected results.
 *
 * Returns: The tattoo_state.
 */
gint
gimp_image_get_tattoo_state (gint32 image_ID)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint tattoo_state = 0;

  return_vals = gimp_run_procedure ("gimp_image_get_tattoo_state",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    tattoo_state = return_vals[1].data.d_int32;

  gimp_destroy_params (return_vals, nreturn_vals);

  return tattoo_state;
}

/**
 * gimp_image_set_tattoo_state:
 * @image_ID: The image.
 * @tattoo_state: The new image tattoo_state.
 *
 * Set the tattoo state associated with the image.
 *
 * This procedure sets the tattoo state of the image. Use only by
 * save/load plugins that wish to preserve an images tattoo state.
 * Using this function at other times will produce unexpected results.
 * A full check of uniqueness of states in layers, channels and paths
 * will be performed by this procedure and a execution failure will be
 * returned if this fails. A failure will also be returned if the new
 * tattoo state value is less than the maximum tattoo value from all of
 * the tattoos from the paths, layers and channels. After the image
 * data has been loaded and all the tattoos have been set then this is
 * the last procedure that should be called. If effectively does a
 * status check on the tattoo values that have been set to make sure
 * that all is OK.
 *
 * Returns: TRUE on success.
 */
gboolean
gimp_image_set_tattoo_state (gint32 image_ID,
			     gint   tattoo_state)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gboolean success = TRUE;

  return_vals = gimp_run_procedure ("gimp_image_set_tattoo_state",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, tattoo_state,
				    GIMP_PDB_END);

  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

  gimp_destroy_params (return_vals, nreturn_vals);

  return success;
}

/**
 * gimp_image_get_layer_by_tattoo:
 * @image_ID: The image.
 * @tattoo: The tattoo of the layer to find.
 *
 * Find a layer with a given tattoo in an image.
 *
 * This procedure returns the layer with the given tattoo in the
 * specified image.
 *
 * Returns: The layer with the specified tattoo.
 */
gint32
gimp_image_get_layer_by_tattoo (gint32 image_ID,
				gint   tattoo)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint32 layer_ID = -1;

  return_vals = gimp_run_procedure ("gimp_image_get_layer_by_tattoo",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, tattoo,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    layer_ID = return_vals[1].data.d_layer;

  gimp_destroy_params (return_vals, nreturn_vals);

  return layer_ID;
}

/**
 * gimp_image_get_channel_by_tattoo:
 * @image_ID: The image.
 * @tattoo: The tattoo of the channel to find.
 *
 * Find a channel with a given tattoo in an image.
 *
 * This procedure returns the channel with the given tattoo in the
 * specified image.
 *
 * Returns: The channel with the specified tattoo.
 */
gint32
gimp_image_get_channel_by_tattoo (gint32 image_ID,
				  gint   tattoo)
{
  GimpParam *return_vals;
  gint nreturn_vals;
  gint32 channel_ID = -1;

  return_vals = gimp_run_procedure ("gimp_image_get_channel_by_tattoo",
				    &nreturn_vals,
				    GIMP_PDB_IMAGE, image_ID,
				    GIMP_PDB_INT32, tattoo,
				    GIMP_PDB_END);

  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
    channel_ID = return_vals[1].data.d_channel;

  gimp_destroy_params (return_vals, nreturn_vals);

  return channel_ID;
}
