Filewatcher File Search
FTP Search
  
Directory 
  
Content Search 
   
pkg://vips-7.8.14.tar.gz:3358561/vips-7.8.14/libsrcCC/VImage.cc  downloads

// Object part of VImage 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

 */


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

#include <vips/vips.h>
#include <vips/colour.h>
#include <vips/dispatch.h>
#include <vips/vipscpp.h>

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

/*
#define DEBUG
 */

#ifdef DEBUG
/* All the refblocks in the world.
 */
static std::list<VImage::refblock*> im__all_refblock;
#endif /*DEBUG*/

void VImage::refblock::print()
{
	std::list<refblock *>::iterator i;

	printf( "refblock 0x%x:\n", (unsigned int) this );
	printf( "  im = 0x%x", (unsigned int) im );
	if( im && ((IMAGE*)im)->filename ) 
		printf( " (im->filename = \"%s\")", ((IMAGE*)im)->filename );
	printf( "\n" );
	printf( "  close_on_delete = %d\n", close_on_delete );
	printf( "  nrefs (refs to us) = %d\n", nrefs );
	printf( "  orefs (refs we make) = refblocks " );
	for( i = orefs.begin(); i != orefs.end(); i++ )
		printf( "0x%x ", (unsigned int) (*i) );
	printf( "\n" );
}

// dump all refblocks for debugging
void im__ccp_print_all()
{
#ifdef DEBUG
	std::list<VImage::refblock *>::iterator i;

	printf( "*** VImage::refblock::print_all() start\n" );
	for( i = im__all_refblock.begin(); i != im__all_refblock.end(); i++ )
		(*i)->print();
	printf( "*** VImage::refblock::print_all() end\n" );
#endif /*DEBUG*/
}

// constructor
VImage::refblock::refblock() 
{
	im = 0; 
	close_on_delete = 1; 
	nrefs = 1; 

#ifdef DEBUG
	im__all_refblock.push_front( this );
#endif /*DEBUG*/
}

// Add a ref - this (output image) depends upon IMAGE in
void VImage::refblock::addref( refblock *in )
{
	if( this == in )
		verror( "sanity failure" );

	in->nrefs++;
	orefs.push_front( in );
}

VImage::refblock::~refblock()
{
#ifdef DEBUG
	printf( "VImage::refblock::removeref(): death!\n" );
	print();
#endif /*DEBUG*/

	std::list<refblock *>::iterator i;

	if( close_on_delete && im ) {
		if( im_close( (IMAGE *) im ) )
			verror();
		im = 0;
	}

	// remove any refs we have ... may trigger other destructs in turn
	for( i = orefs.begin(); i != orefs.end(); i++ )
		(*i)->removeref();

#ifdef DEBUG
	im__all_refblock.remove( this );
#endif /*DEBUG*/
}

// Remove a ref
void VImage::refblock::removeref()
{
	nrefs--;
	if( nrefs < 0 )
		verror( "too many closes!" );		
	if( nrefs == 0 ) 
		delete this;
}

// Init with name ... means open for read.
VImage::VImage( const char *name, const char *mode )
{
	_ref = new refblock;

	if( !(_ref->im = im_open( name, mode )) )
		verror();
	_ref->close_on_delete = 1;

#ifdef DEBUG
	printf( "VImage::VImage( \"%s\", \"%s\" )\n", name, mode );
	_ref->print();
#endif /*DEBUG*/
}

// Build a VImage from an IMAGE structure
VImage::VImage( void *in )
{
	_ref = new refblock;
	
	_ref->im = in;
	_ref->close_on_delete = 0;

#ifdef DEBUG
	printf( "VImage::VImage( IMAGE* 0x%x )\n", (unsigned int) in );
	_ref->print();
#endif /*DEBUG*/
}

// Build from memory buffer
VImage::VImage( void *buffer, int width, int height, 
	int bands, TBandFmt format )
{
	_ref = new refblock;

	if( !(_ref->im = im_image( buffer, width, height, 
		bands, int(format) )) )
		verror();
	_ref->close_on_delete = 1;

#ifdef DEBUG
	printf( "VImage::VImage( void* 0x%x, %d, %d )\n", 
		(unsigned int) buffer, width, height );
	_ref->print();
#endif /*DEBUG*/
}

// Empty init ... means open intermediate
VImage::VImage()
{
	static im_lock_t lock = IM_LOCK_STATIC;
	volatile static int id = 0;
	char filename[256];

	_ref = new refblock;

	/* This is not 100% safe if VIPS threading is not implemented on this
	 * platform ... but it doesn't really matter.
	 */
	im_lock( &lock );
	im_snprintf( filename, 256, "intermediate image #%d", id++ );
	im_unlock( &lock );

	if( !(_ref->im = im_open( filename, "p" )) )
		verror();
	_ref->close_on_delete = 1;

#ifdef DEBUG
	printf( "VImage::VImage()\n" ); 
	_ref->print();
#endif /*DEBUG*/
}

// Copy constructor
VImage::VImage( const VImage &a ) 
{ 
	_ref = a._ref; 
	_ref->nrefs++; 
}

// Assignment
VImage &VImage::operator=( const VImage &a )
{ 
	_ref->removeref(); 
	_ref = a._ref; 
	_ref->nrefs++; 
	
	return *this; 
}

// Extract underlying data pointer
void *VImage::data() const
{
	if( im_incheck( (IMAGE *) _ref->im ) )
		verror();
	
	return( (void *) ((IMAGE *) _ref->im)->data );
}

void VImage::print()
{
	im_printdesc( (IMAGE *) image() );
}

// Write this to a VImage
VImage VImage::write( VImage out )
{
	if( im_copy( (IMAGE *) _ref->im, (IMAGE *) out._ref->im ) )
		verror();
	out._ref->addref( _ref );

	return( out );
}

VImage VImage::write( const char *name )
{
	VImage out( name, "w" );

	if( im_copy( (IMAGE *) _ref->im, (IMAGE *) out._ref->im ) )
		verror();
	out._ref->addref( _ref );

	return( out );
}

VImage VImage::write()
{
	VImage out( "VImage:w1", "t" );

	if( im_copy( (IMAGE *) _ref->im, (IMAGE *) out._ref->im ) )
		verror();
	out._ref->addref( _ref );

	return( out );
}

// Projection functions to get header fields
int VImage::Xsize() { return( ((IMAGE *) _ref->im)->Xsize ); }
int VImage::Ysize() { return( ((IMAGE *) _ref->im)->Ysize ); }
int VImage::Bands() { return( ((IMAGE *) _ref->im)->Bands ); }
VImage::TBandFmt VImage::BandFmt() 
	{ return( (TBandFmt) ((((IMAGE *) _ref->im)->BandFmt)) ); }
VImage::TCoding VImage::Coding() 
	{ return( (TCoding) ((((IMAGE *) _ref->im)->Coding)) ); }
VImage::TType VImage::Type() 
	{ return( (TType) ((((IMAGE *) _ref->im)->Type)) ); }
float VImage::Xres() { return( ((IMAGE *) _ref->im)->Xres ); }
float VImage::Yres() { return( ((IMAGE *) _ref->im)->Yres ); }
int VImage::Length() { return( ((IMAGE *) _ref->im)->Length ); }
VImage::TCompression VImage::Compression() 
	{ return( (TCompression) ((((IMAGE *) _ref->im)->Compression)) ); }
short VImage::Level() { return( ((IMAGE *) _ref->im)->Level ); }
int VImage::Xoffset() { return( ((IMAGE *) _ref->im)->Xoffset ); }
int VImage::Yoffset() { return( ((IMAGE *) _ref->im)->Yoffset ); }

// Derived fields
char *VImage::filename() { return( ((IMAGE *) _ref->im)->filename ); }
char *VImage::Hist() { return( ((IMAGE *) _ref->im)->Hist ); }

// Set header fields and setbuf() in one go.
void VImage::initdesc( int x, int y, int b,
	TBandFmt f, TCoding c, TType t, float xr, float yr, int xo, int yo )
{
	static int fmt[] = { 
		0, 				// NOTSET
		IM_BBITS_BYTE, IM_BBITS_BYTE,	// uchar/char
		IM_BBITS_SHORT, IM_BBITS_SHORT,	// ushort/short
		IM_BBITS_INT, IM_BBITS_INT,	// uint/int
		IM_BBITS_FLOAT,			// float types ...
		IM_BBITS_COMPLEX,
		IM_BBITS_DOUBLE,
		IM_BBITS_DPCOMPLEX
	};

	im_initdesc( (IMAGE *) (_ref->im), x, y, b, 
		fmt[(int)f + 1], f, c, t, xr, yr, xo, yo );
	if( im_setupout( (IMAGE *) _ref->im ) )
		verror();
}

// Class wrapping up a vargv
class Vargv {
	// Function we are args to
	im_function *fn;

	// Base of object vector
	im_object *base;

public:
	Vargv( const char *name );
	~Vargv();

	// Reference to element of base
	im_object &data( int i = 0 ) { return( base[i] ); };

	// Invoke function
	void call();
};

// Create a Vargv from a name
Vargv::Vargv( const char *name )
{
	im_function *f = im_find_function( (char *) name );
	
	if( !f )
		verror();

	fn = f;
	base = new im_object[ fn->argc ]; 
	if( im_allocate_vargv( fn, base ) ) {
		delete[] base;
		verror();
	}
}

// Destroy a Vargv
Vargv::~Vargv()
{
	im_free_vargv( fn, base );
	delete[] base;
}

// Call the function
void
Vargv::call()
{
	if( fn->disp( base ) ) 
		verror();
}

/* Insert automatically generated wrappers for VIPS image processing 
 * functions.
 */
#include "vipsc++.cc"
Results 1 - 1
Help - FTP Sites List - Software Dir.
Searching half a billion files worldwide
© 1997-2009 MARUHN Internet Solutions