// Object part of VMask class

/*

    Copyright (C) 1991-2001 The National Gallery

    This program 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 <cstdlib>
#include <cmath>

#include <vips/vips.h>

#include <vips/vipscpp.h>

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

VIPS_NAMESPACE_START

/* Functions for VMask - refcounting layer over VPMask.
 */

VMask::~VMask()
{
	ref->nrefs--;
	if( !ref->nrefs )
		delete ref;
}

VMask &VMask::operator=( const VMask &a )
{ 
	// Loosing ref to LHS
	ref->nrefs--;

	if( ref->nrefs > 0 )
		// Need fresh refblock
		ref = new refblock;
	else 
		// Recycle old refblock
		delete ref->pmask;

	// LHS now points to RHS
	ref = a.ref; 
	ref->nrefs++; 
	
	return( *this ); 
}

// Make sure this is a private copy of pmask --- dup if nrefs != 1
void VMask::make_private()
{
	if( ref->nrefs > 1 ) {
		// Make fresh refblock
		refblock *ref2 = new refblock;

		// And copy the mask
		ref2->pmask = ref->pmask->dup();
		ref->nrefs--;
		ref = ref2;
	}
}

void VMask::ostream_print( std::ostream &file ) const
{
	file << *(ref->pmask);
}

// Embed INTMASK in VIMask
void VIMask::embed( INTMASK *i ) throw( VError )
{
	if( ref->pmask )
		verror( "embed: VIMask not empty" );
	ref->pmask = new _private_detail::VPIMask( i );
}

// Type conversions: implicit INTMASK to DOUBLEMASK 
VIMask::operator VDMask()
{
	VDMask out( xsize(), ysize() );

	out.mask().dptr->scale = scale();
	out.mask().dptr->offset = offset();

	for( int i = 0; i < size(); i++ )
		out[i] = (*this)[i];

	return( out );
}


// Forward ref of VImage class
class VImage;

// Type conversions: implicit DOUBLEMASK to INTMASK
VDMask::operator VIMask()
{
	VIMask out( xsize(), ysize() );

	out.mask().iptr->scale = int( scale() );
	out.mask().iptr->offset = int( offset() );

	for( int i = 0; i < size(); i++ )
		out[i] = (int) rint( (*this)[i] );

	return( out );
}

// Type conversions: implicit DOUBLEMASK to VImage
VDMask::operator VImage() throw( VError )
{
	VImage out;

	if( im_mask2vips( mask().dptr, out.image() ) )
		verror();

	return( out );
}

// ... and INTMASK to VImage
VIMask::operator VImage() { return( VImage( VDMask( *this ) ) ); }

// Embed DOUBLEMASK in VDMask
void VDMask::embed( DOUBLEMASK *i ) throw( VError )
{
	if( ref->pmask )
		verror( "embed: VDMask not empty" );
	ref->pmask = new _private_detail::VPDMask( i );
}

/* Functions for P*Mask - layer over im_*_*mask() functions.
 */

// Create empty imask
_private_detail::VPIMask::VPIMask( int xsize, int ysize ) throw( VError )
{
	if( !(data.iptr = im_create_imask( "VPIMask::VPIMask", xsize, ysize )) )
		verror();
	type = _private_detail::VPMask::INT;
}

// Init from vector
_private_detail::VPIMask::VPIMask( int xsize, int ysize, 
	int scale, int offset, std::vector<int> coeff )
	throw( VError )
{
	int i;

	if( !(data.iptr = im_create_imask( "VPIMask::VPIMask", xsize, ysize )) )
		verror();
	type = _private_detail::VPMask::INT;

	data.iptr->scale = scale;
	data.iptr->offset = offset;
	for( i = 0; i < xsize * ysize; i++ )
		data.iptr->coeff[i] = coeff[i];
}

// Create from filename
_private_detail::VPIMask::VPIMask( const char *name ) throw( VError )
{
	if( !(data.iptr = im_read_imask( (char *) name )) )
		verror();
	type = _private_detail::VPMask::INT;
}

// Create from existing INTMASK
_private_detail::VPIMask::VPIMask( INTMASK *imask )
{
	data.iptr = imask;
	type = _private_detail::VPMask::INT;
}

// Create empty
_private_detail::VPIMask::VPIMask()
{
	data.iptr = 0;
	type = _private_detail::VPMask::UNASSIGNED;
}

_private_detail::VPIMask::~VPIMask()
{
	if( data.iptr ) {
		im_free_imask( data.iptr );
		data.iptr = 0;
		type = _private_detail::VPMask::UNASSIGNED;
	}
}

// Duplicate -- we are a VPIMask, return a new VPIMask which is a copy of us.
// Return as a VPMask tho'.
_private_detail::VPMask *_private_detail::VPIMask::dup() const throw( VError )
{
	_private_detail::VPIMask *out = new _private_detail::VPIMask();

	INTMASK *msk;
	if( !(msk = im_dup_imask( data.iptr, "VPIMask::dup" )) ) {
		delete out;
		verror();
	}
	out->embed( msk );

	return( out );
}

// Insert INTMASK pointer
void _private_detail::VPIMask::embed( INTMASK *msk ) throw( VError )
{
	if( type != _private_detail::VPMask::UNASSIGNED )
		verror( "VPIMask::embed: VPIMask not empty" );

	data.iptr = msk;
	type = _private_detail::VPMask::INT;
}

int _private_detail::VPIMask::xsize() const throw( VError )
{
	if( !data.iptr ) 
		verror( "xsize: mask not set" );

	return( data.iptr->xsize );
}

int _private_detail::VPIMask::ysize() const throw( VError )
{
	if( !data.iptr ) 
		verror( "ysize: mask not set" );

	return( data.iptr->ysize );
}

int _private_detail::VPIMask::scale() const throw( VError )
{
	if( !data.iptr ) 
		verror( "scale: mask not set" );

	return( data.iptr->scale );
}

int _private_detail::VPIMask::offset() const throw( VError )
{
	if( !data.iptr ) 
		verror( "offset: mask not set" );

	return( data.iptr->offset );
}

const char *_private_detail::VPIMask::filename() const throw( VError )
{
	if( !data.iptr ) 
		verror( "filename: mask not set" );

	return( data.iptr->filename );
}

void _private_detail::VPIMask::ostream_print( std::ostream &file ) const 
	throw( VError )
{
	if( !data.iptr )
		verror( "internal error #7447234" );
	
	int i, j;
	int *p = data.iptr->coeff;

	file << this->xsize() << "\t" << this->ysize() << "\t";
	file << this->scale() << "\t" << this->offset() << "\n";

	for( i = 0; i < this->ysize(); i++ ) {
		for( j = 0; j < this->xsize(); j++ )
			file << *p++ << "\t";

		file << "\n";
	}
}

// Extract start of int array
int *_private_detail::VPIMask::array() const 
{ 
	return( data.iptr->coeff ); 
}

// Create empty dmask
_private_detail::VPDMask::VPDMask( int xsize, int ysize ) throw( VError )
{
	if( !(data.dptr = im_create_dmask( "VPDMask::VPDMask", xsize, ysize )) )
		verror();
	type = _private_detail::VPMask::DOUBLE;
}

// Create from vector
_private_detail::VPDMask::VPDMask( int xsize, int ysize, 
	double scale, double offset, std::vector<double> coeff ) throw( VError )
{
	int i;

	if( !(data.dptr = im_create_dmask( "VPDMask::VPDMask", xsize, ysize )) )
		verror();
	type = _private_detail::VPMask::DOUBLE;

	data.dptr->scale = scale;
	data.dptr->offset = offset;
	for( i = 0; i < xsize * ysize; i++ )
		data.dptr->coeff[i] = coeff[i];
}

// Create from filename
_private_detail::VPDMask::VPDMask( const char *name ) throw( VError )
{
	if( !(data.dptr = im_read_dmask( (char *) name )) )
		verror();
	type = _private_detail::VPMask::DOUBLE;
}

// Create empty
_private_detail::VPDMask::VPDMask()
{
	data.dptr = 0;
	type = _private_detail::VPMask::UNASSIGNED;
}

// Create from existing DOUBLEMASK
_private_detail::VPDMask::VPDMask( DOUBLEMASK *dmask )
{
	data.dptr = dmask;
	type = _private_detail::VPMask::DOUBLE;
}

_private_detail::VPDMask::~VPDMask()
{
	if( data.dptr ) {
		im_free_dmask( data.dptr );
		data.dptr = 0;
		type = _private_detail::VPMask::UNASSIGNED;
	}
}

// Duplicate -- we are a VPIMask, return a new VPIMask which is a copy of us.
// Return as a VPMask tho'.
_private_detail::VPMask *_private_detail::VPDMask::dup() const throw( VError )
{
	_private_detail::VPDMask *out = new _private_detail::VPDMask();

	DOUBLEMASK *msk;
	if( !(msk = im_dup_dmask( data.dptr, "VPDMask::dup" )) ) {
		delete out;
		verror();
	}
	out->embed( msk );

	return( out );
}

// Insert DOUBLEMASK pointer
void _private_detail::VPDMask::embed( DOUBLEMASK *msk ) throw( VError )
{
	if( type != _private_detail::VPMask::UNASSIGNED )
		verror( "VPDMask::embed: VPDMask not empty" );

	data.dptr = msk;
	type = _private_detail::VPMask::DOUBLE;
}

int _private_detail::VPDMask::xsize() const throw( VError )
{
	if( !data.dptr ) 
		verror( "xsize: mask not set" );

	return( data.dptr->xsize );
}

int _private_detail::VPDMask::ysize() const throw( VError )
{
	if( !data.dptr ) 
		verror( "ysize: mask not set" );

	return( data.dptr->ysize );
}

double _private_detail::VPDMask::scale() const throw( VError )
{
	if( !data.dptr ) 
		verror( "scale: mask not set" );

	return( data.dptr->scale );
}

double _private_detail::VPDMask::offset() const throw( VError )
{
	if( !data.dptr ) 
		verror( "offset: mask not set" );

	return( data.dptr->offset );
}

const char *_private_detail::VPDMask::filename() const throw( VError )
{
	if( !data.dptr ) 
		verror( "filename: mask not set" );

	return( data.dptr->filename );
}

void _private_detail::VPDMask::ostream_print( std::ostream &file ) const 
	throw( VError )
{
	if( !data.dptr )
		verror( "internal error #7447234" );
	
	int i, j;
	double *p = data.dptr->coeff;

	file << this->xsize() << "\t" << this->ysize() << "\t";
	file << this->scale() << "\t" << this->offset() << "\n";

	for( i = 0; i < this->ysize(); i++ ) {
		for( j = 0; j < this->xsize(); j++ )
			file << *p++ << "\t";

		file << "\n";
	}
}

// Extract data pointer
double *_private_detail::VPDMask::array() const 
{ 
	return( data.dptr->coeff ); 
}

// Build functions
VIMask VIMask::gauss( double sig, double minamp ) throw( VError )
{
	VIMask out;
	INTMASK *msk;

	if( !(msk = im_gauss_imask( "VIMask::gauss", sig, minamp )) )
		verror();
	out.embed( msk );

	return( out );
}

VIMask VIMask::gauss_sep( double sig, double minamp ) throw( VError )
{
	VIMask out;
	INTMASK *msk;

	if( !(msk = im_gauss_imask_sep( "VIMask::gauss", sig, minamp )) )
		verror();
	out.embed( msk );

	return( out );
}

VDMask VDMask::gauss( double sig, double minamp ) throw( VError )
{
	VDMask out;
	DOUBLEMASK *msk;

	if( !(msk = im_gauss_dmask( "VDMask::gauss", sig, minamp )) )
		verror();
	out.embed( msk );

	return( out );
}

VIMask VIMask::log( double sig, double minamp ) throw( VError )
{
	VIMask out;
	INTMASK *msk;

	if( !(msk = im_log_imask( "VIMask::log", sig, minamp )) )
		verror();
	out.embed( msk );

	return( out );
}

VDMask VDMask::log( double sig, double minamp ) throw( VError )
{
	VDMask out;
	DOUBLEMASK *msk;

	if( !(msk = im_log_dmask( "VDMask::log", sig, minamp )) )
		verror();
	out.embed( msk );

	return( out );
}

// Manipulation functions
VIMask VIMask::rotate45() throw( VError )
{
	VIMask out;
	INTMASK *msk;

	if( !(msk = im_rotate_imask45( mask().iptr, "VIMask::rotate45" )) )
		verror();
	out.embed( msk );

	return( out );
}

VIMask VIMask::rotate90() throw( VError )
{
	VIMask out;
	INTMASK *msk;

	if( !(msk = im_rotate_imask90( mask().iptr, "VIMask::rotate90" )) )
		verror();
	out.embed( msk );

	return( out );
}

VDMask VDMask::rotate45() throw( VError )
{
	VDMask out;
	DOUBLEMASK *msk;

	if( !(msk = im_rotate_dmask45( mask().dptr, "VDMask::rotate45" )) )
		verror();
	out.embed( msk );

	return( out );
}

VDMask VDMask::rotate90() throw( VError )
{
	VDMask out;
	DOUBLEMASK *msk;

	if( !(msk = im_rotate_dmask90( mask().dptr, "VDMask::rotate90" )) )
		verror();
	out.embed( msk );

	return( out );
}

VDMask VDMask::trn() throw( VError )
{
	VDMask out;
	DOUBLEMASK *msk;

	if( !(msk = im_mattrn( mask().dptr, "VDMask::trn" )) )
		verror();
	out.embed( msk );

	return( out );
}

VDMask VDMask::inv() throw( VError )
{
	VDMask out;
	DOUBLEMASK *msk;

	if( !(msk = im_matinv( mask().dptr, "VDMask::inv" )) )
		verror();
	out.embed( msk );

	return( out );
}

VDMask VDMask::mul( VDMask m ) throw( VError )
{
	VDMask out;
	DOUBLEMASK *msk;

	if( !(msk = im_matmul( mask().dptr, m.mask().dptr, "VDMask::mul" )) )
		verror();
	out.embed( msk );

	return( out );
}

VDMask VDMask::cat( VDMask m ) throw( VError )
{
	VDMask out;
	DOUBLEMASK *msk;

	if( !(msk = im_matcat( mask().dptr, m.mask().dptr, "VDMask::cat" )) )
		verror();
	out.embed( msk );

	return( out );
}

VIMask VDMask::scalei() throw( VError )
{
	VIMask out;
	INTMASK *msk;

	if( !(msk = im_scale_dmask( mask().dptr, "VDMask::scalei" )) )
		verror();
	out.embed( msk );

	return( out );
}

// Arithmetic on a VIMask ... just cast and use VDMask
VDMask VIMask::trn() throw( VError ) 
	{ return( ((VDMask)*this).trn() ); }
VDMask VIMask::inv() throw( VError ) 
	{ return( ((VDMask)*this).inv() ); }
VDMask VIMask::cat( VDMask a ) throw( VError ) 
	{ return( ((VDMask)*this).cat( a ) ); }
VDMask VIMask::mul( VDMask a ) throw( VError ) 
	{ return( ((VDMask)*this).mul( a ) ); }

// Overload [] to get linear array subscript.
// Our caller may write to the result, so make sure we have a private
// copy.
// Involves function call, slow anyway, so do range checking
int &VIMask::operator[]( int x ) throw( VError )
{ 
	if( ref->nrefs != 1 )
		make_private();

	if( x > size() )
		verror( "VIMask::operator[]: subscript out of range" );

	return( ((_private_detail::VPIMask *)ref->pmask)->array()[x] ); 
}

double &VDMask::operator[]( int x ) throw( VError )
{ 
	if( ref->nrefs != 1 )
		make_private();

	if( x > size() )
		verror( "VDMask::operator[]: subscript out of range" );

	return( ((_private_detail::VPDMask *)ref->pmask)->array()[x] ); 
}

VIPS_NAMESPACE_END
