/*
 * Copyright © 2000 SuSE, Inc.
 * Copyright © 2007 Red Hat, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of SuSE not be used in advertising or
 * publicity pertaining to distribution of the software without specific,
 * written prior permission.  SuSE makes no representations about the
 * suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 *
 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "pixman-private.h"

static const pixman_color_t transparent_black = { 0, 0, 0, 0 };

static void
gradient_property_changed (pixman_image_t *image)
{
    gradient_t *gradient = &image->gradient;
    int n = gradient->n_stops;
    pixman_gradient_stop_t *stops = gradient->stops;
    pixman_gradient_stop_t *begin = &(gradient->stops[-1]);
    pixman_gradient_stop_t *end = &(gradient->stops[n]);

    switch (gradient->common.repeat)
    {
    default:
    case PIXMAN_REPEAT_NONE:
	begin->x = INT32_MIN;
	begin->color = transparent_black;
	end->x = INT32_MAX;
	end->color = transparent_black;
	break;

    case PIXMAN_REPEAT_NORMAL:
	begin->x = stops[n - 1].x - pixman_fixed_1;
	begin->color = stops[n - 1].color;
	end->x = stops[0].x + pixman_fixed_1;
	end->color = stops[0].color;
	break;

    case PIXMAN_REPEAT_REFLECT:
	begin->x = - stops[0].x;
	begin->color = stops[0].color;
	end->x = pixman_int_to_fixed (2) - stops[n - 1].x;
	end->color = stops[n - 1].color;
	break;

    case PIXMAN_REPEAT_PAD:
	begin->x = INT32_MIN;
	begin->color = stops[0].color;
	end->x = INT32_MAX;
	end->color = stops[n - 1].color;
	break;
    }
}

pixman_bool_t
_pixman_init_gradient (gradient_t *                  gradient,
                       const pixman_gradient_stop_t *stops,
                       int                           n_stops)
{
    return_val_if_fail (n_stops > 0, FALSE);

    /* We allocate two extra stops, one before the beginning of the stop list,
     * and one after the end. These stops are initialized to whatever color
     * would be used for positions outside the range of the stop list.
     *
     * This saves a bit of computation in the gradient walker.
     *
     * The pointer we store in the gradient_t struct still points to the
     * first user-supplied struct, so when freeing, we will have to
     * subtract one.
     */
    gradient->stops =
	pixman_malloc_ab (n_stops + 2, sizeof (pixman_gradient_stop_t));
    if (!gradient->stops)
	return FALSE;

    gradient->stops += 1;
    memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t));
    gradient->n_stops = n_stops;

    gradient->common.property_changed = gradient_property_changed;

    return TRUE;
}

void
_pixman_image_init (pixman_image_t *image)
{
    image_common_t *common = &image->common;

    pixman_region32_init (&common->clip_region);

    common->alpha_count = 0;
    common->have_clip_region = FALSE;
    common->clip_sources = FALSE;
    common->transform = NULL;
    common->repeat = PIXMAN_REPEAT_NONE;
    common->filter = PIXMAN_FILTER_NEAREST;
    common->filter_params = NULL;
    common->n_filter_params = 0;
    common->alpha_map = NULL;
    common->component_alpha = FALSE;
    common->ref_count = 1;
    common->property_changed = NULL;
    common->client_clip = FALSE;
    common->destroy_func = NULL;
    common->destroy_data = NULL;
    common->dirty = TRUE;
}

pixman_bool_t
_pixman_image_fini (pixman_image_t *image)
{
    image_common_t *common = (image_common_t *)image;

    common->ref_count--;

    if (common->ref_count == 0)
    {
	if (image->common.destroy_func)
	    image->common.destroy_func (image, image->common.destroy_data);

	pixman_region32_fini (&common->clip_region);

	free (common->transform);
	free (common->filter_params);

	if (common->alpha_map)
	    pixman_image_unref ((pixman_image_t *)common->alpha_map);

	if (image->type == LINEAR ||
	    image->type == RADIAL ||
	    image->type == CONICAL)
	{
	    if (image->gradient.stops)
	    {
		/* See _pixman_init_gradient() for an explanation of the - 1 */
		free (image->gradient.stops - 1);
	    }

	    /* This will trigger if someone adds a property_changed
	     * method to the linear/radial/conical gradient overwriting
	     * the general one.
	     */
	    assert (
		image->common.property_changed == gradient_property_changed);
	}

	if (image->type == BITS && image->bits.free_me)
	    free (image->bits.free_me);

	return TRUE;
    }

    return FALSE;
}

pixman_image_t *
_pixman_image_allocate (void)
{
    pixman_image_t *image = malloc (sizeof (pixman_image_t));

    if (image)
	_pixman_image_init (image);

    return image;
}

static void
image_property_changed (pixman_image_t *image)
{
    image->common.dirty = TRUE;
}

/* Ref Counting */
PIXMAN_EXPORT pixman_image_t *
pixman_image_ref (pixman_image_t *image)
{
    image->common.ref_count++;

    return image;
}

/* returns TRUE when the image is freed */
PIXMAN_EXPORT pixman_bool_t
pixman_image_unref (pixman_image_t *image)
{
    if (_pixman_image_fini (image))
    {
	free (image);
	return TRUE;
    }

    return FALSE;
}

PIXMAN_EXPORT void
pixman_image_set_destroy_function (pixman_image_t *            image,
                                   pixman_image_destroy_func_t func,
                                   void *                      data)
{
    image->common.destroy_func = func;
    image->common.destroy_data = data;
}

PIXMAN_EXPORT void *
pixman_image_get_destroy_data (pixman_image_t *image)
{
  return image->common.destroy_data;
}

void
_pixman_image_reset_clip_region (pixman_image_t *image)
{
    image->common.have_clip_region = FALSE;
}

/* Executive Summary: This function is a no-op that only exists
 * for historical reasons.
 *
 * There used to be a bug in the X server where it would rely on
 * out-of-bounds accesses when it was asked to composite with a
 * window as the source. It would create a pixman image pointing
 * to some bogus position in memory, but then set a clip region
 * to the position where the actual bits were.
 *
 * Due to a bug in old versions of pixman, where it would not clip
 * against the image bounds when a clip region was set, this would
 * actually work. So when the pixman bug was fixed, a workaround was
 * added to allow certain out-of-bound accesses. This function disabled
 * those workarounds.
 *
 * Since 0.21.2, pixman doesn't do these workarounds anymore, so now
 * this function is a no-op.
 */
PIXMAN_EXPORT void
pixman_disable_out_of_bounds_workaround (void)
{
}

static void
compute_image_info (pixman_image_t *image)
{
    pixman_format_code_t code;
    uint32_t flags = 0;

    /* Transform */
    if (!image->common.transform)
    {
	flags |= (FAST_PATH_ID_TRANSFORM	|
		  FAST_PATH_X_UNIT_POSITIVE	|
		  FAST_PATH_Y_UNIT_ZERO		|
		  FAST_PATH_AFFINE_TRANSFORM);
    }
    else
    {
	flags |= FAST_PATH_HAS_TRANSFORM;

	if (image->common.transform->matrix[2][0] == 0			&&
	    image->common.transform->matrix[2][1] == 0			&&
	    image->common.transform->matrix[2][2] == pixman_fixed_1)
	{
	    flags |= FAST_PATH_AFFINE_TRANSFORM;

	    if (image->common.transform->matrix[0][1] == 0 &&
		image->common.transform->matrix[1][0] == 0)
	    {
		if (image->common.transform->matrix[0][0] == -pixman_fixed_1 &&
		    image->common.transform->matrix[1][1] == -pixman_fixed_1)
		{
		    flags |= FAST_PATH_ROTATE_180_TRANSFORM;
		}
		flags |= FAST_PATH_SCALE_TRANSFORM;
	    }
	    else if (image->common.transform->matrix[0][0] == 0 &&
	             image->common.transform->matrix[1][1] == 0)
	    {
		pixman_fixed_t m01 = image->common.transform->matrix[0][1];
		pixman_fixed_t m10 = image->common.transform->matrix[1][0];

		if (m01 == -1 && m10 == 1)
		    flags |= FAST_PATH_ROTATE_90_TRANSFORM;
		else if (m01 == 1 && m10 == -1)
		    flags |= FAST_PATH_ROTATE_270_TRANSFORM;
	    }
	}

	if (image->common.transform->matrix[0][0] > 0)
	    flags |= FAST_PATH_X_UNIT_POSITIVE;

	if (image->common.transform->matrix[1][0] == 0)
	    flags |= FAST_PATH_Y_UNIT_ZERO;
    }

    /* Filter */
    switch (image->common.filter)
    {
    case PIXMAN_FILTER_NEAREST:
    case PIXMAN_FILTER_FAST:
	flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
	break;

    case PIXMAN_FILTER_BILINEAR:
    case PIXMAN_FILTER_GOOD:
    case PIXMAN_FILTER_BEST:
	flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);

	/* Here we have a chance to optimize BILINEAR filter to NEAREST if
	 * they are equivalent for the currently used transformation matrix.
	 */
	if (flags & FAST_PATH_ID_TRANSFORM)
	{
	    flags |= FAST_PATH_NEAREST_FILTER;
	}
	else if (
	    /* affine and integer translation components in matrix ... */
	    ((flags & FAST_PATH_AFFINE_TRANSFORM) &&
	     !pixman_fixed_frac (image->common.transform->matrix[0][2] |
				 image->common.transform->matrix[1][2])) &&
	    (
		/* ... combined with a simple rotation */
		(flags & (FAST_PATH_ROTATE_90_TRANSFORM |
			  FAST_PATH_ROTATE_180_TRANSFORM |
			  FAST_PATH_ROTATE_270_TRANSFORM)) ||
		/* ... or combined with a simple non-rotated translation */
		(image->common.transform->matrix[0][0] == pixman_fixed_1 &&
		 image->common.transform->matrix[1][1] == pixman_fixed_1 &&
		 image->common.transform->matrix[0][1] == 0 &&
		 image->common.transform->matrix[1][0] == 0)
		)
	    )
	{
	    /* FIXME: there are some affine-test failures, showing that
	     * handling of BILINEAR and NEAREST filter is not quite
	     * equivalent when getting close to 32K for the translation
	     * components of the matrix. That's likely some bug, but for
	     * now just skip BILINEAR->NEAREST optimization in this case.
	     */
	    pixman_fixed_t magic_limit = pixman_int_to_fixed (30000);
	    if (image->common.transform->matrix[0][2] <= magic_limit  &&
	        image->common.transform->matrix[1][2] <= magic_limit  &&
	        image->common.transform->matrix[0][2] >= -magic_limit &&
	        image->common.transform->matrix[1][2] >= -magic_limit)
	    {
		flags |= FAST_PATH_NEAREST_FILTER;
	    }
	}
	break;

    case PIXMAN_FILTER_CONVOLUTION:
	break;

    default:
	flags |= FAST_PATH_NO_CONVOLUTION_FILTER;
	break;
    }

    /* Repeat mode */
    switch (image->common.repeat)
    {
    case PIXMAN_REPEAT_NONE:
	flags |=
	    FAST_PATH_NO_REFLECT_REPEAT		|
	    FAST_PATH_NO_PAD_REPEAT		|
	    FAST_PATH_NO_NORMAL_REPEAT;
	break;

    case PIXMAN_REPEAT_REFLECT:
	flags |=
	    FAST_PATH_NO_PAD_REPEAT		|
	    FAST_PATH_NO_NONE_REPEAT		|
	    FAST_PATH_NO_NORMAL_REPEAT;
	break;

    case PIXMAN_REPEAT_PAD:
	flags |=
	    FAST_PATH_NO_REFLECT_REPEAT		|
	    FAST_PATH_NO_NONE_REPEAT		|
	    FAST_PATH_NO_NORMAL_REPEAT;
	break;

    default:
	flags |=
	    FAST_PATH_NO_REFLECT_REPEAT		|
	    FAST_PATH_NO_PAD_REPEAT		|
	    FAST_PATH_NO_NONE_REPEAT;
	break;
    }

    /* Component alpha */
    if (image->common.component_alpha)
	flags |= FAST_PATH_COMPONENT_ALPHA;
    else
	flags |= FAST_PATH_UNIFIED_ALPHA;

    flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NARROW_FORMAT);

    /* Type specific checks */
    switch (image->type)
    {
    case SOLID:
	code = PIXMAN_solid;

	if (image->solid.color.alpha == 0xffff)
	    flags |= FAST_PATH_IS_OPAQUE;
	break;

    case BITS:
	if (image->bits.width == 1	&&
	    image->bits.height == 1	&&
	    image->common.repeat != PIXMAN_REPEAT_NONE)
	{
	    code = PIXMAN_solid;
	}
	else
	{
	    code = image->bits.format;
	    flags |= FAST_PATH_BITS_IMAGE;
	}

	if (!PIXMAN_FORMAT_A (image->bits.format)				&&
	    PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_GRAY		&&
	    PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_COLOR)
	{
	    flags |= FAST_PATH_SAMPLES_OPAQUE;

	    if (image->common.repeat != PIXMAN_REPEAT_NONE)
		flags |= FAST_PATH_IS_OPAQUE;
	}

	if (image->bits.read_func || image->bits.write_func)
	    flags &= ~FAST_PATH_NO_ACCESSORS;

	if (PIXMAN_FORMAT_IS_WIDE (image->bits.format))
	    flags &= ~FAST_PATH_NARROW_FORMAT;
	break;

    case RADIAL:
	code = PIXMAN_unknown;

	/*
	 * As explained in pixman-radial-gradient.c, every point of
	 * the plane has a valid associated radius (and thus will be
	 * colored) if and only if a is negative (i.e. one of the two
	 * circles contains the other one).
	 */

        if (image->radial.a >= 0)
	    break;

	/* Fall through */

    case CONICAL:
    case LINEAR:
	code = PIXMAN_unknown;

	if (image->common.repeat != PIXMAN_REPEAT_NONE)
	{
	    int i;

	    flags |= FAST_PATH_IS_OPAQUE;
	    for (i = 0; i < image->gradient.n_stops; ++i)
	    {
		if (image->gradient.stops[i].color.alpha != 0xffff)
		{
		    flags &= ~FAST_PATH_IS_OPAQUE;
		    break;
		}
	    }
	}
	break;

    default:
	code = PIXMAN_unknown;
	break;
    }

    /* Alpha map */
    if (!image->common.alpha_map)
    {
	flags |= FAST_PATH_NO_ALPHA_MAP;
    }
    else
    {
	if (PIXMAN_FORMAT_IS_WIDE (image->common.alpha_map->format))
	    flags &= ~FAST_PATH_NARROW_FORMAT;
    }

    /* Both alpha maps and convolution filters can introduce
     * non-opaqueness in otherwise opaque images. Also
     * an image with component alpha turned on is only opaque
     * if all channels are opaque, so we simply turn it off
     * unconditionally for those images.
     */
    if (image->common.alpha_map					||
	image->common.filter == PIXMAN_FILTER_CONVOLUTION	||
	image->common.component_alpha)
    {
	flags &= ~(FAST_PATH_IS_OPAQUE | FAST_PATH_SAMPLES_OPAQUE);
    }

    image->common.flags = flags;
    image->common.extended_format_code = code;
}

void
_pixman_image_validate (pixman_image_t *image)
{
    if (image->common.dirty)
    {
	compute_image_info (image);

	/* It is important that property_changed is
	 * called *after* compute_image_info() because
	 * property_changed() can make use of the flags
	 * to set up accessors etc.
	 */
	if (image->common.property_changed)
	    image->common.property_changed (image);

	image->common.dirty = FALSE;
    }

    if (image->common.alpha_map)
	_pixman_image_validate ((pixman_image_t *)image->common.alpha_map);
}

PIXMAN_EXPORT pixman_bool_t
pixman_image_set_clip_region32 (pixman_image_t *   image,
                                pixman_region32_t *region)
{
    image_common_t *common = (image_common_t *)image;
    pixman_bool_t result;

    if (region)
    {
	if ((result = pixman_region32_copy (&common->clip_region, region)))
	    image->common.have_clip_region = TRUE;
    }
    else
    {
	_pixman_image_reset_clip_region (image);

	result = TRUE;
    }

    image_property_changed (image);

    return result;
}

PIXMAN_EXPORT pixman_bool_t
pixman_image_set_clip_region (pixman_image_t *   image,
                              pixman_region16_t *region)
{
    image_common_t *common = (image_common_t *)image;
    pixman_bool_t result;

    if (region)
    {
	if ((result = pixman_region32_copy_from_region16 (&common->clip_region, region)))
	    image->common.have_clip_region = TRUE;
    }
    else
    {
	_pixman_image_reset_clip_region (image);

	result = TRUE;
    }

    image_property_changed (image);

    return result;
}

PIXMAN_EXPORT void
pixman_image_set_has_client_clip (pixman_image_t *image,
                                  pixman_bool_t   client_clip)
{
    image->common.client_clip = client_clip;
}

PIXMAN_EXPORT pixman_bool_t
pixman_image_set_transform (pixman_image_t *          image,
                            const pixman_transform_t *transform)
{
    static const pixman_transform_t id =
    {
	{ { pixman_fixed_1, 0, 0 },
	  { 0, pixman_fixed_1, 0 },
	  { 0, 0, pixman_fixed_1 } }
    };

    image_common_t *common = (image_common_t *)image;
    pixman_bool_t result;

    if (common->transform == transform)
	return TRUE;

    if (!transform || memcmp (&id, transform, sizeof (pixman_transform_t)) == 0)
    {
	free (common->transform);
	common->transform = NULL;
	result = TRUE;

	goto out;
    }

    if (common->transform &&
	memcmp (common->transform, transform, sizeof (pixman_transform_t)) == 0)
    {
	return TRUE;
    }

    if (common->transform == NULL)
	common->transform = malloc (sizeof (pixman_transform_t));

    if (common->transform == NULL)
    {
	result = FALSE;

	goto out;
    }

    memcpy (common->transform, transform, sizeof(pixman_transform_t));

    result = TRUE;

out:
    image_property_changed (image);

    return result;
}

PIXMAN_EXPORT void
pixman_image_set_repeat (pixman_image_t *image,
                         pixman_repeat_t repeat)
{
    if (image->common.repeat == repeat)
	return;

    image->common.repeat = repeat;

    image_property_changed (image);
}

PIXMAN_EXPORT pixman_bool_t
pixman_image_set_filter (pixman_image_t *      image,
                         pixman_filter_t       filter,
                         const pixman_fixed_t *params,
                         int                   n_params)
{
    image_common_t *common = (image_common_t *)image;
    pixman_fixed_t *new_params;

    if (params == common->filter_params && filter == common->filter)
	return TRUE;

    new_params = NULL;
    if (params)
    {
	new_params = pixman_malloc_ab (n_params, sizeof (pixman_fixed_t));
	if (!new_params)
	    return FALSE;

	memcpy (new_params,
	        params, n_params * sizeof (pixman_fixed_t));
    }

    common->filter = filter;

    if (common->filter_params)
	free (common->filter_params);

    common->filter_params = new_params;
    common->n_filter_params = n_params;

    image_property_changed (image);
    return TRUE;
}

PIXMAN_EXPORT void
pixman_image_set_source_clipping (pixman_image_t *image,
                                  pixman_bool_t   clip_sources)
{
    if (image->common.clip_sources == clip_sources)
	return;

    image->common.clip_sources = clip_sources;

    image_property_changed (image);
}

/* Unlike all the other property setters, this function does not
 * copy the content of indexed. Doing this copying is simply
 * way, way too expensive.
 */
PIXMAN_EXPORT void
pixman_image_set_indexed (pixman_image_t *        image,
                          const pixman_indexed_t *indexed)
{
    bits_image_t *bits = (bits_image_t *)image;

    if (bits->indexed == indexed)
	return;

    bits->indexed = indexed;

    image_property_changed (image);
}

PIXMAN_EXPORT void
pixman_image_set_alpha_map (pixman_image_t *image,
                            pixman_image_t *alpha_map,
                            int16_t         x,
                            int16_t         y)
{
    image_common_t *common = (image_common_t *)image;

    return_if_fail (!alpha_map || alpha_map->type == BITS);

    if (alpha_map && common->alpha_count > 0)
    {
	/* If this image is being used as an alpha map itself,
	 * then you can't give it an alpha map of its own.
	 */
	return;
    }

    if (alpha_map && alpha_map->common.alpha_map)
    {
	/* If the image has an alpha map of its own,
	 * then it can't be used as an alpha map itself
	 */
	return;
    }

    if (common->alpha_map != (bits_image_t *)alpha_map)
    {
	if (common->alpha_map)
	{
	    common->alpha_map->common.alpha_count--;

	    pixman_image_unref ((pixman_image_t *)common->alpha_map);
	}

	if (alpha_map)
	{
	    common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map);

	    common->alpha_map->common.alpha_count++;
	}
	else
	{
	    common->alpha_map = NULL;
	}
    }

    common->alpha_origin_x = x;
    common->alpha_origin_y = y;

    image_property_changed (image);
}

PIXMAN_EXPORT void
pixman_image_set_component_alpha   (pixman_image_t *image,
                                    pixman_bool_t   component_alpha)
{
    if (image->common.component_alpha == component_alpha)
	return;

    image->common.component_alpha = component_alpha;

    image_property_changed (image);
}

PIXMAN_EXPORT pixman_bool_t
pixman_image_get_component_alpha   (pixman_image_t       *image)
{
    return image->common.component_alpha;
}

PIXMAN_EXPORT void
pixman_image_set_accessors (pixman_image_t *           image,
                            pixman_read_memory_func_t  read_func,
                            pixman_write_memory_func_t write_func)
{
    return_if_fail (image != NULL);

    if (image->type == BITS)
    {
	image->bits.read_func = read_func;
	image->bits.write_func = write_func;

	image_property_changed (image);
    }
}

PIXMAN_EXPORT uint32_t *
pixman_image_get_data (pixman_image_t *image)
{
    if (image->type == BITS)
	return image->bits.bits;

    return NULL;
}

PIXMAN_EXPORT int
pixman_image_get_width (pixman_image_t *image)
{
    if (image->type == BITS)
	return image->bits.width;

    return 0;
}

PIXMAN_EXPORT int
pixman_image_get_height (pixman_image_t *image)
{
    if (image->type == BITS)
	return image->bits.height;

    return 0;
}

PIXMAN_EXPORT int
pixman_image_get_stride (pixman_image_t *image)
{
    if (image->type == BITS)
	return image->bits.rowstride * (int) sizeof (uint32_t);

    return 0;
}

PIXMAN_EXPORT int
pixman_image_get_depth (pixman_image_t *image)
{
    if (image->type == BITS)
	return PIXMAN_FORMAT_DEPTH (image->bits.format);

    return 0;
}

PIXMAN_EXPORT pixman_format_code_t
pixman_image_get_format (pixman_image_t *image)
{
    if (image->type == BITS)
	return image->bits.format;

    return 0;
}

uint32_t
_pixman_image_get_solid (pixman_implementation_t *imp,
			 pixman_image_t *         image,
                         pixman_format_code_t     format)
{
    uint32_t result;
    pixman_iter_t iter;

    _pixman_implementation_src_iter_init (
	imp, &iter, image, 0, 0, 1, 1,
	(uint8_t *)&result, ITER_NARROW);

    result = *iter.get_scanline (&iter, NULL);

    /* If necessary, convert RGB <--> BGR. */
    if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB)
    {
	result = (((result & 0xff000000) >>  0) |
	          ((result & 0x00ff0000) >> 16) |
	          ((result & 0x0000ff00) >>  0) |
	          ((result & 0x000000ff) << 16));
    }

    return result;
}
