/* Copy an image. 
 *
 * Copyright: 1990, N. Dessipris, based on im_powtra()
 * Author: Nicos Dessipris
 * Written on: 02/05/1990
 * Modified on: 
 * 23/4/93 J.Cupitt
 *	- adapted to work with partial images
 * 30/6/93 JC
 *	- adapted for partial v2
 *	- and ANSI C
 * 7/7/93 JC
 *	- now does IM_CODING_LABQ too
 * 22/2/95 JC
 *	- new use of im_region_region()
 * 25/6/02 JC
 *	- added im_copy_set()
 *	- hint is IM_ANY
 * 5/9/02 JC
 *	- added xoff/yoff to copy_set
 * 14/4/04 JC
 *	- im_copy() now zeros Xoffset/Yoffset (since origin is the same as
 *	  input)
 * 26/5/04 JC
 *	- added im_copy_swap()
 * 1/6/05
 *	- added im_copy_morph()
 * 13/6/05
 *	- oop, im_copy_set() was messed up
 * 29/9/06
 * 	- added im_copy_set_meta(), handy wrapper for nip2 to set meta fields
 * 2/11/06
 * 	- moved im__convert_saveable() here so it's always defined (was part
 * 	  of JPEG write code)
 * 15/2/08
 * 	- added im__saveable_t ... so we can have CMYK JPEG write
 * 24/3/09
 * 	- added IM_CODING_RAD support
 * 28/1/10
 * 	- gtk-doc
 * 	- cleanups
 * 	- removed im_copy_from() and associated stuff
 * 	- added im_copy_native()
 */

/*

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

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

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

 */

/*

    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk

 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include <vips/vips.h>
#include <vips/internal.h>

#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/

/* Copy a small area.
 */
static int
copy_gen( REGION *or, void *seq, void *a, void *b )
{
	REGION *ir = (REGION *) seq;
	Rect *r = &or->valid;

	/* Ask for input we need.
	 */
	if( im_prepare( ir, r ) )
		return( -1 );

	/* Attach output region to that.
	 */
	if( im_region_region( or, ir, r, r->left, r->top ) )
		return( -1 );

	return( 0 );
}

/* Copy image, changing header fields.
 */
static int 
im_copy_set_all( IMAGE *in, IMAGE *out, 
	VipsType type, float xres, float yres, int xoffset, int yoffset,
	int bands, VipsBandFmt bandfmt, VipsCoding coding )
{	
	/* Check args.
	 */
        if( im_check_coding_known( "im_copy", in ) ||
		im_piocheck( in, out ) )
		return( -1 );
	if( coding != IM_CODING_NONE && 
		coding != IM_CODING_LABQ &&
		coding != IM_CODING_RAD ) {
		im_error( "im_copy", "%s", 
			_( "coding must be NONE, LABQ or RAD" ) );
		return( -1 );
	}
	if( bandfmt < 0 || bandfmt > IM_BANDFMT_DPCOMPLEX ) {
		im_error( "im_copy", _( "bandfmt must be in range [0,%d]" ),
			IM_BANDFMT_DPCOMPLEX );
		return( -1 );
	}

	if( im_cp_desc( out, in ) )
		return( -1 );
	out->Type = type;
	out->Xres = xres;
	out->Yres = yres;
	out->Xoffset = xoffset;
	out->Yoffset = yoffset;
	out->Bands = bands;
	out->BandFmt = bandfmt;
	out->Coding = coding;

	/* Sanity check: we (may) have changed bytes-per-pixel since we've
	 * changed Bands and BandFmt ... bad!
	 */
	if( IM_IMAGE_SIZEOF_PEL( in ) != IM_IMAGE_SIZEOF_PEL( out ) ) {
		im_error( "im_copy", "%s", _( "sizeof( pixel ) has changed" ) );
		return( -1 );
	}

	/* Generate!
	 */
	if( im_demand_hint( out, IM_THINSTRIP, in, NULL ) ||
		im_generate( out, 
			im_start_one, copy_gen, im_stop_one, in, NULL ) )
		return( -1 );

	return( 0 );
}

/**
 * im_copy:
 * @in: input image
 * @out: output image
 *
 * Copy an image. VIPS copies images by copying pointers, so this operation is
 * fast, even for very large images.
 *
 * See also: im_copy(), im_copy_set(), im_copy_morph().
 *
 * Returns: 0 on success, -1 on error.
 */
int 
im_copy( IMAGE *in, IMAGE *out )
{
	return( im_copy_set( in, out, 
		in->Type, in->Xres, in->Yres, 0, 0 ) );
}

/**
 * im_copy_set:
 * @in: input image
 * @out: output image
 * @type: new VipsType to set
 * @xres: new Xres to set
 * @yres: new Yres to set
 * @xoffset: new Xoffset to set
 * @yoffset: new Yoffset to set
 *
 * Copy an image, changing informational header fields on the way.
 *
 * See also: im_copy().
 *
 * Returns: 0 on success, -1 on error.
 */
int 
im_copy_set( IMAGE *in, IMAGE *out, 
	VipsType type, float xres, float yres, int xoffset, int yoffset )
{
	return( im_copy_set_all( in, out, 
		type, xres, yres, 0, 0,
		in->Bands, in->BandFmt, in->Coding ) );
}

/**
 * im_copy_morph:
 * @in: input image
 * @out: output image
 * @bands: new number of bands
 * @bandfmt: new band format
 * @coding: new coding
 *
 * Copy an image, changing header fields which alter pixel addressing. The
 * pixel data itself is unchanged, this operation just changes the header
 * fields. 
 *
 * If you change the header fields such that the sizeof() a pixel changes,
 * you'll get an error.
 *
 * See also: im_copy().
 *
 * Returns: 0 on success, -1 on error.
 */
int 
im_copy_morph( IMAGE *in, IMAGE *out, 
	int bands, VipsBandFmt bandfmt, VipsCoding coding )
{
	return( im_copy_set_all( in, out, 
		in->Type, in->Xres, in->Yres, 0, 0,
		bands, bandfmt, coding ) );
}

/**
 * im_copy_set_meta:
 * @in: input image
 * @out: output image
 * @field: metadata field to set
 * @value: value to set for the field
 *
 * Copy an image, changing a metadata field. You can use this to, for example,
 * update the ICC profile attached to an image.
 *
 * See also: im_copy().
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_copy_set_meta( IMAGE *in, IMAGE *out, const char *field, GValue *value )
{
	if( im_copy( in, out ) ||
		im_meta_set( out, field, value ) )
		return( 1 );

	return( 0 );
}

/* Swap pairs of bytes.
 */
static void
im_copy_swap2_gen( PEL *in, PEL *out, int width, IMAGE *im )
{       
        int x;
        int sz = IM_IMAGE_SIZEOF_PEL( im ) * width;     /* Bytes in buffer */

        for( x = 0; x < sz; x += 2 ) {
                out[x] = in[x + 1];
                out[x + 1] = in[x];
        }
}

/* Swap 4- of bytes.
 */
static void
im_copy_swap4_gen( PEL *in, PEL *out, int width, IMAGE *im )
{
        int x;
        int sz = IM_IMAGE_SIZEOF_PEL( im ) * width;     /* Bytes in buffer */

        for( x = 0; x < sz; x += 4 ) {
                out[x] = in[x + 3];
                out[x + 1] = in[x + 2];
                out[x + 2] = in[x + 1];
                out[x + 3] = in[x];
        }
}

/* Swap 8- of bytes.
 */
static void
im_copy_swap8_gen( PEL *in, PEL *out, int width, IMAGE *im )
{
        int x;
        int sz = IM_IMAGE_SIZEOF_PEL( im ) * width;     /* Bytes in buffer */

        for( x = 0; x < sz; x += 8 ) {
                out[x] = in[x + 7];
                out[x + 1] = in[x + 6];
                out[x + 2] = in[x + 5];
                out[x + 3] = in[x + 4];
                out[x + 4] = in[x + 3];
                out[x + 5] = in[x + 2];
                out[x + 6] = in[x + 1];
                out[x + 7] = in[x];
        }
}

/**
 * im_copy_swap:
 * @in: input image
 * @out: output image
 *
 * Copy an image, swapping byte order between little and big endian. This
 * really does change image pixels and does not just alter the header.
 *
 * See also: im_copy(), im_amiMSBfirst(), im_isMSBfirst().
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_copy_swap( IMAGE *in, IMAGE *out )
{
        if( im_piocheck( in, out ) ||
		im_check_uncoded( "im_copy_swap", in ) ||
		im_cp_desc( out, in ) )
                return( -1 );

	switch( in->BandFmt ) {
        case IM_BANDFMT_CHAR:
        case IM_BANDFMT_UCHAR:
		if( im_copy( in, out ) ) 
			return( -1 );
		break;

        case IM_BANDFMT_SHORT:
        case IM_BANDFMT_USHORT:
		if( im_wrapone( in, out, 
			(im_wrapone_fn) im_copy_swap2_gen, in, NULL ) )
			return( -1 );
		break;

	case IM_BANDFMT_INT:
	case IM_BANDFMT_UINT:
	case IM_BANDFMT_FLOAT:
	case IM_BANDFMT_COMPLEX:
		if( im_wrapone( in, out, 
			(im_wrapone_fn) im_copy_swap4_gen, in, NULL ) )
			return( -1 );
		break;

        case IM_BANDFMT_DOUBLE:
        case IM_BANDFMT_DPCOMPLEX:
		if( im_wrapone( in, out, 
			(im_wrapone_fn) im_copy_swap8_gen, in, NULL ) )
			return( -1 );
		break;

	default:
		im_error( "im_copy_swap", "%s", _( "unsupported image type" ) );
		return( -1 );
	}

	return( 0 );
}

/**
 * im_copy_native:
 * @in: input image
 * @out: output image
 * @is_msb_first: %TRUE if @in is in most-significant first form
 *
 * Copy an image to native order, that is, the order for the executing
 * program.
 *
 * See also: im_copy_swap(), im_amiMSBfirst().
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_copy_native( IMAGE *in, IMAGE *out, gboolean is_msb_first )
{
	if( is_msb_first != im_amiMSBfirst() )
		return( im_copy_swap( in, out ) );
	else
		return( im_copy( in, out ) );
}

/* Convert to a saveable format. 
 *
 * im__saveable_t gives the general type of image
 * we make: vanilla 1/3 bands (eg. PPM), with an optional alpha (eg. PNG), or
 * with CMYK as an option (eg. JPEG). 
 *
 * format_table[] says how to convert each input format. 
 *
 * Need to im_close() the result IMAGE.
 */
IMAGE *
im__convert_saveable( IMAGE *in, 
	im__saveable_t saveable, int format_table[10] ) 
{
	IMAGE *out;

	if( !(out = im_open( "convert-for-save", "p" )) )
		return( NULL );

	/* If this is an IM_CODING_LABQ, we can go straight to RGB.
	 */
	if( in->Coding == IM_CODING_LABQ ) {
		IMAGE *t = im_open_local( out, "conv:1", "p" );
		static void *table = NULL;

		/* Make sure fast LabQ2disp tables are built. 7 is sRGB.
		 */
		if( !table ) 
			table = im_LabQ2disp_build_table( NULL, 
				im_col_displays( 7 ) );

		if( !t || im_LabQ2disp_table( in, t, table ) ) {
			im_close( out );
			return( NULL );
		}

		in = t;
	}

	/* If this is an IM_CODING_RAD, we go to float RGB or XYZ. We should
	 * probably un-gamma-correct the RGB :(
	 */
	if( in->Coding == IM_CODING_RAD ) {
		IMAGE *t;

		if( !(t = im_open_local( out, "conv:1", "p" )) || 
			im_rad2float( in, t ) ) {
			im_close( out );
			return( NULL );
		}

		in = t;
	}

	/* Get the bands right. 
	 */
	if( in->Coding == IM_CODING_NONE ) {
		if( in->Bands == 2 && saveable != IM__RGBA ) {
			IMAGE *t = im_open_local( out, "conv:1", "p" );

			if( !t || im_extract_band( in, t, 0 ) ) {
				im_close( out );
				return( NULL );
			}

			in = t;
		}
		else if( in->Bands > 3 && saveable == IM__RGB ) {
			IMAGE *t = im_open_local( out, "conv:1", "p" );

			if( !t ||
				im_extract_bands( in, t, 0, 3 ) ) {
				im_close( out );
				return( NULL );
			}

			in = t;
		}
		else if( in->Bands > 4 && 
			(saveable == IM__RGB_CMYK || saveable == IM__RGBA) ) {
			IMAGE *t = im_open_local( out, "conv:1", "p" );

			if( !t ||
				im_extract_bands( in, t, 0, 4 ) ) {
				im_close( out );
				return( NULL );
			}

			in = t;
		}

		/* Else we have saveable IM__ANY and we don't chop bands down.
		 */
	}

	/* Interpret the Type field for colorimetric images.
	 */
	if( in->Bands == 3 && in->BandFmt == IM_BANDFMT_SHORT && 
		in->Type == IM_TYPE_LABS ) {
		IMAGE *t = im_open_local( out, "conv:1", "p" );

		if( !t || im_LabS2LabQ( in, t ) ) {
			im_close( out );
			return( NULL );
		}

		in = t;
	}

	if( in->Coding == IM_CODING_LABQ ) {
		IMAGE *t = im_open_local( out, "conv:1", "p" );

		if( !t || im_LabQ2Lab( in, t ) ) {
			im_close( out );
			return( NULL );
		}

		in = t;
	}

	if( in->Coding != IM_CODING_NONE ) {
		im_close( out );
		return( NULL );
	}

	if( in->Bands == 3 && in->Type == IM_TYPE_LCH ) {
		IMAGE *t[2];

                if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
			im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
			im_LCh2Lab( t[0], t[1] ) ) {
			im_close( out );
			return( NULL );
		}

		in = t[1];
	}

	if( in->Bands == 3 && in->Type == IM_TYPE_YXY ) {
		IMAGE *t[2];

                if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
			im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
			im_Yxy2XYZ( t[0], t[1] ) ) {
			im_close( out );
			return( NULL );
		}

		in = t[1];
	}

	if( in->Bands == 3 && in->Type == IM_TYPE_UCS ) {
		IMAGE *t[2];

                if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
			im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
			im_UCS2XYZ( t[0], t[1] ) ) {
			im_close( out );
			return( NULL );
		}

		in = t[1];
	}

	if( in->Bands == 3 && in->Type == IM_TYPE_LAB ) {
		IMAGE *t[2];

                if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
			im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
			im_Lab2XYZ( t[0], t[1] ) ) {
			im_close( out );
			return( NULL );
		}

		in = t[1];
	}

	if( in->Bands == 3 && in->Type == IM_TYPE_XYZ ) {
		IMAGE *t[2];

                if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
			im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
			im_XYZ2disp( t[0], t[1], im_col_displays( 7 ) ) ) {
			im_close( out );
			return( NULL );
		}

		in = t[1];
	}

	/* Cast to the output format.
	 */
	{
		IMAGE *t = im_open_local( out, "conv:1", "p" );

		if( !t || im_clip2fmt( in, t, format_table[in->BandFmt] ) ) {
			im_close( out );
			return( NULL );
		}

		in = t;
	}

	if( im_copy( in, out ) ) {
		im_close( out );
		return( NULL );
	}

	return( out );
}
