448 lines
13 KiB
C++
448 lines
13 KiB
C++
// VIPS image wrapper
|
|
|
|
/*
|
|
|
|
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
|
|
|
|
*/
|
|
|
|
#ifndef IM_VIMAGE_H
|
|
#define IM_VIMAGE_H
|
|
|
|
/* SWIG includes this file directly rather than going through vipscpp.h ... so
|
|
* we have to define these macros here as well.
|
|
*/
|
|
#ifdef SWIG
|
|
# define VIPS_NAMESPACE_START namespace vips {
|
|
# define VIPS_NAMESPACE_END }
|
|
#endif /*SWIG*/
|
|
|
|
/* Don't include these when parsing for SWIG.
|
|
*/
|
|
#ifndef SWIG
|
|
# include <list>
|
|
# include <complex>
|
|
# include <vector>
|
|
#endif /*!SWIG*/
|
|
|
|
/* Wrap pointers to these, but we don't want to import all the old C API. Just
|
|
* declare them.
|
|
*/
|
|
extern "C" {
|
|
struct im__IMAGE;
|
|
|
|
/* Needed by Vargv, see below.
|
|
*/
|
|
struct im__function;
|
|
typedef void *im__object;
|
|
}
|
|
|
|
VIPS_NAMESPACE_START
|
|
|
|
/* A VIPS callback, our name for im_callback_fn.
|
|
*/
|
|
typedef int (*VCallback)( void *, void * );
|
|
|
|
/* VIPS image class.
|
|
*
|
|
* Slightly tricky: we have two sorts of sharing. Several VImage can share one
|
|
* refblock (while results are being returned from functions, for example),
|
|
* and several other refblocks can have IMAGEs which depend upon this IMAGE
|
|
* for their result.
|
|
*/
|
|
class VImage {
|
|
/* We'd like this to be protected so that user subclasses can define
|
|
* their own member wrappers. But sadly C++ doesn't work like that:
|
|
* subclasses of VImage can only refer to protected members via
|
|
* this->, which isn't what we need. Just make it public and hope no
|
|
* one touches it.
|
|
*/
|
|
public:
|
|
/* Doesn't need to be wrapped.
|
|
*/
|
|
#ifndef SWIG
|
|
// Count ref etc. in one of these. One for each open VIPS image.
|
|
struct refblock {
|
|
im__IMAGE *im; // IMAGE pointer
|
|
int close_on_delete; // Set if we must im_close()
|
|
int nrefs; // Number of refs to us
|
|
std::list<refblock*> orefs; // Refs im makes
|
|
|
|
// Construct/destruct
|
|
refblock();
|
|
virtual ~refblock() throw( VError );
|
|
|
|
// Add a ref - this (output image) depends upon IMAGE in
|
|
void addref( refblock *in ) throw( VError );
|
|
|
|
// Remove a ref
|
|
void removeref() throw( VError );
|
|
|
|
// Debugging
|
|
void debug_print();
|
|
|
|
// Linked list needs "==" -- use address equivalence
|
|
friend int operator==( const refblock &left,
|
|
const refblock &right ) { return( &left == &right ); }
|
|
};
|
|
|
|
refblock *_ref;
|
|
#endif /*!SWIG*/
|
|
|
|
public:
|
|
#ifdef DEBUG
|
|
/* All the refblocks in the world.
|
|
*/
|
|
static std::list<refblock*> all_refblock;
|
|
#endif /*DEBUG*/
|
|
|
|
/* Print all refblocks ... debugging. Compile with DEBUG to enable
|
|
* this.
|
|
*/
|
|
static void print_all();
|
|
|
|
/* Typedefs and enums we need.
|
|
*/
|
|
|
|
// Type type
|
|
enum TType {
|
|
MULTIBAND = 0,
|
|
B_W = 1,
|
|
LUMINACE = 2,
|
|
XRAY = 3,
|
|
IR = 4,
|
|
YUV = 5,
|
|
RED_ONLY = 6,
|
|
GREEN_ONLY = 7,
|
|
BLUE_ONLY = 8,
|
|
POWER_SPECTRUM = 9,
|
|
HISTOGRAM = 10,
|
|
LUT = 11,
|
|
XYZ = 12,
|
|
LAB = 13,
|
|
CMC = 14,
|
|
CMYK = 15,
|
|
LABQ = 16,
|
|
RGB = 17,
|
|
UCS = 18,
|
|
LCH = 19,
|
|
LABS = 21,
|
|
sRGB = 22,
|
|
YXY = 23,
|
|
FOURIER = 24,
|
|
RGB16 = 25,
|
|
GREY16 = 26
|
|
};
|
|
|
|
// Format type
|
|
enum TBandFmt {
|
|
FMTNOTSET = -1,
|
|
FMTUCHAR = 0,
|
|
FMTCHAR = 1,
|
|
FMTUSHORT = 2,
|
|
FMTSHORT = 3,
|
|
FMTUINT = 4,
|
|
FMTINT = 5,
|
|
FMTFLOAT = 6,
|
|
FMTCOMPLEX = 7,
|
|
FMTDOUBLE = 8,
|
|
FMTDPCOMPLEX = 9
|
|
};
|
|
|
|
// Coding type
|
|
enum TCoding {
|
|
NOCODING = 0,
|
|
COLQUANT = 1,
|
|
LABPACK = 2,
|
|
LABPACK_COMPRESSED = 3,
|
|
RGB_COMPRESSED = 4,
|
|
LUM_COMPRESSED = 5,
|
|
RAD = 6
|
|
};
|
|
|
|
// Compression type
|
|
enum TCompression {
|
|
NO_COMPRESSION = 0,
|
|
TCSF_COMPRESSION = 1,
|
|
JPEG_COMPRESSION = 2
|
|
};
|
|
|
|
/* Start of wrappers for iofuncs.
|
|
*/
|
|
|
|
// Plain constructors
|
|
VImage( const char *name, const char *mode = "r" ) throw( VError );
|
|
VImage( void *data, int width, int height,
|
|
int bands, TBandFmt format ) throw( VError );
|
|
VImage( im__IMAGE *image );
|
|
VImage() throw( VError );
|
|
|
|
// Convert to a disc file, eg:
|
|
// VImage fred = VImage::convert2disc( "im_jpeg2vips",
|
|
// "file.jpg", "temp.v" );
|
|
// Runs im_jpeg2vips to the temp file, then opens that and returns
|
|
// it. Useful for opening very large files without using a lot of RAM.
|
|
// Now superceeded by the format API, though that's not yet wrapped in
|
|
// C++
|
|
static VImage convert2disc( const char* convert,
|
|
const char* in, const char* disc ) throw( VError );
|
|
|
|
// Copy constructor
|
|
VImage( const VImage &a );
|
|
|
|
// Assignment - delete old ref
|
|
VImage &operator=( const VImage &a ) throw( VError );
|
|
|
|
// Destructor
|
|
virtual ~VImage() throw( VError ) { _ref->removeref(); }
|
|
|
|
// Extract underlying IMAGE* pointer
|
|
im__IMAGE *image() const { return( _ref->im ); }
|
|
|
|
// Extract underlying data pointer
|
|
void *data() const throw( VError );
|
|
|
|
// Write this to another VImage, to a file, or to a mem buffer
|
|
VImage write( VImage out ) throw( VError );
|
|
VImage write( const char *name ) throw( VError );
|
|
VImage write() throw( VError );
|
|
|
|
// Debugging ... print header fields
|
|
void debug_print();
|
|
|
|
// Projection functions to get header fields
|
|
int Xsize();
|
|
int Ysize();
|
|
int Bands();
|
|
TBandFmt BandFmt();
|
|
TCoding Coding();
|
|
TType Type();
|
|
float Xres();
|
|
float Yres();
|
|
int Length();
|
|
TCompression Compression();
|
|
short Level();
|
|
int Xoffset();
|
|
int Yoffset();
|
|
|
|
// Derived fields
|
|
const char *filename();
|
|
const char *Hist();
|
|
|
|
// metadata
|
|
#ifndef SWIG
|
|
// base functionality
|
|
// we don't wrap GValue, so we can't wrap these for now
|
|
void meta_set( const char *field, GValue *value ) throw( VError );
|
|
void meta_get( const char *field, GValue *value_copy ) throw( VError );
|
|
GType meta_get_type( const char *field ) throw( VError );
|
|
#endif /*SWIG*/
|
|
|
|
// convenience functions
|
|
int meta_get_int( const char *field ) throw( VError );
|
|
double meta_get_double( const char *field ) throw( VError );
|
|
const char *meta_get_string( const char *field ) throw( VError );
|
|
void *meta_get_area( const char *field ) throw( VError );
|
|
void *meta_get_blob( const char *field, size_t *length )
|
|
throw( VError );
|
|
|
|
void meta_set( const char *field, int value ) throw( VError );
|
|
void meta_set( const char *field, double value ) throw( VError );
|
|
void meta_set( const char *field, const char *value ) throw( VError );
|
|
|
|
#ifndef SWIG
|
|
// we don't wrap callbacks yet, so we can't wrap these for now
|
|
void meta_set( const char *field,
|
|
VCallback free_fn, void *value )
|
|
throw( VError );
|
|
void meta_set( const char *field,
|
|
VCallback free_fn, void *value, size_t length )
|
|
throw( VError );
|
|
#endif /*SWIG*/
|
|
|
|
// Set header fields
|
|
void initdesc( int, int, int, TBandFmt, TCoding, TType,
|
|
float = 1.0, float = 1.0, int = 0, int = 0 ) throw( VError );
|
|
|
|
/* Insert automatically generated headers.
|
|
*/
|
|
#include "vipsc++.h"
|
|
|
|
/* No point getting SWIG to wrap these ... we do this by hand later so we can
|
|
* handle things like "a + 12" correctly.
|
|
*/
|
|
#ifndef SWIG
|
|
// And some in-line operator equivalences done by hand
|
|
friend VImage operator+( VImage a, VImage b ) throw( VError )
|
|
{ return( a.add( b ) ); }
|
|
friend VImage operator+( double a, VImage b ) throw( VError )
|
|
{ return( b.lin( 1.0, a ) ); }
|
|
friend VImage operator+( VImage a, double b ) throw( VError )
|
|
{ return( a.lin( 1.0, b ) ); }
|
|
|
|
friend VImage operator-( VImage a, VImage b ) throw( VError )
|
|
{ return( a.subtract( b ) ); }
|
|
friend VImage operator-( double a, VImage b ) throw( VError )
|
|
{ return( b.lin( -1.0, a ) ); }
|
|
friend VImage operator-( VImage a, double b ) throw( VError )
|
|
{ return( a.lin( 1.0, -b ) ); }
|
|
|
|
friend VImage operator*( VImage a, VImage b ) throw( VError )
|
|
{ return( a.multiply( b ) ); }
|
|
friend VImage operator*( double a, VImage b ) throw( VError )
|
|
{ return( b.lin( a, 0.0 ) ); }
|
|
friend VImage operator*( VImage a, double b ) throw( VError )
|
|
{ return( a.lin( b, 0.0 ) ); }
|
|
|
|
friend VImage operator/( VImage a, VImage b ) throw( VError )
|
|
{ return( a.divide( b ) ); }
|
|
friend VImage operator/( double a, VImage b ) throw( VError )
|
|
{ return( b.pow( -1.0 ).lin( a, 0.0 ) ); }
|
|
friend VImage operator/( VImage a, double b ) throw( VError )
|
|
{ return( a.lin( 1.0/b, 0.0 ) ); }
|
|
|
|
friend VImage operator%( VImage a, VImage b ) throw( VError )
|
|
{ return( a.remainder( b ) ); }
|
|
friend VImage operator%( VImage a, double b ) throw( VError )
|
|
{ return( a.remainder( b ) ); }
|
|
|
|
friend VImage operator<( VImage a, VImage b ) throw( VError )
|
|
{ return( a.less( b ) ); }
|
|
friend VImage operator<( double a, VImage b ) throw( VError )
|
|
{ return( b.more( a ) ); }
|
|
friend VImage operator<( VImage a, double b ) throw( VError )
|
|
{ return( a.less( b ) ); }
|
|
|
|
friend VImage operator<=( VImage a, VImage b ) throw( VError )
|
|
{ return( a.lesseq( b ) ); }
|
|
friend VImage operator<=( double a, VImage b ) throw( VError )
|
|
{ return( b.moreeq( a ) ); }
|
|
friend VImage operator<=( VImage a, double b ) throw( VError )
|
|
{ return( a.lesseq( b ) ); }
|
|
|
|
friend VImage operator>( VImage a, VImage b ) throw( VError )
|
|
{ return( a.more( b ) ); }
|
|
friend VImage operator>( double a, VImage b ) throw( VError )
|
|
{ return( b.less( a ) ); }
|
|
friend VImage operator>( VImage a, double b ) throw( VError )
|
|
{ return( a.more( b ) ); }
|
|
|
|
friend VImage operator>=( VImage a, VImage b ) throw( VError )
|
|
{ return( a.moreeq( b ) ); }
|
|
friend VImage operator>=( double a, VImage b ) throw( VError )
|
|
{ return( b.lesseq( a ) ); }
|
|
friend VImage operator>=( VImage a, double b ) throw( VError )
|
|
{ return( a.moreeq( b ) ); }
|
|
|
|
friend VImage operator==( VImage a, VImage b ) throw( VError )
|
|
{ return( a.equal( b ) ); }
|
|
friend VImage operator==( double a, VImage b ) throw( VError )
|
|
{ return( b.equal( a ) ); }
|
|
friend VImage operator==( VImage a, double b ) throw( VError )
|
|
{ return( a.equal( b ) ); }
|
|
|
|
friend VImage operator!=( VImage a, VImage b ) throw( VError )
|
|
{ return( a.notequal( b ) ); }
|
|
friend VImage operator!=( double a, VImage b ) throw( VError )
|
|
{ return( b.notequal( a ) ); }
|
|
friend VImage operator!=( VImage a, double b ) throw( VError )
|
|
{ return( a.notequal( b ) ); }
|
|
|
|
friend VImage operator&( VImage a, VImage b ) throw( VError )
|
|
{ return( a.andimage( b ) ); }
|
|
friend VImage operator&( int a, VImage b ) throw( VError )
|
|
{ return( b.andimage( a ) ); }
|
|
friend VImage operator&( VImage a, int b ) throw( VError )
|
|
{ return( a.andimage( b ) ); }
|
|
|
|
friend VImage operator|( VImage a, VImage b ) throw( VError )
|
|
{ return( a.orimage( b ) ); }
|
|
friend VImage operator|( int a, VImage b ) throw( VError )
|
|
{ return( b.orimage( a ) ); }
|
|
friend VImage operator|( VImage a, int b ) throw( VError )
|
|
{ return( a.orimage( b ) ); }
|
|
|
|
friend VImage operator^( VImage a, VImage b ) throw( VError )
|
|
{ return( a.eorimage( b ) ); }
|
|
friend VImage operator^( int a, VImage b ) throw( VError )
|
|
{ return( b.eorimage( a ) ); }
|
|
friend VImage operator^( VImage a, int b ) throw( VError )
|
|
{ return( a.eorimage( b ) ); }
|
|
|
|
friend VImage operator<<( VImage a, int b ) throw( VError )
|
|
{ return( a.shiftleft( b ) ); }
|
|
friend VImage operator>>( VImage a, int b ) throw( VError )
|
|
{ return( a.shiftright( b ) ); }
|
|
|
|
friend VImage operator-( VImage a ) throw( VError )
|
|
{ return( a * -1 ); }
|
|
|
|
// Type conversion: VImage to VDMask and VIMask
|
|
operator VDMask() throw( VError )
|
|
{ return( this->vips2mask() ); }
|
|
operator VIMask() throw( VError )
|
|
{ return( VIMask( VDMask( *this ) ) ); }
|
|
#endif /*!SWIG*/
|
|
};
|
|
|
|
/* Don't include these when parsing for SWIG.
|
|
*/
|
|
#ifndef SWIG
|
|
|
|
/* Class wrapping up a vargv. Member function wrappers need this. It needs to
|
|
* be part of the public API in case people subclass VImage and add their own
|
|
* members.
|
|
*/
|
|
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();
|
|
};
|
|
|
|
#endif /*!SWIG*/
|
|
|
|
VIPS_NAMESPACE_END
|
|
|
|
// Other VIPS protos we need
|
|
extern "C" {
|
|
extern int im_init_world( const char *argv0 );
|
|
extern void im__print_all();
|
|
extern void im_col_Lab2XYZ(
|
|
float, float, float,
|
|
float *, float *, float * );
|
|
}
|
|
|
|
#endif /*IM_VIMAGE_H*/
|