From 4f588ce908234f8ce2fa0f3eb144a8a320a71352 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 27 Oct 2014 13:41:44 +0000 Subject: [PATCH] package up new vips8 C++ API --- Makefile.am | 9 +- configure.ac | 4 + cplusplus/Makefile.am | 16 +- cplusplus/VError.cc | 58 +-- cplusplus/VImage.cc | 380 +++++++----------- cplusplus/examples/a.out | Bin 0 -> 35682 bytes cplusplus/examples/invert.cc | 54 +++ cplusplus/include/vips/Makefile.am | 4 +- .../include/vips/{VError.h => VError8.h} | 44 +- cplusplus/include/vips/VImage.h | 334 --------------- cplusplus/include/vips/VImage8.h | 236 +++++++++++ cplusplus/include/vips/vips-operators.h | 4 +- cplusplus/include/vips/vips8 | 4 +- cplusplus/{ => old}/try92.cc | 0 cplusplus/{ => old}/try93.cc | 0 cplusplus/vips-operators.cc | 18 +- vips-cc.pc.in | 10 + vipsCC.pc.in | 2 +- 18 files changed, 494 insertions(+), 683 deletions(-) create mode 100755 cplusplus/examples/a.out create mode 100644 cplusplus/examples/invert.cc rename cplusplus/include/vips/{VError.h => VError8.h} (60%) delete mode 100644 cplusplus/include/vips/VImage.h create mode 100644 cplusplus/include/vips/VImage8.h rename cplusplus/{ => old}/try92.cc (100%) rename cplusplus/{ => old}/try93.cc (100%) create mode 100644 vips-cc.pc.in diff --git a/Makefile.am b/Makefile.am index a870fe50..bfa09060 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,9 +1,9 @@ -# turn off libvipsCC if C++ is disabled +# turn off C++ APIs if C++ is disabled if ENABLE_CXX -C_COMPILE_DIR = libvipsCC +C_COMPILE_DIR = libvipsCC cplusplus C_DIST_DIR = -C_PKGCONFIG = vipsCC.pc +C_PKGCONFIG = vipsCC.pc vips-cc.pc # turn on Python if we can (requires C++) if HAVE_PYTHON @@ -13,7 +13,7 @@ endif else C_COMPILE_DIR = -C_DIST_DIR = libvipsCC +C_DIST_DIR = libvipsCC cplusplus C_PKGCONFIG = P_COMPILE_DIR = P_DIST_DIR = swig @@ -53,6 +53,7 @@ EXTRA_DIST = \ bootstrap.sh \ vips.pc.in \ vipsCC.pc.in \ + vips-cc.pc.in \ libvips.supp \ acinclude.m4 \ depcomp \ diff --git a/configure.ac b/configure.ac index 63483c80..b6eb15a5 100644 --- a/configure.ac +++ b/configure.ac @@ -794,6 +794,7 @@ AC_SUBST(PACKAGES_USED) AC_OUTPUT([ vips.pc vipsCC.pc + vips-cc.pc Makefile libvips/include/vips/version.h libvips/include/Makefile @@ -817,6 +818,9 @@ AC_OUTPUT([ libvipsCC/include/Makefile libvipsCC/include/vips/Makefile libvipsCC/Makefile + cplusplus/include/Makefile + cplusplus/include/vips/Makefile + cplusplus/Makefile tools/Makefile tools/batch_crop tools/batch_image_convert diff --git a/cplusplus/Makefile.am b/cplusplus/Makefile.am index 9ab3717a..08fa22dd 100644 --- a/cplusplus/Makefile.am +++ b/cplusplus/Makefile.am @@ -8,28 +8,28 @@ AM_CPPFLAGS = \ lib_LTLIBRARIES = libvips-cc.la -libvipsCC_la_SOURCES = \ +libvips_cc_la_SOURCES = \ VImage.cc \ VError.cc -libvipsCC_la_LDFLAGS = \ +libvips_cc_la_LDFLAGS = \ -no-undefined \ -version-info @LIBRARY_CURRENT@:@LIBRARY_REVISION@:@LIBRARY_AGE@ -libvipsCC_la_LIBADD = \ +libvips_cc_la_LIBADD = \ $(top_builddir)/libvips/libvips.la @VIPS_LIBS@ # swap the 'awk' line for this: # awk '{if($$1!="deprecated") print $$1}'` ; \ # to not generate the wrappers for deprecated functions -vipsc++.cc: +vips-operators.cc: packages=`vips list packages | \ awk '{print $$1}'` ; \ - echo > vipsc++.cc ; \ + echo > vips-operators.cc ; \ for name in $$packages; do \ - echo "// bodies for package $$name" >> vipsc++.cc ; \ - vips cppc $$name >> vipsc++.cc ; \ - echo >> vipsc++.cc ; \ + echo "// bodies for package $$name" >> vips-operators.cc ; \ + vips cppc $$name >> vips-operators.cc ; \ + echo >> vips-operators.cc ; \ done EXTRA_DIST = vips-operators.cc diff --git a/cplusplus/VError.cc b/cplusplus/VError.cc index 999d51e4..67e67348 100644 --- a/cplusplus/VError.cc +++ b/cplusplus/VError.cc @@ -32,69 +32,21 @@ #endif /*HAVE_CONFIG_H*/ #include -#include -#include - #include -#include - -#include - -#ifdef WITH_DMALLOC -#include -#endif /*WITH_DMALLOC*/ +#include VIPS_NAMESPACE_START -void VError::perror() -{ - std::cerr << _what; - exit( 1 ); +std::ostream &operator<<( std::ostream &file, const VError &err ) +{ + err.ostream_print( file ); + return( file ); } -void VError::perror( const char *name ) -{ - std::cerr << name << ": " << _what; - exit( 1 ); -} - -// Add a new bit to the end of the error buffer -VError &VError::app( const int i ) -{ - char buf[ 256 ]; - - sprintf( buf, "%d", i ); - _what += buf; - - return( *this ); -} - -VError &VError::app( std::string txt ) -{ - _what += txt; - - return( *this ); -}; - void VError::ostream_print( std::ostream &file ) const { file << _what; } -void verror( std::string str ) throw( VError ) -{ - VError err; - - err.app( "VIPS error: " ); - if( str == "" ) { - err.app( im_error_buffer() ); - im_error_clear(); - } - else - err.app( str ).app( "\n" ); - - throw( err ); -} - VIPS_NAMESPACE_END diff --git a/cplusplus/VImage.cc b/cplusplus/VImage.cc index 5893adce..a09971c9 100644 --- a/cplusplus/VImage.cc +++ b/cplusplus/VImage.cc @@ -32,303 +32,221 @@ #endif /*HAVE_CONFIG_H*/ #include -#include -#include -#include +#include -#include #include -#include - -#include "include/vips/vips8" - -#ifdef WITH_DMALLOC -#include -#endif /*WITH_DMALLOC*/ - /* #define DEBUG */ VIPS_NAMESPACE_START -/* Useful to have these as namespaced C++ functions. - */ -void -init( const char *argv0 ) - throw( VError ) +VOption::~VOption() { - if( vips_init( argv0 ) ) - throw VError(); + std::list::iterator i; + + for( i = options.begin(); i != options.end(); i++ ) + delete *i; } -void shutdown() +VOption *VOption::set( const char *name, const char *value ) { - vips_shutdown(); + Pair *pair = new Pair( name ); + + pair->input = true; + g_value_init( &pair->value, G_TYPE_STRING ); + g_value_set_string( &pair->value, value ); + options.push_back( pair ); + + return( this ); } -void thread_shutdown() +VOption *VOption::set( const char *name, int value ) { - vips_thread_shutdown(); + Pair *pair = new Pair( name ); + + pair->input = true; + g_value_init( &pair->value, G_TYPE_INT ); + g_value_set_int( &pair->value, value ); + options.push_back( pair ); + + return( this ); } -static void -call_get( GParamSpec *pspec, void *arg ) +VOption *VOption::set( const char *name, VImage value ) { - /* We've read out of the VipsObject to the pointer. If it's a - * VipsImage, we need to box it. - */ - if( G_IS_PARAM_SPEC_OBJECT( pspec ) ) { - VImage *image = new VImage( *((VipsImage **) arg) ); + Pair *pair = new Pair( name ); - *((VImage *) arg) = *image; - } + pair->input = true; + g_value_init( &pair->value, VIPS_TYPE_IMAGE ); + // we need to unbox + g_value_set_object( &pair->value, value.get_image() ); + options.push_back( pair ); + + return( this ); } -static void -call_set( GParamSpec *pspec, GValue *value ) +VOption *VOption::set( const char *name, VImage *value ) { - if( G_VALUE_HOLDS( value, VIPS_TYPE_IMAGE ) ) { - /* A VImage has been written to the GValue, extract the VImage - * and swap it for the underlying VipsImage* pointer. - */ - VImage *image = static_cast( - g_value_peek_pointer( value ) ); + Pair *pair = new Pair( name ); - g_value_set_object( value, (gpointer) (image->image()) ); - } + // note where we will write the VImage on success + pair->input = false; + pair->vimage = value; + g_value_init( &pair->value, VIPS_TYPE_IMAGE ); + + options.push_back( pair ); + + return( this ); } -/* Some systems do not have va_copy() ... this might work (it does on MSVC, - * apparently). - * - * FIXME ... this should be in configure.in - */ -#ifndef va_copy -#define va_copy(d,s) ((d) = (s)) -#endif - -void -call( const char *operation_name, ... ) - throw( VError ) +// walk the options and set props on the operation +void VOption::set_operation( VipsOperation *operation ) { - VipsCollect collect; - VipsOperation *operation; - int result; - va_list required; - va_list optional; + std::list::iterator i; - if( !(operation = vips_operation_new( operation_name )) ) - throw VError(); + for( i = options.begin(); i != options.end(); i++ ) + if( (*i)->input ) { + printf( "set_operation: " ); + vips_object_print_name( VIPS_OBJECT( operation ) ); + char *str_value = + g_strdup_value_contents( &(*i)->value ); + printf( ".%s = %s\n", (*i)->name, str_value ); + g_free( str_value ); - /* We have to break the va_list into separate required and optional - * components. - * - * Note the start, grab the required, then copy and reuse. - */ - va_start( required, operation_name ); - - va_copy( optional, required ); - - VIPS_ARGUMENT_FOR_ALL( operation, - pspec, argument_class, argument_instance ) { - - g_assert( argument_instance ); - - if( (argument_class->flags & VIPS_ARGUMENT_REQUIRED) ) { - VIPS_ARGUMENT_COLLECT_SET( pspec, argument_class, - optional ); - - VIPS_ARGUMENT_COLLECT_GET( pspec, argument_class, - optional ); - - VIPS_ARGUMENT_COLLECT_END + g_object_set_property( G_OBJECT( operation ), + (*i)->name, &(*i)->value ); } - } VIPS_ARGUMENT_FOR_ALL_END - - collect.get = call_get; - collect.set = call_set; - result = vips_call_required_optional( &operation, - &collect, required, optional ); - - va_end( required ); - va_end( optional ); - - /* Build failed: junk args. - */ - if( result ) - vips_object_unref_outputs( VIPS_OBJECT( operation ) ); - - /* The operation we have built should now have been reffed by one of - * its arguments or have finished its work. Either way, we can unref. - */ - g_object_unref( operation ); - - if( result ) - throw VError(); } -int -call_split( const char *operation_name, va_list optional, ... ) +// walk the options and do any processing needed for output objects +void VOption::get_operation( VipsOperation *operation ) +{ + std::list::iterator i; + + for( i = options.begin(); i != options.end(); i++ ) + if( not (*i)->input ) { + g_object_get_property( G_OBJECT( operation ), + (*i)->name, &(*i)->value ); + + printf( "get_operation: " ); + vips_object_print_name( VIPS_OBJECT( operation ) ); + char *str_value = + g_strdup_value_contents( &(*i)->value ); + printf( ".%s = %s\n", (*i)->name, str_value ); + g_free( str_value ); + + // rebox object + VipsImage *image = VIPS_IMAGE( + g_value_get_object( &(*i)->value ) ); + if( (*i)->vimage ) + *((*i)->vimage) = VImage( image ); + } +} + +void VImage::call_option_string( const char *operation_name, + const char *option_string, VOption *options ) + throw( VError ) { VipsOperation *operation; - va_list required; - VipsCollect collect; - int result; - if( !(operation = vips_operation_new( operation_name )) ) - throw VError(); + VIPS_DEBUG_MSG( "vips_call_by_name: starting for %s ...\n", + operation_name ); - va_start( required, optional ); + if( !(operation = vips_operation_new( operation_name )) ) { + if( options ) + delete options; + throw( VError() ); + } - collect.get = call_get; - collect.set = call_set; - result = vips_call_required_optional( &operation, - &collect, required, optional ); - - va_end( required ); - - /* Build failed: junk args. + /* Set str options before vargs options, so the user can't + * override things we set deliberately. */ - if( result ) + if( option_string && + vips_object_set_from_string( VIPS_OBJECT( operation ), + option_string ) ) { vips_object_unref_outputs( VIPS_OBJECT( operation ) ); + g_object_unref( operation ); + delete options; + throw( VError() ); + } - /* The operation we have built should now have been reffed by one of - * its arguments or have finished its work. Either way, we can unref. + if( options ) + options->set_operation( operation ); + + /* Build from cache. + */ + if( vips_cache_operation_buildp( &operation ) ) { + vips_object_unref_outputs( VIPS_OBJECT( operation ) ); + delete options; + throw( VError() ); + } + + /* Walk args again, writing output. + */ + if( options ) + options->get_operation( operation ); + + /* We're done with options! + */ + delete options; + + /* The operation we have built should now have been reffed by + * one of its arguments or have finished its work. Either + * way, we can unref. */ g_object_unref( operation ); - - if( result ) - throw VError(); } -// see vips_image_new_from_file() -VImage::VImage( const char *name, ... ) - throw( VError ) +void VImage::call( const char *operation_name, VOption *options ) + throw( VError ) +{ + call_option_string( operation_name, NULL, options ); +} + +VImage VImage::new_from_file( const char *name, VOption *options ) + throw( VError ) { char filename[VIPS_PATH_MAX]; char option_string[VIPS_PATH_MAX]; const char *operation_name; - va_list ap; - int result; + + VImage out; vips__filename_split8( name, filename, option_string ); - if( !(operation_name = vips_foreign_find_load( filename )) ) + if( !(operation_name = vips_foreign_find_load( filename )) ) { + delete options; throw VError(); + } - va_start( ap, name ); - result = vips_call_split_option_string( operation_name, - option_string, ap, filename, &im ); - va_end( ap ); + call_option_string( operation_name, option_string, + (options ? options : VImage::option())-> + set( "filename", filename )-> + set( "out", &out ) ); - if( result ) - throw VError(); + return( out ); } -// see vips_image_new_from_buffer() -VImage::VImage( void *buffer, size_t length, const char *option_string, ... ) - throw( VError ) -{ - const char *operation_name; - VipsBlob *blob; - va_list ap; - int result; - - if( !(operation_name = - vips_foreign_find_load_buffer( buffer, length )) ) - throw VError(); - - /* We don't take a copy of the data or free it. - */ - blob = vips_blob_new( NULL, buffer, length ); - - va_start( ap, option_string ); - result = vips_call_split_option_string( operation_name, - option_string, ap, blob, &im ); - va_end( ap ); - - vips_area_unref( VIPS_AREA( blob ) ); - - if( result ) - throw VError(); -} - -// see vips_image_write_to_file() -void VImage::write_to_file( const char *name, ... ) +void VImage::write_to_file( const char *name, VOption *options ) throw( VError ) { char filename[VIPS_PATH_MAX]; char option_string[VIPS_PATH_MAX]; const char *operation_name; - va_list ap; - int result; vips__filename_split8( name, filename, option_string ); - if( !(operation_name = vips_foreign_find_save( filename )) ) + if( !(operation_name = vips_foreign_find_save( filename )) ) { + delete options; throw VError(); + } - va_start( ap, name ); - result = vips_call_split_option_string( operation_name, option_string, - ap, this->im, filename ); - va_end( ap ); - - if( result ) - throw VError(); + call_option_string( operation_name, option_string, + (options ? options : VImage::option())-> + set( "in", *this )-> + set( "filename", filename ) ); } -// see vips_image_write_to_buffer() -void *VImage::write_to_buffer( const char *suffix, size_t *size, ... ) - throw( VError ) -{ - char filename[VIPS_PATH_MAX]; - char option_string[VIPS_PATH_MAX]; - const char *operation_name; - va_list ap; - VipsBlob *blob; - int result; - void *buf; - - vips__filename_split8( suffix, filename, option_string ); - if( !(operation_name = vips_foreign_find_save_buffer( filename )) ) - throw VError(); - - va_start( ap, size ); - result = vips_call_split_option_string( operation_name, option_string, - ap, this->im, &blob ); - va_end( ap ); - - if( result ) - throw VError(); - - g_assert( blob ); - - buf = VIPS_AREA( blob )->data; - VIPS_AREA( blob )->free_fn = NULL; - if( size ) - *size = VIPS_AREA( blob )->length; - - vips_area_unref( VIPS_AREA( blob ) ); - - return( buf ); -} - - -/* Insert automatically generated wrappers for vips operators. - */ #include "vips-operators.cc" VIPS_NAMESPACE_END - - -int -main( int argc, char **argv ) -{ - vips8::init( argv[0] ); - - vips8::VImage x( "/home/john/pics/k2.jpg", NULL ); - - printf( "width = %d\n", x.width() ); - - return( 0 ); -} diff --git a/cplusplus/examples/a.out b/cplusplus/examples/a.out new file mode 100755 index 0000000000000000000000000000000000000000..3d0c6cb21337dd4236bcd3bef7a43884e18da8ae GIT binary patch literal 35682 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 + +using namespace vips8; + +int +main( int argc, char **argv ) +{ + GOptionContext *context; + GOptionGroup *main_group; + GError *error = NULL; + + if( vips_init( argv[0] ) ) + vips_error_exit( NULL ); + + context = g_option_context_new( "" ); + + main_group = g_option_group_new( NULL, NULL, NULL, NULL, NULL ); + g_option_context_set_main_group( context, main_group ); + g_option_context_add_group( context, vips_get_option_group() ); + + if( !g_option_context_parse( context, &argc, &argv, &error ) ) { + if( error ) { + fprintf( stderr, "%s\n", error->message ); + g_error_free( error ); + } + + vips_error_exit( NULL ); + } + + + printf( "these should match if VImage is compile-time-only\n" ); + printf( "sizeof( VipsImage *) = %zd\n", sizeof( VipsImage *) ); + printf( "sizeof( VImage ) = %zd\n", sizeof( VImage ) ); + +{ + VImage in = VImage::new_from_file( argv[1] ); + VImage out; + + out = in.invert(); + + out.write_to_file( argv[2] ); +} + + vips_shutdown(); + + return( 0 ); +} diff --git a/cplusplus/include/vips/Makefile.am b/cplusplus/include/vips/Makefile.am index 94eceef4..c14ef992 100644 --- a/cplusplus/include/vips/Makefile.am +++ b/cplusplus/include/vips/Makefile.am @@ -1,6 +1,6 @@ pkginclude_HEADERS = \ - VError.h \ - VImage.h \ + VError8.h \ + VImage8.h \ vips8 \ vips-operators.h diff --git a/cplusplus/include/vips/VError.h b/cplusplus/include/vips/VError8.h similarity index 60% rename from cplusplus/include/vips/VError.h rename to cplusplus/include/vips/VError8.h index 9cfdb41f..0cb7478d 100644 --- a/cplusplus/include/vips/VError.h +++ b/cplusplus/include/vips/VError8.h @@ -27,57 +27,31 @@ */ -#ifndef IM_VERROR_H -#define IM_VERROR_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*/ +#ifndef VIPS_VERROR_H +#define VIPS_VERROR_H -/* Don't include these when parsing for SWIG. - */ -#ifndef SWIG -# include -# include -# include -#endif /*!SWIG*/ +#include +#include +#include + +#include VIPS_NAMESPACE_START -// Error type class VError : public std::exception { std::string _what; public: VError( std::string what ) : _what( what ) {} - VError() {} + VError() : _what( vips_error_buffer() ) {} virtual ~VError() throw() {} - // Print message and exit - void perror( const char * ); - void perror(); - - // Append some more text to the message - VError &app( std::string txt ); - VError &app( const int i ); - // Extract string virtual const char *what() const throw() { return _what.c_str(); } void ostream_print( std::ostream & ) const; }; -inline std::ostream &operator<<( std::ostream &file, const VError &err ) -{ - err.ostream_print( file ); - return( file ); -} - -void verror( std::string str = "" ) throw( VError ); - VIPS_NAMESPACE_END -#endif /*IM_VERROR_H*/ +#endif /*VIPS_VERROR_H*/ diff --git a/cplusplus/include/vips/VImage.h b/cplusplus/include/vips/VImage.h deleted file mode 100644 index f102f454..00000000 --- a/cplusplus/include/vips/VImage.h +++ /dev/null @@ -1,334 +0,0 @@ -// 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., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA - - */ - -/* - - These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk - - */ - -#ifndef VIPS_VIMAGE_H -#define VIPS_VIMAGE_H - -#include -#include -#include - -#include - -VIPS_NAMESPACE_START - -/* vips_init() and vips_shutdown as namespaced C++ functions. - */ -void init( const char *argv0 = "nothing" ) throw( VError ); -void thread_shutdown( void ); -void shutdown( void ); - -/* VIPS image class. - */ -class VImage { -protected: - VipsImage *im = NULL; // Underlying vips pointer - -public: - VImage() - { - im = NULL; - } - - // ref the VipsImage ... see new_steal() for one that steals the - // caller's ref - VImage( VipsImage *vips_image ) - { - g_assert( !im ); - - im = vips_image; - g_object_ref( im ); - } - - // make a VImage, stealing the caller's ref - VImage new_steal( VipsImage *vips_image ) - { - VImage image; - - g_assert( !image.im ); - - image.im = vips_image; - } - - VImage( const char *filename, const char *mode = "r" ) - throw( VError ) - { - if( !(im = vips_image_new_mode( filename, mode )) ) - throw VError(); - } - - // see vips_image_new_from_file() - VImage( const char *name, ... ) - throw( VError ) __attribute__((sentinel)); - - // see vips_image_new_from_buffer() - VImage( void *buffer, size_t length, const char *option_string, ... ) - throw( VError ) __attribute__((sentinel)); - - // see vips_image_new_from_memory() - VImage( void *data, size_t size, int width, int height, - int bands, VipsBandFormat format ) throw( VError ) - { - if( !(im = vips_image_new_from_memory( data, size, - width, height, bands, format )) ) - throw VError(); - } - - // also do - // vips_image_new_matrix() - // vips_image_new_matrixv() - // vips_image_new_matrix_from_array() - // vips_image_new_from_file_raw:() - // vips_image_new_from_file_RW() - // vips_image_new_memory() - - // Copy constructor - VImage( const VImage &a ) - { - g_assert( !im ); - - im = a.im; - g_object_ref( im ); - } - - // Assignment - delete old ref - VImage &operator=( const VImage &a ) - { - VIPS_UNREF( im ); - im = a.im; - g_object_ref( im ); - } - - // Destructor - ~VImage() throw( VError ) { VIPS_UNREF( im ); } - - // Peek at the underlying VipsImage pointer - VipsImage *image() const { return( im ); } - - // get a pointer to the pixels ... can be very slow! this may render - // the whole image to a memory buffer - void *data() - throw( VError ) - { - if( vips_image_wio_input( im ) ) - throw VError(); - - return( VIPS_IMAGE_ADDR( im, 0, 0 ) ); - } - - // Write this to another VImage, to a file, or to a mem buffer - void write( VImage out ) - throw( VError ) - { - if( vips_image_write( im, out.im ) ) - throw VError(); - } - - void write_to_file( const char *name, ... ) - throw( VError ) - { - if( vips_image_write_to_file( im, name, NULL ) ) - throw VError(); - } - - // see vips_image_write_to_buffer() - void *write_to_buffer( const char *suffix, size_t *size, ... ) - throw( VError ); - - // also need - // vips_image_write_to_memory() - - // Projection functions to get header fields - int width() { return( im->Xsize ); } - int height() { return( im->Ysize ); } - int bands() { return( im->Bands ); } - VipsBandFormat format() { return( im->BandFmt ); } - VipsCoding coding() { return( im->Coding ); } - VipsInterpretation interpretation() { return( im->Type ); } - float xres() { return( im->Xres ); } - float yres() { return( im->Yres ); } - int xoffset() { return( im->Xoffset ); } - int yoffset() { return( im->Yoffset ); } - - // Derived fields - const char *filename() { return( im->filename ); } - const char *hist() { return( vips_image_get_history( im ) ); } - - // metadata - - /* - - // base functionality - void meta_set( const char *field, GValue *value ) throw( VError ); - void meta_get( const char *field, GValue *value_copy ) throw( VError ); - 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 ); - - 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 ); - - // Set header fields - void initdesc( int, int, int, - VipsBandFormat, VipsCoding, VipsInterpretation, - float = 1.0, float = 1.0, int = 0, int = 0 ) throw( VError ); - */ - - /* Insert automatically generated headers. - */ -#include "vips-operators.h" - - /* - - // 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 ); } - */ - -}; - -VIPS_NAMESPACE_END - -#endif /*VIPS_VIMAGE_H*/ diff --git a/cplusplus/include/vips/VImage8.h b/cplusplus/include/vips/VImage8.h new file mode 100644 index 00000000..b839acf8 --- /dev/null +++ b/cplusplus/include/vips/VImage8.h @@ -0,0 +1,236 @@ +// 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., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA + + */ + +/* + + These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk + + */ + +#ifndef VIPS_VIMAGE_H +#define VIPS_VIMAGE_H + +#include +#include +#include + +#include + +VIPS_NAMESPACE_START + +enum VSteal { + NOSTEAL = 0, + STEAL = 1 +}; + +/* A smart VipsObject pointer class ... use g_object_ref()/_unref() for + * lifetime management. + */ +class VObject +{ +private: + // can be NULL, see eg. VObject() + VipsObject *vobject; + +public: + VObject( VipsObject *new_vobject, VSteal steal = STEAL ) : + vobject( new_vobject ) + { + // we allow NULL init, eg. "VImage a;" + g_assert( !new_vobject || + VIPS_IS_OBJECT( new_vobject ) ); + + printf( "VObject constructor, obj = %p, steal = %d\n", + new_vobject, steal ); + if( new_vobject ) { + printf( " obj " ); + vips_object_print_name( VIPS_OBJECT( new_vobject ) ); + printf( "\n" ); + } + if( !steal ) { + printf( " reffing object\n" ); + g_object_ref( vobject ); + } + } + + VObject() : + vobject( 0 ) + { + } + + // copy constructor + VObject( const VObject &a ) : + vobject( a.vobject ) + { + g_assert( VIPS_IS_OBJECT( a.vobject ) ); + + printf( "VObject copy constructor, obj = %p\n", + vobject ); + g_object_ref( vobject ); + printf( " reffing object\n" ); + } + + // assignment ... we must delete the old ref + // old can be NULL, new must not be NULL + VObject &operator=( const VObject &a ) + { + VipsObject *old_vobject; + + printf( "VObject assignment\n" ); + printf( " reffing %p\n", a.vobject ); + printf( " unreffing %p\n", vobject ); + + g_assert( !vobject || + VIPS_IS_OBJECT( vobject ) ); + g_assert( a.vobject && + VIPS_IS_OBJECT( a.vobject ) ); + + // delete the old ref at the end ... otherwise "a = a;" could + // unref before reffing again + old_vobject = vobject; + vobject = a.vobject; + g_object_ref( vobject ); + if( old_vobject ) + g_object_unref( old_vobject ); + + return( *this ); + } + + // this mustn't be virtual: we want this class to only be a pointer, + // no vtable allowed + ~VObject() + { + printf( "VObject destructor\n" ); + printf( " unreffing %p\n", vobject ); + + g_assert( !vobject || + VIPS_IS_OBJECT( vobject ) ); + + if( vobject ) + g_object_unref( vobject ); + } + + VipsObject *get_object() + { + g_assert( !vobject || + VIPS_IS_OBJECT( vobject ) ); + + return( vobject ); + } + +}; + +class VImage; +class VOption; + +class VOption +{ +private: + struct Pair { + const char *name; + + // the thing we pass to VipsOperation + GValue value; + + // an input or output parameter ... we guess the direction + // from the arg to set() + bool input; + + // we need to box and unbox VImage ... keep a pointer to the + // VImage from C++ here + VImage *vimage; + + Pair( const char *name ) : + name( name ), input( false ), vimage( 0 ) + { + G_VALUE_TYPE( &value ) = 0; + } + + ~Pair() + { + g_value_unset( &value ); + } + }; + + std::list options; + +public: + VOption() + { + } + + virtual ~VOption(); + + VOption *set( const char *name, const char *value ); + VOption *set( const char *name, int value ); + VOption *set( const char *name, VImage value ); + VOption *set( const char *name, VImage *value ); + + void set_operation( VipsOperation *operation ); + void get_operation( VipsOperation *operation ); + +}; + +class VImage : VObject +{ +public: + VImage( VipsImage *image, VSteal steal = STEAL ) : + VObject( (VipsObject *) image, steal ) + { + } + + // an empty (NULL) VImage, eg. "VImage a;" + VImage() : + VObject( 0 ) + { + } + + VipsImage *get_image() + { + return( (VipsImage *) VObject::get_object() ); + } + + static VOption *option() + { + return( new VOption() ); + } + + static void call_option_string( const char *operation_name, + const char *option_string, VOption *options = 0 ) + throw( VError ); + static void call( const char *operation_name, VOption *options = 0 ) + throw( VError ); + + static VImage new_from_file( const char *name, VOption *options = 0 ) + throw( VError ); + + void write_to_file( const char *name, VOption *options = 0 ) + throw( VError ); + +#include "vips-operators.h" + +}; + +VIPS_NAMESPACE_END + +#endif /*VIPS_VIMAGE_H*/ diff --git a/cplusplus/include/vips/vips-operators.h b/cplusplus/include/vips/vips-operators.h index 4cf76864..6f75c822 100644 --- a/cplusplus/include/vips/vips-operators.h +++ b/cplusplus/include/vips/vips-operators.h @@ -1,3 +1 @@ - -VImage add( VImage add_in2, ... ) - throw( VError ) __attribute__((sentinel)); +VImage invert( VOption *options = 0 ) throw( VError ); diff --git a/cplusplus/include/vips/vips8 b/cplusplus/include/vips/vips8 index fa08fd7e..19f5b8f2 100644 --- a/cplusplus/include/vips/vips8 +++ b/cplusplus/include/vips/vips8 @@ -37,7 +37,7 @@ #define VIPS_NAMESPACE_START namespace vips8 { #define VIPS_NAMESPACE_END } -#include "VError.h" -#include "VImage.h" +#include "VError8.h" +#include "VImage8.h" #endif /*VIPS_CPLUSPLUS*/ diff --git a/cplusplus/try92.cc b/cplusplus/old/try92.cc similarity index 100% rename from cplusplus/try92.cc rename to cplusplus/old/try92.cc diff --git a/cplusplus/try93.cc b/cplusplus/old/try93.cc similarity index 100% rename from cplusplus/try93.cc rename to cplusplus/old/try93.cc diff --git a/cplusplus/vips-operators.cc b/cplusplus/vips-operators.cc index 27e360f8..0a644743 100644 --- a/cplusplus/vips-operators.cc +++ b/cplusplus/vips-operators.cc @@ -1,16 +1,14 @@ -VImage VImage::add( VImage in2, ... ) + +VImage VImage::invert( VOption *options ) throw( VError ) { - va_list ap; - VImage out; - int result; + VImage out; - va_start( ap, in2 ); - result = call_split( "add", ap, this, in2, &out ); - va_end( ap ); - - if( result ) - VError(); + call( "invert", + (options ? options : VImage::option())-> + set( "in", *this )-> + set( "out", &out ) ); return( out ); } + diff --git a/vips-cc.pc.in b/vips-cc.pc.in new file mode 100644 index 00000000..b5f7b14b --- /dev/null +++ b/vips-cc.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: vips-cc +Description: C++ API for vips8 image processing library +Version: @VERSION@ +Requires: vips = @VERSION@ +Libs: -L${libdir} -lvips-cc diff --git a/vipsCC.pc.in b/vipsCC.pc.in index 7175c53b..4484778a 100644 --- a/vipsCC.pc.in +++ b/vipsCC.pc.in @@ -4,7 +4,7 @@ libdir=@libdir@ includedir=@includedir@ Name: vipsCC -Description: C++ API for vips image processing library +Description: C++ API for vips7 image processing library Version: @VERSION@ Requires: vips = @VERSION@ Libs: -L${libdir} -lvipsCC