package up new vips8 C++ API

This commit is contained in:
John Cupitt 2014-10-27 13:41:44 +00:00
parent 266e120676
commit 4f588ce908
18 changed files with 494 additions and 683 deletions

View File

@ -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 \

View File

@ -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

View File

@ -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

View File

@ -32,69 +32,21 @@
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <vips/vips.h>
#include <vips/vipscpp.h>
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/
#include <vips/vips8>
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

View File

@ -32,303 +32,221 @@
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vips/vips8>
#include <vips/vips.h>
#include <vips/debug.h>
#include <gobject/gvaluecollector.h>
#include "include/vips/vips8"
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#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<Pair *>::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<VImage *>(
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<Pair *>::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<Pair *>::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 );
}

BIN
cplusplus/examples/a.out Executable file

Binary file not shown.

View File

@ -0,0 +1,54 @@
/*
* compile with:
*
* g++ -g -Wall invert.cc `pkg-config vips-cc --cflags --libs`
*
*/
#include <vips/vips8>
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 );
}

View File

@ -1,6 +1,6 @@
pkginclude_HEADERS = \
VError.h \
VImage.h \
VError8.h \
VImage8.h \
vips8 \
vips-operators.h

View File

@ -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 <string>
# include <iosfwd>
# include <exception>
#endif /*!SWIG*/
#include <string>
#include <iosfwd>
#include <exception>
#include <vips/vips.h>
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*/

View File

@ -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 <list>
#include <complex>
#include <vector>
#include <vips/vips.h>
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*/

View File

@ -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 <list>
#include <complex>
#include <vector>
#include <vips/vips.h>
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<Pair *> 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*/

View File

@ -1,3 +1 @@
VImage add( VImage add_in2, ... )
throw( VError ) __attribute__((sentinel));
VImage invert( VOption *options = 0 ) throw( VError );

View File

@ -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*/

View File

@ -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 );
}

10
vips-cc.pc.in Normal file
View File

@ -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

View File

@ -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