// 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 # include # include #endif /*!SWIG*/ /* Wrap pointers to these, but we don't want to import all the old C API. Just * declare them. */ extern "C" { struct _VipsImage; /* 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 { _VipsImage *im; // IMAGE pointer int close_on_delete; // Set if we must im_close() int nrefs; // Number of refs to us std::list 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 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( _VipsImage *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 _VipsImage *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 ); #endif /*SWIG*/ // We can wrap these, fwiw gboolean meta_remove( const char *field ); GType meta_get_typeof( const char *field ); // 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*/