Logo Search packages:      
Sourcecode: gandalf version File versions

image_channel.c

/**
 * File:          $RCSfile: image_channel.c,v $
 * Module:        Extract/fill selected channel(s) of image
 * Part of:       Gandalf Library
 *
 * Revision:      $Revision: 1.14 $
 * Last edited:   $Date: 2003/03/11 13:07:55 $
 * Author:        $Author: pm $
 * Copyright:     (c) 2000 Imagineer Software Limited
 */

/* This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <gandalf/image/image_channel.h>
#include <gandalf/image/image_extract.h>
#include <gandalf/image/image_gl_uchar.h>
#include <gandalf/image/image_gl_short.h>
#include <gandalf/image/image_gl_ushort.h>
#include <gandalf/image/image_gl_int.h>
#include <gandalf/image/image_gl_uint.h>
#include <gandalf/image/image_gl_float.h>
#include <gandalf/image/image_gl_double.h>
#include <gandalf/image/image_gla_uchar.h>
#include <gandalf/image/image_gla_short.h>
#include <gandalf/image/image_gla_ushort.h>
#include <gandalf/image/image_gla_int.h>
#include <gandalf/image/image_gla_uint.h>
#include <gandalf/image/image_gla_float.h>
#include <gandalf/image/image_gla_double.h>
#include <gandalf/image/image_rgb_uchar.h>
#include <gandalf/image/image_rgb_short.h>
#include <gandalf/image/image_rgb_ushort.h>
#include <gandalf/image/image_rgb_int.h>
#include <gandalf/image/image_rgb_uint.h>
#include <gandalf/image/image_rgb_float.h>
#include <gandalf/image/image_rgb_double.h>
#include <gandalf/image/image_rgba_uchar.h>
#include <gandalf/image/image_rgba_short.h>
#include <gandalf/image/image_rgba_ushort.h>
#include <gandalf/image/image_rgba_int.h>
#include <gandalf/image/image_rgba_uint.h>
#include <gandalf/image/image_rgba_float.h>
#include <gandalf/image/image_rgba_double.h>
#include <gandalf/image/image_vfield2D_short.h>
#include <gandalf/image/image_vfield2D_int.h>
#include <gandalf/image/image_vfield2D_float.h>
#include <gandalf/image/image_vfield2D_double.h>
#include <gandalf/image/image_vfield3D_short.h>
#include <gandalf/image/image_vfield3D_int.h>
#include <gandalf/image/image_vfield3D_float.h>
#include <gandalf/image/image_vfield3D_double.h>

/**
 * \addtogroup ImagePackage
 * \{
 */

/**
 * \defgroup ImageChannel Access Whole Channels of an Image
 * \{
 */

/* extract the intensity channel from a grey-level image with alpha channel */
static Gan_Image *
 gla_extract_intensity ( Gan_Image *source,
                         unsigned r0,     unsigned c0,
                         unsigned height, unsigned width,
                         Gan_Image *dest )
{
   int i, j;

   /* consistency check */
   gan_err_test_ptr ( source->format == GAN_GREY_LEVEL_ALPHA_IMAGE,
                      "gla_extract_intensity", GAN_ERROR_INCOMPATIBLE, "" );

   switch ( source->type )
   {
      case GAN_UCHAR:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_uc ( dest, i, j,
                                        gan_image_get_pixptr_gla_uc(source,
                                                                    r0+i,
                                                                    c0+j)->I );
        break;

      case GAN_SHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_s ( dest, i, j,
                                       gan_image_get_pixptr_gla_s(source,
                                                                  r0+i,
                                                                  c0+j)->I );
        break;

      case GAN_USHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_us ( dest, i, j,
                                        gan_image_get_pixptr_gla_us(source,
                                                                    r0+i,
                                                                    c0+j)->I );
        break;

      case GAN_INT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_i ( dest, i, j,
                                       gan_image_get_pixptr_gla_i(source,
                                                                  r0+i,
                                                                  c0+j)->I );
        break;

      case GAN_UINT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_ui ( dest, i, j,
                                        gan_image_get_pixptr_gla_ui(source,
                                                                    r0+i,
                                                                    c0+j)->I );
        break;

      case GAN_FLOAT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_f ( dest, i, j,
                                       gan_image_get_pixptr_gla_f(source,
                                                                  r0+i,
                                                                  c0+j)->I );
        break;

      default:
        gan_err_flush_trace();
        gan_err_register (  "gla_extract_intensity",
                            GAN_ERROR_NOT_IMPLEMENTED, "image conversion" );
        return NULL;
   }

   /* success */
   return dest;
}

/* extract the alpha channel from a grey-level image with alpha channel */
static Gan_Image *
 gla_extract_alpha ( Gan_Image *source,
                     unsigned r0,     unsigned c0,
                     unsigned height, unsigned width,
                     Gan_Image *dest )
{
   int i, j;

   /* consistency check */
   gan_err_test_ptr ( source->format == GAN_GREY_LEVEL_ALPHA_IMAGE,
                      "gla_extract_alpha", GAN_ERROR_INCOMPATIBLE, "" );

   switch ( source->type )
   {
      case GAN_UCHAR:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_uc ( dest, i, j,
                                        gan_image_get_pixptr_gla_uc(source,
                                                                    r0+i,
                                                                    c0+j)->A );

        break;

      case GAN_SHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_s ( dest, i, j,
                                       gan_image_get_pixptr_gla_s(source,
                                                                  r0+i,
                                                                  c0+j)->A );
        break;

      case GAN_USHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_us ( dest, i, j,
                                        gan_image_get_pixptr_gla_us(source,
                                                                    r0+i,
                                                                    c0+j)->A );
        break;

      case GAN_INT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_i ( dest, i, j,
                                       gan_image_get_pixptr_gla_i(source,
                                                                  r0+i,
                                                                  c0+j)->A );
        break;

      case GAN_UINT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_ui ( dest, i, j,
                                        gan_image_get_pixptr_gla_ui(source,
                                                                    r0+i,
                                                                    c0+j)->A );
        break;

      case GAN_FLOAT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_f ( dest, i, j,
                                       gan_image_get_pixptr_gla_f(source,
                                                                  r0+i,
                                                                  c0+j)->A );
        break;

      default:
        gan_err_flush_trace();
        gan_err_register (  "gla_extract_alpha",
                            GAN_ERROR_NOT_IMPLEMENTED, "image conversion" );
        return NULL;
   }

   /* success */
   return dest;
}

/* extract the red channel from an RGB colour image */
static Gan_Image *
 rgb_extract_red ( Gan_Image *source,
                   unsigned r0,     unsigned c0,
                   unsigned height, unsigned width,
                   Gan_Image *dest )
{
   int i, j;

   /* consistency check */
   gan_err_test_ptr ( source->format == GAN_RGB_COLOUR_IMAGE,
                      "rgb_extract_red", GAN_ERROR_INCOMPATIBLE, "" );

   switch ( source->type )
   {
      case GAN_UCHAR:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_uc ( dest, i, j,
                                        gan_image_get_pixptr_rgb_uc(source,
                                                                    r0+i,
                                                                    c0+j)->R );
        break;

      case GAN_SHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_s ( dest, i, j,
                                       gan_image_get_pixptr_rgb_s(source,
                                                                  r0+i,
                                                                  c0+j)->R );
        break;

      case GAN_USHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_us ( dest, i, j,
                                        gan_image_get_pixptr_rgb_us(source,
                                                                    r0+i,
                                                                    c0+j)->R );
        break;

      case GAN_INT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_i ( dest, i, j,
                                       gan_image_get_pixptr_rgb_i(source,
                                                                  r0+i,
                                                                  c0+j)->R );
        break;

      case GAN_UINT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_ui ( dest, i, j,
                                        gan_image_get_pixptr_rgb_ui(source,
                                                                    r0+i,
                                                                    c0+j)->R );
        break;

      case GAN_FLOAT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_f ( dest, i, j,
                                       gan_image_get_pixptr_rgb_f(source,
                                                                  r0+i,
                                                                  c0+j)->R );
        break;

      default:
        gan_err_flush_trace();
        gan_err_register (  "rgb_extract_red",
                            GAN_ERROR_NOT_IMPLEMENTED, "image conversion" );
        return NULL;
   }

   /* success */
   return dest;
}

/* extract the green channel from an RGB colour image */
static Gan_Image *
 rgb_extract_green ( Gan_Image *source,
                     unsigned r0,     unsigned c0,
                     unsigned height, unsigned width,
                     Gan_Image *dest )
{
   int i, j;

   /* consistency check */
   gan_err_test_ptr ( source->format == GAN_RGB_COLOUR_IMAGE,
                      "rgb_extract_green", GAN_ERROR_INCOMPATIBLE, "" );

   switch ( source->type )
   {
      case GAN_UCHAR:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_uc ( dest, i, j,
                                        gan_image_get_pixptr_rgb_uc(source,
                                                                    r0+i,
                                                                    c0+j)->G );
        break;

      case GAN_SHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_s ( dest, i, j,
                                       gan_image_get_pixptr_rgb_s(source,
                                                                  r0+i,
                                                                  c0+j)->G );
        break;

      case GAN_USHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_us ( dest, i, j,
                                        gan_image_get_pixptr_rgb_us(source,
                                                                    r0+i,
                                                                    c0+j)->G );
        break;

      case GAN_INT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_i ( dest, i, j,
                                       gan_image_get_pixptr_rgb_i(source,
                                                                  r0+i,
                                                                  c0+j)->G );
        break;

      case GAN_UINT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_ui ( dest, i, j,
                                        gan_image_get_pixptr_rgb_ui(source,
                                                                    r0+i,
                                                                    c0+j)->G );
        break;

      case GAN_FLOAT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_f ( dest, i, j,
                                       gan_image_get_pixptr_rgb_f(source,
                                                                  r0+i,
                                                                  c0+j)->G );
        break;

      default:
        gan_err_flush_trace();
        gan_err_register (  "rgb_extract_green",
                            GAN_ERROR_NOT_IMPLEMENTED, "image conversion" );
        return NULL;
   }

   /* success */
   return dest;
}

/* extract the blue channel from an RGB colour image */
static Gan_Image *
 rgb_extract_blue ( Gan_Image *source,
                    unsigned r0,     unsigned c0,
                    unsigned height, unsigned width,
                    Gan_Image *dest )
{
   int i, j;

   /* consistency check */
   gan_err_test_ptr ( source->format == GAN_RGB_COLOUR_IMAGE,
                      "rgb_extract_blue", GAN_ERROR_INCOMPATIBLE, "" );

   switch ( source->type )
   {
      case GAN_UCHAR:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_uc ( dest, i, j,
                                        gan_image_get_pixptr_rgb_uc(source,
                                                                    r0+i,
                                                                    c0+j)->B );
        break;

      case GAN_SHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_s ( dest, i, j,
                                       gan_image_get_pixptr_rgb_s(source,
                                                                  r0+i,
                                                                  c0+j)->B );
        break;

      case GAN_USHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_us ( dest, i, j,
                                        gan_image_get_pixptr_rgb_us(source,
                                                                    r0+i,
                                                                    c0+j)->B );
        break;

      case GAN_INT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_i ( dest, i, j,
                                       gan_image_get_pixptr_rgb_i(source,
                                                                  r0+i,
                                                                  c0+j)->B );
        break;

      case GAN_UINT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_ui ( dest, i, j,
                                        gan_image_get_pixptr_rgb_ui(source,
                                                                    r0+i,
                                                                    c0+j)->B );
        break;

      case GAN_FLOAT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_f ( dest, i, j,
                                       gan_image_get_pixptr_rgb_f(source,
                                                                  r0+i,
                                                                  c0+j)->B );
        break;

      default:
        gan_err_flush_trace();
        gan_err_register (  "rgb_extract_blue",
                            GAN_ERROR_NOT_IMPLEMENTED, "image conversion" );
        return NULL;
   }

   /* success */
   return dest;
}

/* extract the red channel from an RGB colour image with alpha channel */
static Gan_Image *
 rgba_extract_red ( Gan_Image *source,
                    unsigned r0,     unsigned c0,
                    unsigned height, unsigned width,
                    Gan_Image *dest )
{
   int i, j;

   /* consistency check */
   gan_err_test_ptr ( source->format == GAN_RGB_COLOUR_ALPHA_IMAGE,
                      "rgba_extract_red", GAN_ERROR_INCOMPATIBLE, "" );

   switch ( source->type )
   {
      case GAN_UCHAR:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_uc ( dest, i, j,
                                        gan_image_get_pixptr_rgba_uc(source,
                                                                     r0+i,
                                                                     c0+j)->R);
        break;

      case GAN_SHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_s ( dest, i, j,
                                       gan_image_get_pixptr_rgba_s(source,
                                                                   r0+i,
                                                                   c0+j)->R);
        break;

      case GAN_USHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_us ( dest, i, j,
                                        gan_image_get_pixptr_rgba_us(source,
                                                                     r0+i,
                                                                     c0+j)->R);
        break;

      case GAN_INT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_i ( dest, i, j,
                                       gan_image_get_pixptr_rgba_i(source,
                                                                   r0+i,
                                                                   c0+j)->R);
        break;

      case GAN_UINT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_ui ( dest, i, j,
                                        gan_image_get_pixptr_rgba_ui(source,
                                                                     r0+i,
                                                                     c0+j)->R);
        break;

      case GAN_FLOAT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_f ( dest, i, j,
                                       gan_image_get_pixptr_rgba_f(source,
                                                                   r0+i,
                                                                   c0+j)->R);
        break;

      default:
        gan_err_flush_trace();
        gan_err_register (  "rgba_extract_red",
                            GAN_ERROR_NOT_IMPLEMENTED, "image conversion" );
        return NULL;
   }

   /* success */
   return dest;
}

/* extract the green channel from an RGB colour image with alpha channel */
static Gan_Image *
 rgba_extract_green ( Gan_Image *source,
                      unsigned r0,     unsigned c0,
                      unsigned height, unsigned width,
                      Gan_Image *dest )
{
   int i, j;

   /* consistency check */
   gan_err_test_ptr ( source->format == GAN_RGB_COLOUR_ALPHA_IMAGE,
                      "rgba_extract_green", GAN_ERROR_INCOMPATIBLE, "" );

   switch ( source->type )
   {
      case GAN_UCHAR:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_uc ( dest, i, j,
                                        gan_image_get_pixptr_rgba_uc(source,
                                                                     r0+i,
                                                                     c0+j)->G);
        break;

      case GAN_SHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_s ( dest, i, j,
                                       gan_image_get_pixptr_rgba_s(source,
                                                                   r0+i,
                                                                   c0+j)->G);
        break;

      case GAN_USHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_us ( dest, i, j,
                                        gan_image_get_pixptr_rgba_us(source,
                                                                     r0+i,
                                                                     c0+j)->G);
        break;

      case GAN_INT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_i ( dest, i, j,
                                       gan_image_get_pixptr_rgba_i(source,
                                                                   r0+i,
                                                                   c0+j)->G);
        break;

      case GAN_UINT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_ui ( dest, i, j,
                                        gan_image_get_pixptr_rgba_ui(source,
                                                                     r0+i,
                                                                     c0+j)->G);
        break;

      case GAN_FLOAT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_f ( dest, i, j,
                                       gan_image_get_pixptr_rgba_f(source,
                                                                   r0+i,
                                                                   c0+j)->G);
        break;

      default:
        gan_err_flush_trace();
        gan_err_register (  "rgba_extract_green",
                            GAN_ERROR_NOT_IMPLEMENTED, "image conversion" );
        return NULL;
   }

   /* success */
   return dest;
}

/* extract the blue channel from an RGB colour image with alpha channel */
static Gan_Image *
 rgba_extract_blue ( Gan_Image *source,
                     unsigned r0,     unsigned c0,
                     unsigned height, unsigned width,
                     Gan_Image *dest )
{
   int i, j;

   /* consistency check */
   gan_err_test_ptr ( source->format == GAN_RGB_COLOUR_ALPHA_IMAGE,
                      "rgba_extract_blue", GAN_ERROR_INCOMPATIBLE, "" );

   switch ( source->type )
   {
      case GAN_UCHAR:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_uc ( dest, i, j,
                                        gan_image_get_pixptr_rgba_uc(source,
                                                                     r0+i,
                                                                     c0+j)->B);
        break;

      case GAN_SHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_s ( dest, i, j,
                                       gan_image_get_pixptr_rgba_s(source,
                                                                   r0+i,
                                                                   c0+j)->B);
        break;

      case GAN_USHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_us ( dest, i, j,
                                        gan_image_get_pixptr_rgba_us(source,
                                                                     r0+i,
                                                                     c0+j)->B);
        break;

      case GAN_INT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_i ( dest, i, j,
                                       gan_image_get_pixptr_rgba_i(source,
                                                                   r0+i,
                                                                   c0+j)->B);
        break;

      case GAN_UINT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_ui ( dest, i, j,
                                        gan_image_get_pixptr_rgba_ui(source,
                                                                     r0+i,
                                                                     c0+j)->B);
        break;

      case GAN_FLOAT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_f ( dest, i, j,
                                       gan_image_get_pixptr_rgba_f(source,
                                                                   r0+i,
                                                                   c0+j)->B);
        break;

      default:
        gan_err_flush_trace();
        gan_err_register (  "rgba_extract_blue",
                            GAN_ERROR_NOT_IMPLEMENTED, "image conversion" );
        return NULL;
   }

   /* success */
   return dest;
}

/* extract the alpha channel from an RGB colour image with alpha channel */
static Gan_Image *
 rgba_extract_alpha ( Gan_Image *source,
                      unsigned r0,     unsigned c0,
                      unsigned height, unsigned width,
                      Gan_Image *dest )
{
   int i, j;

   /* consistency check */
   gan_err_test_ptr ( source->format == GAN_RGB_COLOUR_ALPHA_IMAGE,
                      "rgba_extract_alpha", GAN_ERROR_INCOMPATIBLE, "" );

   switch ( source->type )
   {
      case GAN_UCHAR:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_uc ( dest, i, j,
                                        gan_image_get_pixptr_rgba_uc(source,
                                                                     r0+i,
                                                                     c0+j)->A);
        break;

      case GAN_SHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_s ( dest, i, j,
                                       gan_image_get_pixptr_rgba_s(source,
                                                                   r0+i,
                                                                   c0+j)->A);
        break;

      case GAN_USHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_us ( dest, i, j,
                                        gan_image_get_pixptr_rgba_us(source,
                                                                     r0+i,
                                                                     c0+j)->A);
        break;

      case GAN_INT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_i ( dest, i, j,
                                       gan_image_get_pixptr_rgba_i(source,
                                                                   r0+i,
                                                                   c0+j)->A);
        break;

      case GAN_UINT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_ui ( dest, i, j,
                                        gan_image_get_pixptr_rgba_ui(source,
                                                                     r0+i,
                                                                     c0+j)->A);
        break;

      case GAN_FLOAT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_f ( dest, i, j,
                                       gan_image_get_pixptr_rgba_f(source,
                                                                   r0+i,
                                                                   c0+j)->A);
        break;

      default:
        gan_err_flush_trace();
        gan_err_register (  "rgba_extract_alpha",
                            GAN_ERROR_NOT_IMPLEMENTED, "image conversion" );
        return NULL;
   }

   /* success */
   return dest;
}

/* extract the x coordinate channel from a 2D vector field image */
static Gan_Image *
 vfield2D_extract_x ( Gan_Image *source,
                      unsigned r0,     unsigned c0,
                      unsigned height, unsigned width,
                      Gan_Image *dest )
{
   int i, j;

   /* consistency check */
   gan_err_test_ptr ( source->format == GAN_VECTOR_FIELD_2D,
                      "vfield2D_extract_x", GAN_ERROR_INCOMPATIBLE, "" );

   switch ( source->type )
   {
      case GAN_SHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_s(dest, i, j,
                                     gan_image_get_pixptr_vfield2D_s(source,
                                                                     r0+i,
                                                                     c0+j)->x);
        break;

      case GAN_INT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_i(dest, i, j,
                                     gan_image_get_pixptr_vfield2D_i(source,
                                                                     r0+i,
                                                                     c0+j)->x);
        break;

      case GAN_FLOAT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_f(dest, i, j,
                                     gan_image_get_pixptr_vfield2D_f(source,
                                                                     r0+i,
                                                                     c0+j)->x);
        break;

      case GAN_DOUBLE:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_d(dest, i, j,
                                     gan_image_get_pixptr_vfield2D_d(source,
                                                                     r0+i,
                                                                     c0+j)->x);
        break;

      default:
        gan_err_flush_trace();
        gan_err_register (  "vfield2D_extract_x",
                            GAN_ERROR_NOT_IMPLEMENTED, "image conversion" );
        return NULL;
   }

   /* success */
   return dest;
}

/* extract the y coordinate channel from a 2D vector field image */
static Gan_Image *
 vfield2D_extract_y ( Gan_Image *source,
                      unsigned r0,     unsigned c0,
                      unsigned height, unsigned width,
                      Gan_Image *dest )
{
   int i, j;

   /* consistency check */
   gan_err_test_ptr ( source->format == GAN_VECTOR_FIELD_2D,
                      "vfield2D_extract_y", GAN_ERROR_INCOMPATIBLE, "" );

   switch ( source->type )
   {
      case GAN_SHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_s(dest, i, j,
                                     gan_image_get_pixptr_vfield2D_s(source,
                                                                     r0+i,
                                                                     c0+j)->y);
        break;

      case GAN_INT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_i(dest, i, j,
                                     gan_image_get_pixptr_vfield2D_i(source,
                                                                     r0+i,
                                                                     c0+j)->y);
        break;

      case GAN_FLOAT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_f(dest, i, j,
                                     gan_image_get_pixptr_vfield2D_f(source,
                                                                     r0+i,
                                                                     c0+j)->y);
        break;

      case GAN_DOUBLE:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_d(dest, i, j,
                                     gan_image_get_pixptr_vfield2D_d(source,
                                                                     r0+i,
                                                                     c0+j)->y);
        break;

      default:
        gan_err_flush_trace();
        gan_err_register (  "vfield2D_extract_y",
                            GAN_ERROR_NOT_IMPLEMENTED, "image conversion" );
        return NULL;
   }

   /* success */
   return dest;
}

/* extract the x coordinate channel from a 3D vector field image */
static Gan_Image *
 vfield3D_extract_x ( Gan_Image *source,
                      unsigned r0,     unsigned c0,
                      unsigned height, unsigned width,
                      Gan_Image *dest )
{
   int i, j;

   /* consistency check */
   gan_err_test_ptr ( source->format == GAN_VECTOR_FIELD_3D,
                      "vfield3D_extract_x", GAN_ERROR_INCOMPATIBLE, "" );

   switch ( source->type )
   {
      case GAN_SHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_s(dest, i, j,
                                     gan_image_get_pixptr_vfield3D_s(source,
                                                                     r0+i,
                                                                     c0+j)->x);
        break;

      case GAN_INT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_i(dest, i, j,
                                     gan_image_get_pixptr_vfield3D_i(source,
                                                                     r0+i,
                                                                     c0+j)->x);
        break;

      case GAN_FLOAT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_f(dest, i, j,
                                     gan_image_get_pixptr_vfield3D_f(source,
                                                                     r0+i,
                                                                     c0+j)->x);
        break;

      case GAN_DOUBLE:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_d(dest, i, j,
                                     gan_image_get_pixptr_vfield3D_d(source,
                                                                     r0+i,
                                                                     c0+j)->x);
        break;

      default:
        gan_err_flush_trace();
        gan_err_register (  "vfield3D_extract_x",
                            GAN_ERROR_NOT_IMPLEMENTED, "image conversion" );
        return NULL;
   }

   /* success */
   return dest;
}

/* extract the y coordinate channel from a 3D vector field image */
static Gan_Image *
 vfield3D_extract_y ( Gan_Image *source,
                      unsigned r0,     unsigned c0,
                      unsigned height, unsigned width,
                      Gan_Image *dest )
{
   int i, j;

   /* consistency check */
   gan_err_test_ptr ( source->format == GAN_VECTOR_FIELD_3D,
                      "vfield3D_extract_y", GAN_ERROR_INCOMPATIBLE, "" );

   switch ( source->type )
   {
      case GAN_SHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_s(dest, i, j,
                                     gan_image_get_pixptr_vfield3D_s(source,
                                                                     r0+i,
                                                                     c0+j)->y);
        break;

      case GAN_INT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_i(dest, i, j,
                                     gan_image_get_pixptr_vfield3D_i(source,
                                                                     r0+i,
                                                                     c0+j)->y);
        break;

      case GAN_FLOAT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_f(dest, i, j,
                                     gan_image_get_pixptr_vfield3D_f(source,
                                                                     r0+i,
                                                                     c0+j)->y);
        break;

      case GAN_DOUBLE:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_d(dest, i, j,
                                     gan_image_get_pixptr_vfield3D_d(source,
                                                                     r0+i,
                                                                     c0+j)->y);
        break;

      default:
        gan_err_flush_trace();
        gan_err_register (  "vfield3D_extract_y",
                            GAN_ERROR_NOT_IMPLEMENTED, "image conversion" );
        return NULL;
   }

   /* success */
   return dest;
}

/* extract the z coordinate channel from a 3D vector field image */
static Gan_Image *
 vfield3D_extract_z ( Gan_Image *source,
                      unsigned r0,     unsigned c0,
                      unsigned height, unsigned width,
                      Gan_Image *dest )
{
   int i, j;

   /* consistency check */
   gan_err_test_ptr ( source->format == GAN_VECTOR_FIELD_3D,
                      "vfield3D_extract_z", GAN_ERROR_INCOMPATIBLE, "" );

   switch ( source->type )
   {
      case GAN_SHORT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_s(dest, i, j,
                                     gan_image_get_pixptr_vfield3D_s(source,
                                                                     r0+i,
                                                                     c0+j)->z);
        break;

      case GAN_INT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_i(dest, i, j,
                                     gan_image_get_pixptr_vfield3D_i(source,
                                                                     r0+i,
                                                                     c0+j)->z);
        break;

      case GAN_FLOAT:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_f(dest, i, j,
                                     gan_image_get_pixptr_vfield3D_f(source,
                                                                     r0+i,
                                                                     c0+j)->z);
        break;

      case GAN_DOUBLE:
        for ( i = (int)height-1; i >= 0; i-- )
           for ( j = (int)width-1; j >= 0; j-- )
              gan_image_set_pix_gl_d(dest, i, j,
                                     gan_image_get_pixptr_vfield3D_d(source,
                                                                     r0+i,
                                                                     c0+j)->z);
        break;

      default:
        gan_err_flush_trace();
        gan_err_register (  "vfield3D_extract_z",
                            GAN_ERROR_NOT_IMPLEMENTED, "image conversion" );
        return NULL;
   }

   /* success */
   return dest;
}

/**
 * \brief Extracts a specific channel from part of an image.
 * \param source The input image
 * \param channel The channel to extract from the image
 * \param r0 Vertical offset of start of region
 * \param c0 Horizontal offset of start of region
 * \param height Height of region in pixels
 * \param width Width of region in pixels
 * \param dest The destination image
 * \return A pointer to the extracted image, or \c NULL on failure.
 *
 * Extracts a specific channel in a sub-part of an image,
 *
 * \sa gan_image_extract_channel_s().
 */
Gan_Image *
01123  gan_image_extract_channel_q ( Gan_Image *source,
                               Gan_ImageChannelType channel,
                               unsigned r0,     unsigned c0,
                               unsigned height, unsigned width,
                               Gan_Image *dest )
{
   gan_err_test_ptr ( r0+height <= source->height && c0+width <= source->width,
                      "gan_image_extract_channel_q", GAN_ERROR_INCOMPATIBLE,
                      "illegal portion of source image" );

   /* allocate/set image */
   if ( dest == NULL )
      dest = gan_image_alloc ( GAN_GREY_LEVEL_IMAGE, source->type,
                               height, width );
   else
      dest = gan_image_set_format_type_dims ( dest, GAN_GREY_LEVEL_IMAGE,
                                              source->type, height, width );

   if ( dest == NULL )
   {
      gan_err_register ( "gan_image_extract_channel_q", GAN_ERROR_FAILURE, "");
      return NULL;
   }

   switch ( source->format )
   {
      case GAN_GREY_LEVEL_IMAGE:
        switch ( channel )
        {
           case GAN_INTENSITY_CHANNEL:
             dest = gan_image_extract_q ( source, r0, c0, height, width,
                                          source->format, source->type,
                                          GAN_TRUE, dest );
             break;

           default:
             gan_err_flush_trace();
             gan_err_register ( "gan_image_extract_channel_q",
                                GAN_ERROR_ILLEGAL_TYPE, "" );
             return NULL;
        }
        break;

      case GAN_GREY_LEVEL_ALPHA_IMAGE:
        switch ( channel )
        {
           case GAN_INTENSITY_CHANNEL:
             dest = gla_extract_intensity ( source, r0, c0, height, width,
                                            dest );
             break;

           case GAN_ALPHA_CHANNEL:
             dest = gla_extract_alpha ( source, r0, c0, height, width,
                                        dest );
             break;

           default:
             gan_err_flush_trace();
             gan_err_register ( "gan_image_extract_channel_q",
                                GAN_ERROR_ILLEGAL_TYPE, "" );
             return NULL;
        }
        break;

      case GAN_RGB_COLOUR_IMAGE:
        switch ( channel )
        {
           case GAN_RED_CHANNEL:
             dest = rgb_extract_red ( source, r0, c0, height, width, dest );
             break;

           case GAN_GREEN_CHANNEL:
             dest = rgb_extract_green ( source, r0, c0, height, width, dest );
             break;

           case GAN_BLUE_CHANNEL:
             dest = rgb_extract_blue ( source, r0, c0, height, width, dest );
             break;

           default:
             gan_err_flush_trace();
             gan_err_register ( "gan_image_extract_channel_q",
                                GAN_ERROR_ILLEGAL_TYPE, "" );
             return NULL;
        }
        break;

      case GAN_RGB_COLOUR_ALPHA_IMAGE:
        switch ( channel )
        {
           case GAN_RED_CHANNEL:
             dest = rgba_extract_red ( source, r0, c0, height, width, dest );
             break;

           case GAN_GREEN_CHANNEL:
             dest = rgba_extract_green ( source, r0, c0, height, width, dest );
             break;

           case GAN_BLUE_CHANNEL:
             dest = rgba_extract_blue ( source, r0, c0, height, width, dest );
             break;

           case GAN_ALPHA_CHANNEL:
             dest = rgba_extract_alpha ( source, r0, c0, height, width, dest );
             break;

           default:
             gan_err_flush_trace();
             gan_err_register ( "gan_image_extract_channel_q",
                                GAN_ERROR_ILLEGAL_TYPE, "" );
             return NULL;
        }
        break;

      case GAN_VECTOR_FIELD_2D:
        switch ( channel )
        {
           case GAN_X_CHANNEL:
             dest = vfield2D_extract_x ( source, r0, c0, height, width, dest );
             break;

           case GAN_Y_CHANNEL:
             dest = vfield2D_extract_y ( source, r0, c0, height, width, dest );
             break;

           default:
             gan_err_flush_trace();
             gan_err_register ( "gan_image_extract_channel_q",
                                GAN_ERROR_ILLEGAL_TYPE, "" );
             return NULL;
        }
        break;

      case GAN_VECTOR_FIELD_3D:
        switch ( channel )
        {
           case GAN_X_CHANNEL:
             dest = vfield3D_extract_x ( source, r0, c0, height, width, dest );
             break;

           case GAN_Y_CHANNEL:
             dest = vfield3D_extract_y ( source, r0, c0, height, width, dest );
             break;

           case GAN_Z_CHANNEL:
             dest = vfield3D_extract_z ( source, r0, c0, height, width, dest );
             break;

           default:
             gan_err_flush_trace();
             gan_err_register ( "gan_image_extract_channel_q",
                                GAN_ERROR_ILLEGAL_TYPE, "" );
             return NULL;
        }
        break;

      default:
        gan_err_flush_trace();
        gan_err_register ( "gan_image_extract_channel_q",
                           GAN_ERROR_ILLEGAL_TYPE, "" );
        return NULL;
   }
                                          
   if ( dest == NULL )
      gan_err_register ( "gan_image_extract_channel_q", GAN_ERROR_FAILURE,
                         "" );

   /* set offsets */
   dest->offset_x = source->offset_x+c0;
   dest->offset_y = source->offset_x+r0;

   /* success */
   return dest;
}

static Gan_Bool
 gla_fill_intensity ( Gan_Image *image, Gan_Pixel *pixel )
{
   int iRow, iCol;

   switch ( image->type )
   {
      case GAN_UCHAR:
      {
         unsigned char val = (pixel == NULL) ? 0 : pixel->data.gl.uc;
         Gan_GLAPixel_uc *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_gla_uc(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].I = val;
      }
      break;

      case GAN_USHORT:
      {
         unsigned short val = (pixel == NULL) ? 0 : pixel->data.gl.us;
         Gan_GLAPixel_us *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_gla_us(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].I = val;
      }
      break;

      case GAN_UINT:
      {
         unsigned int val = (pixel == NULL) ? 0 : pixel->data.gl.ui;
         Gan_GLAPixel_ui *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_gla_ui(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].I = val;
      }
      break;

      case GAN_FLOAT:
      {
         float val = (pixel == NULL) ? 0.0F : pixel->data.gl.f;
         Gan_GLAPixel_f *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_gla_f(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].I = val;
      }
      break;

      case GAN_DOUBLE:
      {
         double val = (pixel == NULL) ? 0.0 : pixel->data.gl.d;
         Gan_GLAPixel_d *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_gla_d(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].I = val;
      }
      break;

      default:
        gan_err_flush_trace();
        gan_err_register ( "gla_fill_intensity", GAN_ERROR_NOT_IMPLEMENTED,
                           "" );
        return GAN_FALSE;
   }

   /* success */
   return GAN_TRUE;
}

static Gan_Bool
 gla_fill_alpha ( Gan_Image *image, Gan_Pixel *pixel )
{
   int iRow, iCol;

   switch ( image->type )
   {
      case GAN_UCHAR:
      {
         unsigned char val = (pixel == NULL) ? 0 : pixel->data.gl.uc;
         Gan_GLAPixel_uc *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_gla_uc(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].A = val;
      }
      break;

      case GAN_USHORT:
      {
         unsigned short val = (pixel == NULL) ? 0 : pixel->data.gl.us;
         Gan_GLAPixel_us *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_gla_us(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].A = val;
      }
      break;

      case GAN_UINT:
      {
         unsigned int val = (pixel == NULL) ? 0 : pixel->data.gl.ui;
         Gan_GLAPixel_ui *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_gla_ui(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].A = val;
      }
      break;

      case GAN_FLOAT:
      {
         float val = (pixel == NULL) ? 0.0F : pixel->data.gl.f;
         Gan_GLAPixel_f *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_gla_f(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].A = val;
      }
      break;

      case GAN_DOUBLE:
      {
         double val = (pixel == NULL) ? 0.0 : pixel->data.gl.d;
         Gan_GLAPixel_d *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_gla_d(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].A = val;
      }
      break;

      default:
        gan_err_flush_trace();
        gan_err_register ( "gla_fill_alpha", GAN_ERROR_NOT_IMPLEMENTED,
                           "" );
        return GAN_FALSE;
   }

   /* success */
   return GAN_TRUE;
}

static Gan_Bool
 rgb_fill_red ( Gan_Image *image, Gan_Pixel *pixel )
{
   int iRow, iCol;

   switch ( image->type )
   {
      case GAN_UCHAR:
      {
         unsigned char val = (pixel == NULL) ? 0 : pixel->data.gl.uc;
         Gan_RGBPixel_uc *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgb_uc(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].R = val;
      }
      break;

      case GAN_USHORT:
      {
         unsigned short val = (pixel == NULL) ? 0 : pixel->data.gl.us;
         Gan_RGBPixel_us *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgb_us(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].R = val;
      }
      break;

      case GAN_UINT:
      {
         unsigned int val = (pixel == NULL) ? 0 : pixel->data.gl.ui;
         Gan_RGBPixel_ui *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgb_ui(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].R = val;
      }
      break;

      case GAN_FLOAT:
      {
         float val = (pixel == NULL) ? 0.0F : pixel->data.gl.f;
         Gan_RGBPixel_f *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgb_f(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].R = val;
      }
      break;

      case GAN_DOUBLE:
      {
         double val = (pixel == NULL) ? 0.0 : pixel->data.gl.d;
         Gan_RGBPixel_d *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgb_d(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].R = val;
      }
      break;

      default:
        gan_err_flush_trace();
        gan_err_register ( "rgb_fill_red", GAN_ERROR_NOT_IMPLEMENTED,
                           "" );
        return GAN_FALSE;
   }

   /* success */
   return GAN_TRUE;
}

static Gan_Bool
 rgb_fill_green ( Gan_Image *image, Gan_Pixel *pixel )
{
   int iRow, iCol;

   switch ( image->type )
   {
      case GAN_UCHAR:
      {
         unsigned char val = (pixel == NULL) ? 0 : pixel->data.gl.uc;
         Gan_RGBPixel_uc *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgb_uc(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].G = val;
      }
      break;

      case GAN_USHORT:
      {
         unsigned short val = (pixel == NULL) ? 0 : pixel->data.gl.us;
         Gan_RGBPixel_us *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgb_us(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].G = val;
      }
      break;

      case GAN_UINT:
      {
         unsigned int val = (pixel == NULL) ? 0 : pixel->data.gl.ui;
         Gan_RGBPixel_ui *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgb_ui(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].G = val;
      }
      break;

      case GAN_FLOAT:
      {
         float val = (pixel == NULL) ? 0.0F : pixel->data.gl.f;
         Gan_RGBPixel_f *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgb_f(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].G = val;
      }
      break;

      case GAN_DOUBLE:
      {
         double val = (pixel == NULL) ? 0.0 : pixel->data.gl.d;
         Gan_RGBPixel_d *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgb_d(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].G = val;
      }
      break;

      default:
        gan_err_flush_trace();
        gan_err_register ( "rgb_fill_green", GAN_ERROR_NOT_IMPLEMENTED,
                           "" );
        return GAN_FALSE;
   }

   /* success */
   return GAN_TRUE;
}

static Gan_Bool
 rgb_fill_blue ( Gan_Image *image, Gan_Pixel *pixel )
{
   int iRow, iCol;

   switch ( image->type )
   {
      case GAN_UCHAR:
      {
         unsigned char val = (pixel == NULL) ? 0 : pixel->data.gl.uc;
         Gan_RGBPixel_uc *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgb_uc(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].B = val;
      }
      break;

      case GAN_USHORT:
      {
         unsigned short val = (pixel == NULL) ? 0 : pixel->data.gl.us;
         Gan_RGBPixel_us *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgb_us(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].B = val;
      }
      break;

      case GAN_UINT:
      {
         unsigned int val = (pixel == NULL) ? 0 : pixel->data.gl.ui;
         Gan_RGBPixel_ui *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgb_ui(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].B = val;
      }
      break;

      case GAN_FLOAT:
      {
         float val = (pixel == NULL) ? 0.0F : pixel->data.gl.f;
         Gan_RGBPixel_f *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgb_f(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].B = val;
      }
      break;

      case GAN_DOUBLE:
      {
         double val = (pixel == NULL) ? 0.0 : pixel->data.gl.d;
         Gan_RGBPixel_d *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgb_d(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].B = val;
      }
      break;

      default:
        gan_err_flush_trace();
        gan_err_register ( "rgb_fill_blue", GAN_ERROR_NOT_IMPLEMENTED,
                           "" );
        return GAN_FALSE;
   }

   /* success */
   return GAN_TRUE;
}

static Gan_Bool
 rgba_fill_red ( Gan_Image *image, Gan_Pixel *pixel )
{
   int iRow, iCol;

   switch ( image->type )
   {
      case GAN_UCHAR:
      {
         unsigned char val = (pixel == NULL) ? 0 : pixel->data.gl.uc;
         Gan_RGBAPixel_uc *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_uc(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].R = val;
      }
      break;

      case GAN_USHORT:
      {
         unsigned short val = (pixel == NULL) ? 0 : pixel->data.gl.us;
         Gan_RGBAPixel_us *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_us(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].R = val;
      }
      break;

      case GAN_UINT:
      {
         unsigned int val = (pixel == NULL) ? 0 : pixel->data.gl.ui;
         Gan_RGBAPixel_ui *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_ui(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].R = val;
      }
      break;

      case GAN_FLOAT:
      {
         float val = (pixel == NULL) ? 0.0F : pixel->data.gl.f;
         Gan_RGBAPixel_f *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_f(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].R = val;
      }
      break;

      case GAN_DOUBLE:
      {
         double val = (pixel == NULL) ? 0.0 : pixel->data.gl.d;
         Gan_RGBAPixel_d *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_d(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].R = val;
      }
      break;

      default:
        gan_err_flush_trace();
        gan_err_register ( "rgba_fill_red", GAN_ERROR_NOT_IMPLEMENTED,
                           "" );
        return GAN_FALSE;
   }

   /* success */
   return GAN_TRUE;
}

static Gan_Bool
 rgba_fill_green ( Gan_Image *image, Gan_Pixel *pixel )
{
   int iRow, iCol;

   switch ( image->type )
   {
      case GAN_UCHAR:
      {
         unsigned char val = (pixel == NULL) ? 0 : pixel->data.gl.uc;
         Gan_RGBAPixel_uc *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_uc(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].G = val;
      }
      break;

      case GAN_USHORT:
      {
         unsigned short val = (pixel == NULL) ? 0 : pixel->data.gl.us;
         Gan_RGBAPixel_us *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_us(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].G = val;
      }
      break;

      case GAN_UINT:
      {
         unsigned int val = (pixel == NULL) ? 0 : pixel->data.gl.ui;
         Gan_RGBAPixel_ui *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_ui(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].G = val;
      }
      break;

      case GAN_FLOAT:
      {
         float val = (pixel == NULL) ? 0.0F : pixel->data.gl.f;
         Gan_RGBAPixel_f *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_f(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].G = val;
      }
      break;

      case GAN_DOUBLE:
      {
         double val = (pixel == NULL) ? 0.0 : pixel->data.gl.d;
         Gan_RGBAPixel_d *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_d(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].G = val;
      }
      break;

      default:
        gan_err_flush_trace();
        gan_err_register ( "rgba_fill_green", GAN_ERROR_NOT_IMPLEMENTED,
                           "" );
        return GAN_FALSE;
   }

   /* success */
   return GAN_TRUE;
}

static Gan_Bool
 rgba_fill_blue ( Gan_Image *image, Gan_Pixel *pixel )
{
   int iRow, iCol;

   switch ( image->type )
   {
      case GAN_UCHAR:
      {
         unsigned char val = (pixel == NULL) ? 0 : pixel->data.gl.uc;
         Gan_RGBAPixel_uc *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_uc(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].B = val;
      }
      break;

      case GAN_USHORT:
      {
         unsigned short val = (pixel == NULL) ? 0 : pixel->data.gl.us;
         Gan_RGBAPixel_us *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_us(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].B = val;
      }
      break;

      case GAN_UINT:
      {
         unsigned int val = (pixel == NULL) ? 0 : pixel->data.gl.ui;
         Gan_RGBAPixel_ui *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_ui(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].B = val;
      }
      break;

      case GAN_FLOAT:
      {
         float val = (pixel == NULL) ? 0.0F : pixel->data.gl.f;
         Gan_RGBAPixel_f *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_f(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].B = val;
      }
      break;

      case GAN_DOUBLE:
      {
         double val = (pixel == NULL) ? 0.0 : pixel->data.gl.d;
         Gan_RGBAPixel_d *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_d(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].B = val;
      }
      break;

      default:
        gan_err_flush_trace();
        gan_err_register ( "rgba_fill_blue", GAN_ERROR_NOT_IMPLEMENTED,
                           "" );
        return GAN_FALSE;
   }

   /* success */
   return GAN_TRUE;
}

static Gan_Bool
 rgba_fill_alpha ( Gan_Image *image, Gan_Pixel *pixel )
{
   int iRow, iCol;

   switch ( image->type )
   {
      case GAN_UCHAR:
      {
         unsigned char val = (pixel == NULL) ? 0 : pixel->data.gl.uc;
         Gan_RGBAPixel_uc *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_uc(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].A = val;
      }
      break;

      case GAN_USHORT:
      {
         unsigned short val = (pixel == NULL) ? 0 : pixel->data.gl.us;
         Gan_RGBAPixel_us *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_us(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].A = val;
      }
      break;

      case GAN_UINT:
      {
         unsigned int val = (pixel == NULL) ? 0 : pixel->data.gl.ui;
         Gan_RGBAPixel_ui *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_ui(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].A = val;
      }
      break;

      case GAN_FLOAT:
      {
         float val = (pixel == NULL) ? 0.0F : pixel->data.gl.f;
         Gan_RGBAPixel_f *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_f(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].A = val;
      }
      break;

      case GAN_DOUBLE:
      {
         double val = (pixel == NULL) ? 0.0 : pixel->data.gl.d;
         Gan_RGBAPixel_d *pix;

         for ( iRow = (int)image->height-1; iRow >= 0; iRow-- )
            for ( pix = gan_image_get_pixptr_rgba_d(image,iRow,0),
                  iCol = (int)image->width-1; iCol >= 0; iCol-- )
               pix[iCol].A = val;
      }
      break;

      default:
        gan_err_flush_trace();
        gan_err_register ( "rgba_fill_alpha", GAN_ERROR_NOT_IMPLEMENTED,
                           "" );
        return GAN_FALSE;
   }

   /* success */
   return GAN_TRUE;
}

/**
 * \brief Sets a single channel of an image to a constant value.
 * \param image The input image
 * \param channel The channel to set to constant value
 * \param pixel Pointer to grey-level pixel value
 * \return #GAN_TRUE on success, #GAN_FALSE on failure.
 *
 * Sets a single channel of an \a image to a constant value. The \a channel
 * should correspond to one of the available channels in the \a image.
 * The type of the \a pixel structure should be the same as the \a image,
 * and the format should be #GAN_GREY_LEVEL_IMAGE. If \a pixel is passed as
 * \c NULL, the channel is filled with zeros.
 *
 * \sa gan_image_fill_channel_zero().
 */
Gan_Bool
02016  gan_image_fill_channel_const ( Gan_Image *image,
                                Gan_ImageChannelType channel,
                                Gan_Pixel *pixel )
{
   Gan_Bool bResult;

   gan_err_test_bool ( pixel == NULL ||
                       (pixel->format == GAN_GREY_LEVEL_IMAGE &&
                        pixel->type == image->type),
                       "gan_image_fill_channel_const", GAN_ERROR_INCOMPATIBLE,
                       "" );
   
   switch ( image->format )
   {
      case GAN_GREY_LEVEL_IMAGE:
        switch ( channel )
        {
           case GAN_INTENSITY_CHANNEL:
             bResult = gan_image_fill_const ( image, pixel );
             break;

           default:
             gan_err_flush_trace();
             gan_err_register ( "gan_image_fill_channel_const",
                                GAN_ERROR_ILLEGAL_TYPE, "" );
             return GAN_FALSE;
        }
        break;

      case GAN_GREY_LEVEL_ALPHA_IMAGE:
        switch ( channel )
        {
           case GAN_INTENSITY_CHANNEL:
             bResult = gla_fill_intensity ( image, pixel );
             break;

           case GAN_ALPHA_CHANNEL:
             bResult = gla_fill_alpha ( image, pixel );
             break;

           default:
             gan_err_flush_trace();
             gan_err_register ( "gan_image_fill_channel_const",
                                GAN_ERROR_ILLEGAL_TYPE, "" );
             return GAN_FALSE;
        }
        break;

      case GAN_RGB_COLOUR_IMAGE:
        switch ( channel )
        {
           case GAN_RED_CHANNEL:
             bResult = rgb_fill_red ( image, pixel );
             break;

           case GAN_GREEN_CHANNEL:
             bResult = rgb_fill_green ( image, pixel );
             break;

           case GAN_BLUE_CHANNEL:
             bResult = rgb_fill_blue ( image, pixel );
             break;

           default:
             gan_err_flush_trace();
             gan_err_register ( "gan_image_fill_channel_const",
                                GAN_ERROR_ILLEGAL_TYPE, "" );
             return GAN_FALSE;
        }
        break;

      case GAN_RGB_COLOUR_ALPHA_IMAGE:
        switch ( channel )
        {
           case GAN_RED_CHANNEL:
             bResult = rgba_fill_red ( image, pixel );
             break;

           case GAN_GREEN_CHANNEL:
             bResult = rgba_fill_green ( image, pixel );
             break;

           case GAN_BLUE_CHANNEL:
             bResult = rgba_fill_blue ( image, pixel );
             break;

           case GAN_ALPHA_CHANNEL:
             bResult = rgba_fill_alpha ( image, pixel );
             break;

           default:
             gan_err_flush_trace();
             gan_err_register ( "gan_image_fill_channel_const",
                                GAN_ERROR_ILLEGAL_TYPE, "" );
             return GAN_FALSE;
        }
        break;

      default:
        gan_err_flush_trace();
        gan_err_register ( "gan_image_fill_channel_const",
                           GAN_ERROR_ILLEGAL_TYPE, "" );
        return GAN_FALSE;
   }
                                          
   if ( !bResult )
   {
      gan_err_register ( "gan_image_fill_channel_const", GAN_ERROR_FAILURE,
                         "" );
      return GAN_FALSE;
   }

   /* success */
   return GAN_TRUE;
}

/**
 * \}
 */

/**
 * \}
 */

Generated by  Doxygen 1.6.0   Back to index