/* 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 3 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, see
 * <https://www.gnu.org/licenses/>.
 */

/* NOTE: This file is auto-generated by pdbgen.pl */

#include "config.h"

#include "stamp-pdbgen.h"

#include "gimp.h"


/**
 * SECTION: gimpimage
 * @title: gimpimage
 * @short_description: Operations on complete images.
 *
 * Operations on complete images: creation, resizing/rescaling, and
 * operations involving multiple layers.
 **/


/**
 * gimp_image_id_is_valid:
 * @image_id: The image ID to check.
 *
 * Returns TRUE if the image ID is valid.
 *
 * This procedure checks if the given image ID is valid and refers to
 * an existing image.
 *
 * Returns: Whether the image ID is valid.
 *
 * Since: 3.0
 **/
gboolean
gimp_image_id_is_valid (gint image_id)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean valid = FALSE;

  args = gimp_value_array_new_from_types (NULL,
                                          G_TYPE_INT, image_id,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-id-is-valid",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    valid = GIMP_VALUES_GET_BOOLEAN (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return valid;
}

/**
 * gimp_get_images:
 *
 * Returns the list of images currently open.
 *
 * This procedure returns the list of images currently open in GIMP.
 *
 * Returns: (element-type GimpImage) (array zero-terminated=1) (transfer container):
 *          The list of images currently open.
 *          The returned value must be freed with g_free().
 **/
GimpImage **
gimp_get_images (void)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpImage **images = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-get-images",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    images = g_value_dup_boxed (gimp_value_array_index (return_vals, 1));

  gimp_value_array_unref (return_vals);

  return images;
}

/**
 * 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_insert_layer() command.
 *
 * If your image's type if INDEXED, a palette must also be set with
 * [method@Gimp.Image.set_palette]. An indexed image without a palette
 * will output unexpected colors.
 *
 * Returns: (transfer none): The newly created image.
 **/
GimpImage *
gimp_image_new (gint              width,
                gint              height,
                GimpImageBaseType type)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpImage *image = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          G_TYPE_INT, width,
                                          G_TYPE_INT, height,
                                          GIMP_TYPE_IMAGE_BASE_TYPE, type,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-new",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    image = GIMP_VALUES_GET_IMAGE (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return image;
}

/**
 * gimp_image_new_with_precision:
 * @width: The width of the image.
 * @height: The height of the image.
 * @type: The type of image.
 * @precision: The precision.
 *
 * Creates a new image with the specified width, height, type and
 * precision.
 *
 * Creates a new image, undisplayed with the specified extents, type
 * and precision. Indexed images can only be created at
 * GIMP_PRECISION_U8_NON_LINEAR precision. See gimp_image_new() for
 * further details.
 *
 * Returns: (transfer none): The newly created image.
 *
 * Since: 2.10
 **/
GimpImage *
gimp_image_new_with_precision (gint              width,
                               gint              height,
                               GimpImageBaseType type,
                               GimpPrecision     precision)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpImage *image = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          G_TYPE_INT, width,
                                          G_TYPE_INT, height,
                                          GIMP_TYPE_IMAGE_BASE_TYPE, type,
                                          GIMP_TYPE_PRECISION, precision,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-new-with-precision",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    image = GIMP_VALUES_GET_IMAGE (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return image;
}

/**
 * gimp_image_duplicate:
 * @image: The image.
 *
 * Duplicate the specified image
 *
 * This procedure duplicates the specified image, copying all layers,
 * channels, and image information.
 *
 * Returns: (transfer none): The new, duplicated image.
 **/
GimpImage *
gimp_image_duplicate (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpImage *new_image = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-duplicate",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    new_image = GIMP_VALUES_GET_IMAGE (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return new_image;
}

/**
 * gimp_image_delete:
 * @image: 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 (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-delete",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_get_base_type:
 * @image: 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_get_base_type (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpImageBaseType base_type = 0;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-base-type",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    base_type = GIMP_VALUES_GET_ENUM (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return base_type;
}

/**
 * gimp_image_get_precision:
 * @image: The image.
 *
 * Get the precision of the image.
 *
 * This procedure returns the image's precision.
 *
 * Returns: The image's precision.
 *
 * Since: 2.10
 **/
GimpPrecision
gimp_image_get_precision (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpPrecision precision = 0;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-precision",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    precision = GIMP_VALUES_GET_ENUM (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return precision;
}

/**
 * gimp_image_get_default_new_layer_mode:
 * @image: The image.
 *
 * Get the default mode for newly created layers of this image.
 *
 * Returns the default mode for newly created layers of this image.
 *
 * Returns: The layer mode.
 *
 * Since: 2.10
 **/
GimpLayerMode
gimp_image_get_default_new_layer_mode (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpLayerMode mode = 0;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-default-new-layer-mode",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    mode = GIMP_VALUES_GET_ENUM (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return mode;
}

/**
 * gimp_image_get_width:
 * @image: 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_get_width (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gint width = 0;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-width",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    width = GIMP_VALUES_GET_INT (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return width;
}

/**
 * gimp_image_get_height:
 * @image: 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_get_height (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gint height = 0;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-height",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    height = GIMP_VALUES_GET_INT (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return height;
}

/**
 * gimp_image_get_layers:
 * @image: The image.
 *
 * Returns the list of root layers contained in the specified image.
 *
 * This procedure returns the list of root layers contained in the
 * specified image. The order of layers is from topmost to bottommost.
 * Note that this is not the full list of layers, but only the root
 * layers, i.e. layers with no parents themselves. If you need all
 * layers, it is up to you to verify that any of these layers is a
 * group layer with gimp_item_is_group() and to obtain its children
 * with gimp_item_get_children() (possibly recursively checking if
 * these have children too).
 *
 * Returns: (element-type GimpLayer) (array zero-terminated=1) (transfer container):
 *          The list of layers contained in the image.
 *          The returned value must be freed with g_free().
 **/
GimpLayer **
gimp_image_get_layers (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpLayer **layers = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-layers",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    layers = g_value_dup_boxed (gimp_value_array_index (return_vals, 1));

  gimp_value_array_unref (return_vals);

  return layers;
}

/**
 * gimp_image_get_channels:
 * @image: 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. Note that
 * \"channels\" are custom channels and do not include the image's
 * color components.
 *
 * Returns: (element-type GimpChannel) (array zero-terminated=1) (transfer container):
 *          The list of channels contained in the image.
 *          The returned value must be freed with g_free().
 **/
GimpChannel **
gimp_image_get_channels (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpChannel **channels = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-channels",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    channels = g_value_dup_boxed (gimp_value_array_index (return_vals, 1));

  gimp_value_array_unref (return_vals);

  return channels;
}

/**
 * gimp_image_get_paths:
 * @image: The image.
 *
 * Returns the list of paths contained in the specified image.
 *
 * This procedure returns the list of paths contained in the specified
 * image.
 *
 * Returns: (element-type GimpPath) (array zero-terminated=1) (transfer container):
 *          The list of paths contained in the image.
 *          The returned value must be freed with g_free().
 *
 * Since: 2.4
 **/
GimpPath **
gimp_image_get_paths (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpPath **paths = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-paths",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    paths = g_value_dup_boxed (gimp_value_array_index (return_vals, 1));

  gimp_value_array_unref (return_vals);

  return paths;
}

/**
 * gimp_image_unset_active_channel:
 * @image: 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 (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-unset-active-channel",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_get_floating_sel:
 * @image: 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: (transfer none): The image's floating selection.
 **/
GimpLayer *
gimp_image_get_floating_sel (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpLayer *floating_sel = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-floating-sel",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    floating_sel = GIMP_VALUES_GET_LAYER (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return floating_sel;
}

/**
 * gimp_image_floating_sel_attached_to:
 * @image: 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: (transfer none):
 *          The drawable the floating selection is attached to.
 **/
GimpDrawable *
gimp_image_floating_sel_attached_to (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpDrawable *drawable = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-floating-sel-attached-to",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    drawable = GIMP_VALUES_GET_DRAWABLE (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return drawable;
}

/**
 * gimp_image_pick_color:
 * @image: The image.
 * @drawables: (element-type GimpDrawable) (array zero-terminated=1): The drawables 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 drawables.
 * @sample_average: Average the color of all the pixels in a specified radius.
 * @average_radius: The radius of pixels to average.
 * @color: (out) (transfer full): The return color.
 *
 * Determine the color at the given 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 drawables, then an error is returned. All drawables must
 * belong to the image and be of the same type.
 * If only one drawable is given and it 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. With several drawables specified, the
 * composite image with only these drawables is used.
 * If the sample_merged parameter is TRUE, the data of the composite
 * image will be used instead of that for the specified drawables. This
 * is equivalent to sampling for colors after merging all visible
 * layers. In the case of a merged sampling, the supplied drawables are
 * ignored.
 *
 * Returns: TRUE on success.
 **/
gboolean
gimp_image_pick_color (GimpImage           *image,
                       const GimpDrawable **drawables,
                       gdouble              x,
                       gdouble              y,
                       gboolean             sample_merged,
                       gboolean             sample_average,
                       gdouble              average_radius,
                       GeglColor          **color)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_CORE_OBJECT_ARRAY, drawables,
                                          G_TYPE_DOUBLE, x,
                                          G_TYPE_DOUBLE, y,
                                          G_TYPE_BOOLEAN, sample_merged,
                                          G_TYPE_BOOLEAN, sample_average,
                                          G_TYPE_DOUBLE, average_radius,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-pick-color",
                                               args);
  gimp_value_array_unref (args);

  *color = NULL;

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  if (success)
    *color = g_value_dup_object (gimp_value_array_index (return_vals, 1));

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_pick_correlate_layer:
 * @image: 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: (transfer none): The layer found at the specified coordinates.
 **/
GimpLayer *
gimp_image_pick_correlate_layer (GimpImage *image,
                                 gint       x,
                                 gint       y)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpLayer *layer = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_INT, x,
                                          G_TYPE_INT, y,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-pick-correlate-layer",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    layer = GIMP_VALUES_GET_LAYER (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return layer;
}

/**
 * gimp_image_insert_layer:
 * @image: The image.
 * @layer: The layer.
 * @parent: (nullable): The parent layer.
 * @position: The layer position.
 *
 * Add the specified layer to the image.
 *
 * This procedure adds the specified layer to the image at the given
 * position. If the specified parent is a valid layer group (See
 * gimp_item_is_group() and gimp_layer_group_new()) then the layer is
 * added inside the group. If the parent is 0, the layer is added
 * inside the main stack, outside of any group. The position argument
 * specifies the location of the layer inside the stack (or the group,
 * if a valid parent was supplied), starting from the top (0) and
 * increasing. If the position is specified as -1 and the parent is
 * specified as 0, then the layer is inserted above the active layer,
 * or inside the group if the active layer is a layer group. The layer
 * type must be compatible with the image base type.
 *
 * Returns: TRUE on success.
 **/
gboolean
gimp_image_insert_layer (GimpImage *image,
                         GimpLayer *layer,
                         GimpLayer *parent,
                         gint       position)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_LAYER, layer,
                                          GIMP_TYPE_LAYER, parent,
                                          G_TYPE_INT, position,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-insert-layer",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_remove_layer:
 * @image: The image.
 * @layer: 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 (GimpImage *image,
                         GimpLayer *layer)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_LAYER, layer,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-remove-layer",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_freeze_layers:
 * @image: The image.
 *
 * Freeze the image's layer list.
 *
 * This procedure freezes the layer list of the image, suppressing any
 * updates to the Layers dialog in response to changes to the image's
 * layers. This can significantly improve performance while applying
 * changes affecting the layer list.
 *
 * Each call to gimp_image_freeze_layers() should be matched by a
 * corresponding call to gimp_image_thaw_layers(), undoing its effects.
 *
 * Returns: TRUE on success.
 *
 * Since: 2.10.2
 **/
gboolean
gimp_image_freeze_layers (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-freeze-layers",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_thaw_layers:
 * @image: The image.
 *
 * Thaw the image's layer list.
 *
 * This procedure thaws the layer list of the image, re-enabling
 * updates to the Layers dialog.
 *
 * This procedure should match a corresponding call to
 * gimp_image_freeze_layers().
 *
 * Returns: TRUE on success.
 *
 * Since: 2.10.2
 **/
gboolean
gimp_image_thaw_layers (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-thaw-layers",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_insert_channel:
 * @image: The image.
 * @channel: The channel.
 * @parent: (nullable): The parent channel.
 * @position: The channel position.
 *
 * Add the specified channel to the image.
 *
 * This procedure adds the specified channel to the image at the given
 * position. Since channel groups are not currently supported, the
 * parent argument must always be 0. The position argument specifies
 * the location of the channel inside the stack, starting from the top
 * (0) and increasing. If the position is specified as -1, then the
 * channel is inserted above the active channel.
 *
 * Returns: TRUE on success.
 **/
gboolean
gimp_image_insert_channel (GimpImage   *image,
                           GimpChannel *channel,
                           GimpChannel *parent,
                           gint         position)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_CHANNEL, channel,
                                          GIMP_TYPE_CHANNEL, parent,
                                          G_TYPE_INT, position,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-insert-channel",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_remove_channel:
 * @image: The image.
 * @channel: 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 (GimpImage   *image,
                           GimpChannel *channel)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_CHANNEL, channel,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-remove-channel",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_freeze_channels:
 * @image: The image.
 *
 * Freeze the image's channel list.
 *
 * This procedure freezes the channel list of the image, suppressing
 * any updates to the Channels dialog in response to changes to the
 * image's channels. This can significantly improve performance while
 * applying changes affecting the channel list.
 *
 * Each call to gimp_image_freeze_channels() should be matched by a
 * corresponding call to gimp_image_thaw_channels(), undoing its
 * effects.
 *
 * Returns: TRUE on success.
 *
 * Since: 2.10.2
 **/
gboolean
gimp_image_freeze_channels (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-freeze-channels",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_thaw_channels:
 * @image: The image.
 *
 * Thaw the image's channel list.
 *
 * This procedure thaws the channel list of the image, re-enabling
 * updates to the Channels dialog.
 *
 * This procedure should match a corresponding call to
 * gimp_image_freeze_channels().
 *
 * Returns: TRUE on success.
 *
 * Since: 2.10.2
 **/
gboolean
gimp_image_thaw_channels (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-thaw-channels",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_insert_path:
 * @image: The image.
 * @path: The path.
 * @parent: (nullable): The parent path.
 * @position: The path position.
 *
 * Add the specified path to the image.
 *
 * This procedure adds the specified path to the image at the given
 * position. Since path groups are not currently supported, the parent
 * argument must always be 0. The position argument specifies the
 * location of the path inside the stack, starting from the top (0) and
 * increasing. If the position is specified as -1, then the path is
 * inserted above the active path.
 *
 * Returns: TRUE on success.
 **/
gboolean
gimp_image_insert_path (GimpImage *image,
                        GimpPath  *path,
                        GimpPath  *parent,
                        gint       position)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_PATH, path,
                                          GIMP_TYPE_PATH, parent,
                                          G_TYPE_INT, position,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-insert-path",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_remove_path:
 * @image: The image.
 * @path: The path object.
 *
 * Remove the specified path from the image.
 *
 * This procedure removes the specified path from the image. If the
 * path doesn't exist, an error is returned.
 *
 * Returns: TRUE on success.
 *
 * Since: 2.4
 **/
gboolean
gimp_image_remove_path (GimpImage *image,
                        GimpPath  *path)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_PATH, path,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-remove-path",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_import_paths_from_file:
 * @image: The image.
 * @file: The SVG file to import.
 * @merge: Merge paths into a single path object.
 * @scale: Scale the SVG to image dimensions.
 * @paths: (out) (element-type GimpPath) (array zero-terminated=1) (transfer container): The list of newly created paths.
 *
 * Import paths from an SVG file.
 *
 * This procedure imports paths from an SVG file. SVG elements other
 * than paths and basic shapes are ignored.
 *
 * Returns: TRUE on success.
 *
 * Since: 2.4
 **/
gboolean
gimp_image_import_paths_from_file (GimpImage   *image,
                                   GFile       *file,
                                   gboolean     merge,
                                   gboolean     scale,
                                   GimpPath  ***paths)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_FILE, file,
                                          G_TYPE_BOOLEAN, merge,
                                          G_TYPE_BOOLEAN, scale,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-import-paths-from-file",
                                               args);
  gimp_value_array_unref (args);

  *paths = NULL;

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  if (success)
    *paths = g_value_dup_boxed (gimp_value_array_index (return_vals, 1));

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_import_paths_from_string:
 * @image: The image.
 * @string: A string that must be a complete and valid SVG document.
 * @length: Number of bytes in string or -1 if the string is NULL terminated.
 * @merge: Merge paths into a single path object.
 * @scale: Scale the SVG to image dimensions.
 * @paths: (out) (element-type GimpPath) (array zero-terminated=1) (transfer container): The list of newly created paths.
 *
 * Import paths from an SVG string.
 *
 * This procedure works like [method@Gimp.Image.import_paths_from_file]
 * but takes a string rather than reading the SVG from a file. This
 * allows you to write scripts that generate SVG and feed it to GIMP.
 *
 * Returns: TRUE on success.
 *
 * Since: 2.4
 **/
gboolean
gimp_image_import_paths_from_string (GimpImage     *image,
                                     const gchar   *string,
                                     gint           length,
                                     gboolean       merge,
                                     gboolean       scale,
                                     GimpPath    ***paths)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_STRING, string,
                                          G_TYPE_INT, length,
                                          G_TYPE_BOOLEAN, merge,
                                          G_TYPE_BOOLEAN, scale,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-import-paths-from-string",
                                               args);
  gimp_value_array_unref (args);

  *paths = NULL;

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  if (success)
    *paths = g_value_dup_boxed (gimp_value_array_index (return_vals, 1));

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_export_path_to_file:
 * @image: The image.
 * @file: The SVG file to create.
 * @path: (nullable): The path object to export, or %NULL for all in the image.
 *
 * save a path as an SVG file.
 *
 * This procedure creates an SVG file to save a Path object, that is, a
 * path. The resulting file can be edited using a vector graphics
 * application, or later reloaded into GIMP. Pass %NULL as the 'path'
 * argument to export all paths in the image.
 *
 * Returns: TRUE on success.
 *
 * Since: 2.6
 **/
gboolean
gimp_image_export_path_to_file (GimpImage *image,
                                GFile     *file,
                                GimpPath  *path)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_FILE, file,
                                          GIMP_TYPE_PATH, path,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-export-path-to-file",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_export_path_to_string:
 * @image: The image.
 * @path: (nullable): The path object to export, or %NULL for all in the image.
 *
 * Save a path as an SVG string.
 *
 * This procedure works like [method@Gimp.Image.export_path_to_file]
 * but creates a string rather than a file. The string is
 * NULL-terminated and holds a complete XML document. Pass %NULL as the
 * 'path' argument to export all paths in the image.
 *
 * Returns: (transfer full):
 *          A string whose contents are a complete SVG document.
 *          The returned value must be freed with g_free().
 *
 * Since: 2.6
 **/
gchar *
gimp_image_export_path_to_string (GimpImage *image,
                                  GimpPath  *path)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gchar *string = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_PATH, path,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-export-path-to-string",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    string = GIMP_VALUES_DUP_STRING (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return string;
}

/**
 * gimp_image_freeze_paths:
 * @image: The image.
 *
 * Freeze the image's path list.
 *
 * This procedure freezes the path list of the image, suppressing any
 * updates to the Paths dialog in response to changes to the image's
 * path. This can significantly improve performance while applying
 * changes affecting the path list.
 *
 * Each call to gimp_image_freeze_paths() should be matched by a
 * corresponding call to gimp_image_thaw_paths (), undoing its effects.
 *
 * Returns: TRUE on success.
 *
 * Since: 2.10.2
 **/
gboolean
gimp_image_freeze_paths (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-freeze-paths",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_thaw_paths:
 * @image: The image.
 *
 * Thaw the image's path list.
 *
 * This procedure thaws the path list of the image, re-enabling updates
 * to the Paths dialog.
 *
 * This procedure should match a corresponding call to
 * gimp_image_freeze_paths().
 *
 * Returns: TRUE on success.
 *
 * Since: 2.10.2
 **/
gboolean
gimp_image_thaw_paths (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-thaw-paths",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_get_item_position:
 * @image: The image.
 * @item: The item.
 *
 * Returns the position of the item in its level of its item tree.
 *
 * This procedure determines the position of the specified item in its
 * level in its item tree in the image. If the item doesn't exist in
 * the image, or the item is not part of an item tree, an error is
 * returned.
 *
 * Returns: The position of the item in its level in the item tree.
 *
 * Since: 2.8
 **/
gint
gimp_image_get_item_position (GimpImage *image,
                              GimpItem  *item)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gint position = 0;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_ITEM, item,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-item-position",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    position = GIMP_VALUES_GET_INT (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return position;
}

/**
 * gimp_image_raise_item:
 * @image: The image.
 * @item: The item to raise.
 *
 * Raise the specified item in its level in its item tree
 *
 * This procedure raises the specified item one step in the item tree.
 * The procedure call will fail if there is no item above it.
 *
 * Returns: TRUE on success.
 *
 * Since: 2.8
 **/
gboolean
gimp_image_raise_item (GimpImage *image,
                       GimpItem  *item)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_ITEM, item,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-raise-item",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_lower_item:
 * @image: The image.
 * @item: The item to lower.
 *
 * Lower the specified item in its level in its item tree
 *
 * This procedure lowers the specified item one step in the item tree.
 * The procedure call will fail if there is no item below it.
 *
 * Returns: TRUE on success.
 *
 * Since: 2.8
 **/
gboolean
gimp_image_lower_item (GimpImage *image,
                       GimpItem  *item)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_ITEM, item,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-lower-item",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_raise_item_to_top:
 * @image: The image.
 * @item: The item to raise to top.
 *
 * Raise the specified item to the top of its level in its item tree
 *
 * This procedure raises the specified item to top of its level in the
 * item tree. It will not move the item if there is no item above it.
 *
 * Returns: TRUE on success.
 *
 * Since: 2.8
 **/
gboolean
gimp_image_raise_item_to_top (GimpImage *image,
                              GimpItem  *item)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_ITEM, item,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-raise-item-to-top",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_lower_item_to_bottom:
 * @image: The image.
 * @item: The item to lower to bottom.
 *
 * Lower the specified item to the bottom of its level in its item tree
 *
 * This procedure lowers the specified item to bottom of its level in
 * the item tree. It will not move the layer if there is no layer below
 * it.
 *
 * Returns: TRUE on success.
 *
 * Since: 2.8
 **/
gboolean
gimp_image_lower_item_to_bottom (GimpImage *image,
                                 GimpItem  *item)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_ITEM, item,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-lower-item-to-bottom",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_reorder_item:
 * @image: The image.
 * @item: The item to reorder.
 * @parent: (nullable): The new parent item.
 * @position: The new position of the item.
 *
 * Reorder the specified item within its item tree
 *
 * Reorders or moves item within an item tree. Requires parent is %NULL
 * or a GroupLayer, else returns error. When parent is not %NULL and
 * item is in parent, reorders item within parent group. When parent is
 * not %NULL and item is not in parent, moves item into parent group.
 * When parent is %NULL, moves item from current parent to top level.
 *
 * Requires item is in same tree as not %NULL parent, else returns
 * error. Layers, Channels, and Paths are in separate trees.
 *
 * Requires item is not ancestor of parent, else returns error, to
 * preclude cycles.
 *
 * Returns: TRUE on success.
 *
 * Since: 2.8
 **/
gboolean
gimp_image_reorder_item (GimpImage *image,
                         GimpItem  *item,
                         GimpItem  *parent,
                         gint       position)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_ITEM, item,
                                          GIMP_TYPE_ITEM, parent,
                                          G_TYPE_INT, position,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-reorder-item",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_flatten:
 * @image: 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: (transfer none): The resulting layer.
 **/
GimpLayer *
gimp_image_flatten (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpLayer *layer = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-flatten",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    layer = GIMP_VALUES_GET_LAYER (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return layer;
}

/**
 * gimp_image_merge_visible_layers:
 * @image: 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: (transfer none): The resulting layer.
 **/
GimpLayer *
gimp_image_merge_visible_layers (GimpImage     *image,
                                 GimpMergeType  merge_type)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpLayer *layer = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_MERGE_TYPE, merge_type,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-merge-visible-layers",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    layer = GIMP_VALUES_GET_LAYER (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return layer;
}

/**
 * gimp_image_merge_down:
 * @image: The image.
 * @merge_layer: 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: (transfer none): The resulting layer.
 **/
GimpLayer *
gimp_image_merge_down (GimpImage     *image,
                       GimpLayer     *merge_layer,
                       GimpMergeType  merge_type)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpLayer *layer = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_LAYER, merge_layer,
                                          GIMP_TYPE_MERGE_TYPE, merge_type,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-merge-down",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    layer = GIMP_VALUES_GET_LAYER (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return layer;
}

/**
 * gimp_image_get_palette:
 * @image: The image.
 *
 * Returns the image's colormap
 *
 * This procedure returns the image's colormap as a %GimpPalette. If
 * the image is not in Indexed color mode, %NULL is returned.
 *
 * Returns: (transfer none): The image's colormap palette.
 *
 * Since: 3.0
 **/
GimpPalette *
gimp_image_get_palette (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpPalette *palette = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-palette",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    palette = GIMP_VALUES_GET_PALETTE (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return palette;
}

/**
 * gimp_image_set_palette:
 * @image: The image.
 * @new_palette: The palette to copy from.
 *
 * Set the image's colormap to a copy of @palette
 *
 * This procedure changes the image's colormap to an exact copy of
 * @palette and returns the palette of @image.
 * If the image is not in Indexed color mode, nothing happens and %NULL
 * is returned.
 *
 * Returns: (transfer none): The image's colormap palette.
 *
 * Since: 3.0
 **/
GimpPalette *
gimp_image_set_palette (GimpImage   *image,
                        GimpPalette *new_palette)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpPalette *palette = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_PALETTE, new_palette,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-set-palette",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    palette = GIMP_VALUES_GET_PALETTE (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return palette;
}

/**
 * _gimp_image_get_metadata:
 * @image: The image.
 *
 * Returns the image's metadata.
 *
 * Returns exif/iptc/xmp metadata from the image.
 *
 * Returns: (transfer full): The exif/ptc/xmp metadata as a string.
 *          The returned value must be freed with g_free().
 **/
gchar *
_gimp_image_get_metadata (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gchar *metadata_string = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-metadata",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    metadata_string = GIMP_VALUES_DUP_STRING (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return metadata_string;
}

/**
 * _gimp_image_set_metadata:
 * @image: The image.
 * @metadata_string: The exif/ptc/xmp metadata as a string.
 *
 * Set the image's metadata.
 *
 * Sets exif/iptc/xmp metadata on the image.
 *
 * Returns: TRUE on success.
 **/
gboolean
_gimp_image_set_metadata (GimpImage   *image,
                          const gchar *metadata_string)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_STRING, metadata_string,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-set-metadata",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_clean_all:
 * @image: 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. Note that save plug-ins must NOT
 * call this function themselves after saving the image.
 *
 * Returns: TRUE on success.
 **/
gboolean
gimp_image_clean_all (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-clean-all",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_is_dirty:
 * @image: 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. Note that saving the image does not automatically
 * set the dirty count to 0, you need to call gimp_image_clean_all()
 * after calling a save procedure to make the image clean.
 *
 * Returns: TRUE if the image has unsaved changes.
 **/
gboolean
gimp_image_is_dirty (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean dirty = FALSE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-is-dirty",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    dirty = GIMP_VALUES_GET_BOOLEAN (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return dirty;
}

/**
 * _gimp_image_thumbnail:
 * @image: The image.
 * @width: The requested thumbnail width.
 * @height: The requested thumbnail height.
 * @actual_width: (out): The previews width.
 * @actual_height: (out): The previews height.
 * @bpp: (out): The previews bpp.
 * @thumbnail_data: (out) (transfer full): 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 RGB[A] or GRAY[A] format. The bpp return value gives
 * the number of bits per pixel in the image.
 *
 * Returns: TRUE on success.
 **/
gboolean
_gimp_image_thumbnail (GimpImage  *image,
                       gint        width,
                       gint        height,
                       gint       *actual_width,
                       gint       *actual_height,
                       gint       *bpp,
                       GBytes    **thumbnail_data)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_INT, width,
                                          G_TYPE_INT, height,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-thumbnail",
                                               args);
  gimp_value_array_unref (args);

  *actual_width = 0;
  *actual_height = 0;
  *bpp = 0;
  *thumbnail_data = NULL;

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  if (success)
    {
      *actual_width = GIMP_VALUES_GET_INT (return_vals, 1);
      *actual_height = GIMP_VALUES_GET_INT (return_vals, 2);
      *bpp = GIMP_VALUES_GET_INT (return_vals, 3);
      *thumbnail_data = GIMP_VALUES_DUP_BYTES (return_vals, 4);
    }

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_get_selected_layers:
 * @image: The image.
 *
 * Returns the specified image's selected layers.
 *
 * This procedure returns the list of selected layers in the specified
 * image.
 *
 * Returns: (element-type GimpLayer) (array zero-terminated=1) (transfer container):
 *          The list of selected layers in the image.
 *          The returned value must be freed with g_free().
 *
 * Since: 3.0.0
 **/
GimpLayer **
gimp_image_get_selected_layers (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpLayer **layers = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-selected-layers",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    layers = g_value_dup_boxed (gimp_value_array_index (return_vals, 1));

  gimp_value_array_unref (return_vals);

  return layers;
}

/**
 * gimp_image_set_selected_layers:
 * @image: The image.
 * @layers: (element-type GimpLayer) (array zero-terminated=1): The list of layers to select.
 *
 * Sets the specified image's selected layers.
 *
 * The layers are set as the selected layers in the image. Any previous
 * selected layers or channels are unselected. An exception is a
 * previously existing floating selection, in which case this procedure
 * will return an execution error.
 *
 * Returns: TRUE on success.
 *
 * Since: 3.0.0
 **/
gboolean
gimp_image_set_selected_layers (GimpImage        *image,
                                const GimpLayer **layers)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_CORE_OBJECT_ARRAY, layers,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-set-selected-layers",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_get_selected_channels:
 * @image: The image.
 *
 * Returns the specified image's selected channels.
 *
 * This procedure returns the list of selected channels in the
 * specified image.
 *
 * Returns: (element-type GimpChannel) (array zero-terminated=1) (transfer container):
 *          The list of selected channels in the image.
 *          The returned value must be freed with g_free().
 *
 * Since: 3.0.0
 **/
GimpChannel **
gimp_image_get_selected_channels (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpChannel **channels = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-selected-channels",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    channels = g_value_dup_boxed (gimp_value_array_index (return_vals, 1));

  gimp_value_array_unref (return_vals);

  return channels;
}

/**
 * gimp_image_set_selected_channels:
 * @image: The image.
 * @channels: (element-type GimpChannel) (array zero-terminated=1): The list of channels to select.
 *
 * Sets the specified image's selected channels.
 *
 * The channels are set as the selected channels in the image. Any
 * previous selected layers or channels are unselected. An exception is
 * a previously existing floating selection, in which case this
 * procedure will return an execution error.
 *
 * Returns: TRUE on success.
 *
 * Since: 3.0.0
 **/
gboolean
gimp_image_set_selected_channels (GimpImage          *image,
                                  const GimpChannel **channels)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_CORE_OBJECT_ARRAY, channels,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-set-selected-channels",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_get_selected_paths:
 * @image: The image.
 *
 * Returns the specified image's selected paths.
 *
 * This procedure returns the list of selected paths in the specified
 * image.
 *
 * Returns: (element-type GimpPath) (array zero-terminated=1) (transfer container):
 *          The list of selected paths in the image.
 *          The returned value must be freed with g_free().
 *
 * Since: 3.0.0
 **/
GimpPath **
gimp_image_get_selected_paths (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpPath **paths = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-selected-paths",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    paths = g_value_dup_boxed (gimp_value_array_index (return_vals, 1));

  gimp_value_array_unref (return_vals);

  return paths;
}

/**
 * gimp_image_set_selected_paths:
 * @image: The image.
 * @paths: (element-type GimpPath) (array zero-terminated=1): The list of paths to select.
 *
 * Sets the specified image's selected paths.
 *
 * The paths are set as the selected paths in the image.
 *
 * Returns: TRUE on success.
 *
 * Since: 3.0.0
 **/
gboolean
gimp_image_set_selected_paths (GimpImage       *image,
                               const GimpPath **paths)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_CORE_OBJECT_ARRAY, paths,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-set-selected-paths",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_get_selected_drawables:
 * @image: The image.
 *
 * Get the image's selected drawables
 *
 * This procedure returns the list of selected drawable in the
 * specified image. This can be either layers, channels, or a layer
 * mask.
 * The active drawables are the active image channels. If there are
 * none, these are the active image layers. 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: (element-type GimpDrawable) (array zero-terminated=1) (transfer container):
 *          The list of selected drawables in the image.
 *          The returned value must be freed with g_free().
 *
 * Since: 3.0.0
 **/
GimpDrawable **
gimp_image_get_selected_drawables (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpDrawable **drawables = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-selected-drawables",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    drawables = g_value_dup_boxed (gimp_value_array_index (return_vals, 1));

  gimp_value_array_unref (return_vals);

  return drawables;
}

/**
 * gimp_image_get_selection:
 * @image: 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: (transfer none): The selection channel.
 **/
GimpSelection *
gimp_image_get_selection (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpSelection *selection = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-selection",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    selection = GIMP_VALUES_GET_SELECTION (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return selection;
}

/**
 * gimp_image_get_component_active:
 * @image: 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 (GimpImage       *image,
                                 GimpChannelType  component)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean active = FALSE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_CHANNEL_TYPE, component,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-component-active",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    active = GIMP_VALUES_GET_BOOLEAN (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return active;
}

/**
 * gimp_image_set_component_active:
 * @image: 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 (GimpImage       *image,
                                 GimpChannelType  component,
                                 gboolean         active)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_CHANNEL_TYPE, component,
                                          G_TYPE_BOOLEAN, active,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-set-component-active",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_get_component_visible:
 * @image: 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 (GimpImage       *image,
                                  GimpChannelType  component)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean visible = FALSE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_CHANNEL_TYPE, component,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-component-visible",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    visible = GIMP_VALUES_GET_BOOLEAN (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return visible;
}

/**
 * gimp_image_set_component_visible:
 * @image: 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 (GimpImage       *image,
                                  GimpChannelType  component,
                                  gboolean         visible)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_CHANNEL_TYPE, component,
                                          G_TYPE_BOOLEAN, visible,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-set-component-visible",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_get_file:
 * @image: The image.
 *
 * Returns the file for the specified image.
 *
 * This procedure returns the file associated with the specified image.
 * The image has a file only if it was loaded or imported from a file
 * or has since been saved or exported. Otherwise, this function
 * returns %NULL. See also gimp-image-get-imported-file to get the
 * current file if it was imported from a non-GIMP file format and not
 * yet saved, or gimp-image-get-exported-file if the image has been
 * exported to a non-GIMP file format.
 *
 * Returns: (transfer full): The file.
 *
 * Since: 2.8
 **/
GFile *
gimp_image_get_file (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GFile *file = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-file",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    file = GIMP_VALUES_DUP_FILE (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return file;
}

/**
 * gimp_image_set_file:
 * @image: The image.
 * @file: The new image file.
 *
 * Sets the specified XCF image's file.
 *
 * This procedure sets the specified image's file.
 * This is to set the XCF file associated with your image. In
 * particular, do not use this function to set the imported file in
 * file import plug-ins. This is done by the core process.
 *
 * Returns: TRUE on success.
 **/
gboolean
gimp_image_set_file (GimpImage *image,
                     GFile     *file)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_FILE, file,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-set-file",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_get_xcf_file:
 * @image: The image.
 *
 * Returns the XCF file for the specified image.
 *
 * This procedure returns the XCF file associated with the image. If
 * there is no such file, this procedure returns %NULL.
 *
 * Returns: (transfer full): The imported XCF file.
 *
 * Since: 2.8
 **/
GFile *
gimp_image_get_xcf_file (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GFile *file = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-xcf-file",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    file = GIMP_VALUES_DUP_FILE (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return file;
}

/**
 * gimp_image_get_imported_file:
 * @image: The image.
 *
 * Returns the imported file for the specified image.
 *
 * This procedure returns the file associated with the specified image
 * if the image was imported from a non-native Gimp format. If the
 * image was not imported, or has since been saved in the native Gimp
 * format, this procedure returns %NULL.
 *
 * Returns: (transfer full): The imported file.
 *
 * Since: 2.8
 **/
GFile *
gimp_image_get_imported_file (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GFile *file = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-imported-file",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    file = GIMP_VALUES_DUP_FILE (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return file;
}

/**
 * gimp_image_get_exported_file:
 * @image: The image.
 *
 * Returns the exported file for the specified image.
 *
 * This procedure returns the file associated with the specified image
 * if the image was exported a non-native GIMP format. If the image was
 * not exported, this procedure returns %NULL.
 *
 * Returns: (transfer full): The exported file.
 *
 * Since: 2.8
 **/
GFile *
gimp_image_get_exported_file (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GFile *file = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-exported-file",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    file = GIMP_VALUES_DUP_FILE (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return file;
}

/**
 * gimp_image_get_name:
 * @image: The image.
 *
 * Returns the specified image's name.
 *
 * This procedure returns the image's name. If the image has a filename
 * or an URI, then the returned name contains the filename's or URI's
 * base name (the last component of the path). Otherwise it is the
 * translated string \"Untitled\". The returned name is formatted like
 * the image name in the image window title, it may contain '[]',
 * '(imported)' etc. and should only be used to label user interface
 * elements. Never use it to construct filenames.
 *
 * Returns: (transfer full): The name.
 *          The returned value must be freed with g_free().
 **/
gchar *
gimp_image_get_name (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gchar *name = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-name",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    name = GIMP_VALUES_DUP_STRING (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return name;
}

/**
 * gimp_image_get_resolution:
 * @image: The image.
 * @xresolution: (out): The resolution in the x-axis, in dots per inch.
 * @yresolution: (out): The resolution in 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 (GimpImage *image,
                           gdouble   *xresolution,
                           gdouble   *yresolution)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-resolution",
                                               args);
  gimp_value_array_unref (args);

  *xresolution = 0.0;
  *yresolution = 0.0;

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  if (success)
    {
      *xresolution = GIMP_VALUES_GET_DOUBLE (return_vals, 1);
      *yresolution = GIMP_VALUES_GET_DOUBLE (return_vals, 2);
    }

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_set_resolution:
 * @image: 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 (GimpImage *image,
                           gdouble    xresolution,
                           gdouble    yresolution)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_DOUBLE, xresolution,
                                          G_TYPE_DOUBLE, yresolution,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-set-resolution",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_get_unit:
 * @image: 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: (transfer none): The unit.
 **/
GimpUnit *
gimp_image_get_unit (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpUnit *unit = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-unit",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    unit = GIMP_VALUES_GET_UNIT (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return unit;
}

/**
 * gimp_image_set_unit:
 * @image: 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 (GimpImage *image,
                     GimpUnit  *unit)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_UNIT, unit,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-set-unit",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_get_tattoo_state:
 * @image: The image.
 *
 * Returns the tattoo state associated with the image.
 *
 * This procedure returns the tattoo state of the image. Use only by
 * save/load plug-ins that wish to preserve an images tattoo state.
 * Using this function at other times will produce unexpected results.
 *
 * Returns: The tattoo state.
 **/
guint
gimp_image_get_tattoo_state (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  guint tattoo_state = 0;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-tattoo-state",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    tattoo_state = GIMP_VALUES_GET_UINT (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return tattoo_state;
}

/**
 * gimp_image_set_tattoo_state:
 * @image: 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 plug-ins 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 (GimpImage *image,
                             guint      tattoo_state)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_UINT, tattoo_state,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-set-tattoo-state",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_get_layer_by_tattoo:
 * @image: 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: (transfer none): The layer with the specified tattoo.
 **/
GimpLayer *
gimp_image_get_layer_by_tattoo (GimpImage *image,
                                guint      tattoo)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpLayer *layer = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_UINT, tattoo,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-layer-by-tattoo",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    layer = GIMP_VALUES_GET_LAYER (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return layer;
}

/**
 * gimp_image_get_channel_by_tattoo:
 * @image: 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: (transfer none): The channel with the specified tattoo.
 **/
GimpChannel *
gimp_image_get_channel_by_tattoo (GimpImage *image,
                                  guint      tattoo)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpChannel *channel = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_UINT, tattoo,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-channel-by-tattoo",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    channel = GIMP_VALUES_GET_CHANNEL (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return channel;
}

/**
 * gimp_image_get_path_by_tattoo:
 * @image: The image.
 * @tattoo: The tattoo of the path to find.
 *
 * Find a path with a given tattoo in an image.
 *
 * This procedure returns the path with the given tattoo in the
 * specified image.
 *
 * Returns: (transfer none): The path with the specified tattoo.
 *
 * Since: 2.6
 **/
GimpPath *
gimp_image_get_path_by_tattoo (GimpImage *image,
                               guint      tattoo)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpPath *path = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_UINT, tattoo,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-path-by-tattoo",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    path = GIMP_VALUES_GET_PATH (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return path;
}

/**
 * gimp_image_get_layer_by_name:
 * @image: The image.
 * @name: The name of the layer to find.
 *
 * Find a layer with a given name in an image.
 *
 * This procedure returns the layer with the given name in the
 * specified image.
 *
 * Returns: (transfer none): The layer with the specified name.
 *
 * Since: 2.8
 **/
GimpLayer *
gimp_image_get_layer_by_name (GimpImage   *image,
                              const gchar *name)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpLayer *layer = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_STRING, name,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-layer-by-name",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    layer = GIMP_VALUES_GET_LAYER (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return layer;
}

/**
 * gimp_image_get_channel_by_name:
 * @image: The image.
 * @name: The name of the channel to find.
 *
 * Find a channel with a given name in an image.
 *
 * This procedure returns the channel with the given name in the
 * specified image.
 *
 * Returns: (transfer none): The channel with the specified name.
 *
 * Since: 2.8
 **/
GimpChannel *
gimp_image_get_channel_by_name (GimpImage   *image,
                                const gchar *name)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpChannel *channel = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_STRING, name,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-channel-by-name",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    channel = GIMP_VALUES_GET_CHANNEL (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return channel;
}

/**
 * gimp_image_get_path_by_name:
 * @image: The image.
 * @name: The name of the path to find.
 *
 * Find a path with a given name in an image.
 *
 * This procedure returns the path with the given name in the specified
 * image.
 *
 * Returns: (transfer none): The path with the specified name.
 *
 * Since: 2.8
 **/
GimpPath *
gimp_image_get_path_by_name (GimpImage   *image,
                             const gchar *name)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpPath *path = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_STRING, name,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-path-by-name",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    path = GIMP_VALUES_GET_PATH (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return path;
}

/**
 * gimp_image_attach_parasite:
 * @image: The image.
 * @parasite: The parasite to attach to an image.
 *
 * Add a parasite to an image.
 *
 * This procedure attaches a parasite to an image. It has no return
 * values.
 *
 * Returns: TRUE on success.
 *
 * Since: 2.8
 **/
gboolean
gimp_image_attach_parasite (GimpImage          *image,
                            const GimpParasite *parasite)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          GIMP_TYPE_PARASITE, parasite,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-attach-parasite",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_detach_parasite:
 * @image: The image.
 * @name: The name of the parasite to detach from an image.
 *
 * Removes a parasite from an image.
 *
 * This procedure detaches a parasite from an image. It has no return
 * values.
 *
 * Returns: TRUE on success.
 *
 * Since: 2.8
 **/
gboolean
gimp_image_detach_parasite (GimpImage   *image,
                            const gchar *name)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_STRING, name,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-detach-parasite",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_get_parasite:
 * @image: The image.
 * @name: The name of the parasite to find.
 *
 * Look up a parasite in an image
 *
 * Finds and returns the parasite that was previously attached to an
 * image.
 *
 * Returns: (transfer full): The found parasite.
 *
 * Since: 2.8
 **/
GimpParasite *
gimp_image_get_parasite (GimpImage   *image,
                         const gchar *name)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  GimpParasite *parasite = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_STRING, name,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-parasite",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    parasite = GIMP_VALUES_DUP_PARASITE (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return parasite;
}

/**
 * gimp_image_get_parasite_list:
 * @image: The image.
 *
 * List all parasites.
 *
 * Returns a list of the names of all currently attached parasites.
 * These names can later be used to get the actual #GimpParasite with
 * gimp_image_get_parasite() when needed.
 *
 * Returns: (array zero-terminated=1) (transfer full):
 *          The names of currently attached parasites.
 *          The returned value must be freed with g_strfreev().
 *
 * Since: 2.8
 **/
gchar **
gimp_image_get_parasite_list (GimpImage *image)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gchar **parasites = NULL;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-get-parasite-list",
                                               args);
  gimp_value_array_unref (args);

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    parasites = GIMP_VALUES_DUP_STRV (return_vals, 1);

  gimp_value_array_unref (return_vals);

  return parasites;
}

/**
 * gimp_image_policy_rotate:
 * @image: The image.
 * @interactive: Querying the user through a dialog is a possibility.
 *
 * Execute the \"Orientation\" metadata policy.
 *
 * Process the image according to the rotation policy as set in
 * Preferences. If GIMP is running as a GUI and interactive is TRUE, a
 * dialog may be presented to the user depending on the set policy.
 * Otherwise, if the policy does not mandate the action to perform, the
 * image will be rotated following the Orientation metadata.
 * If you wish absolutely to rotate a loaded image following the
 * Orientation metadata, do not use this function and process the
 * metadata yourself. Indeed even with `interactive` to FALSE, user
 * settings may leave the image unrotated.
 * Finally it is unnecessary to call this function in a format load
 * procedure because this is called automatically by the core code when
 * loading any image. You should only call this function explicitly
 * when loading an image through a PDB call.
 *
 * Returns: TRUE on success.
 *
 * Since: 3.0
 **/
gboolean
gimp_image_policy_rotate (GimpImage *image,
                          gboolean   interactive)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_BOOLEAN, interactive,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-policy-rotate",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}

/**
 * gimp_image_policy_color_profile:
 * @image: The image.
 * @interactive: Querying the user through a dialog is a possibility.
 *
 * Execute the color profile conversion policy.
 *
 * Process the image according to the color profile policy as set in
 * Preferences.
 * If GIMP is running as a GUI and interactive is TRUE, a dialog may be
 * presented to the user depending on the policy. Otherwise, if the
 * policy does not mandate the conversion to perform, the conversion to
 * the preferred RGB or grayscale profile will happen, defaulting to
 * built-in profiles if no preferred profiles were set in
 * `Preferences`.
 * This function should be used only if you want to follow user
 * settings. If you intend to convert to a specific profile, call
 * preferably gimp_image_convert_color_profile(). And if you wish to
 * leave whatever profile an image has, do not call any of these
 * functions.
 * Finally it is unnecessary to call this function in a format load
 * procedure because this is called automatically by the core code when
 * loading any image. You should only call this function explicitly
 * when loading an image through a PDB call.
 *
 * Returns: TRUE on success.
 *
 * Since: 3.0
 **/
gboolean
gimp_image_policy_color_profile (GimpImage *image,
                                 gboolean   interactive)
{
  GimpValueArray *args;
  GimpValueArray *return_vals;
  gboolean success = TRUE;

  args = gimp_value_array_new_from_types (NULL,
                                          GIMP_TYPE_IMAGE, image,
                                          G_TYPE_BOOLEAN, interactive,
                                          G_TYPE_NONE);

  return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
                                               "gimp-image-policy-color-profile",
                                               args);
  gimp_value_array_unref (args);

  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;

  gimp_value_array_unref (return_vals);

  return success;
}
