diff --git a/ChangeLog b/ChangeLog index 3ca5beda..01373bea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ 25/1/08 started 7.14.0 - bump all version numbers for new stable -- better CMYK JPEG read +- better CMYK JPEG read (thanks Ole) +- add __str__ to VError in Python (thanks Ole) +- revert the dynamic wrapping for Python :-( next version! +- added VImage::convert2disc (thanks Ole) 12/12/07 started 7.13.3 - added "include " to VImage.cc to help gcc 4.3 diff --git a/doc/src/vimage.tex b/doc/src/vimage.tex index c897725f..a32fe02e 100644 --- a/doc/src/vimage.tex +++ b/doc/src/vimage.tex @@ -99,6 +99,25 @@ disc with deflate compression. See the manual page for \verb+im_open(3)+ for details of all the file formats and conversions available. +\subsection{Large files} + +Opening large files in formats like JPEG which do not support random access +can use large amounts of memory, since the file has to be decompressed before +it can be used. + +The \verb+convert2disc()+ member lets you decompress to a disc file rather +than to memory. For example: + +\begin{verbatim} +VImage fred = VImage::convert2disc( "im_jpeg2vips", + "file.jpg", "temp.v" ); +\end{verbatim} + +/noindent +Will decompress to the file \verb+temp.v+, then open that and return a +reference to it. You will need to delete the file once you are finished with +it. + \subsection{Projection functions} A set of member functions of \verb+VImage+ provide access to the fields in diff --git a/include/vips/VImage.h b/include/vips/VImage.h index 5ee2b3bf..345d9eb3 100644 --- a/include/vips/VImage.h +++ b/include/vips/VImage.h @@ -192,6 +192,15 @@ public: 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. + // FIXME ... what a hack, replace this with something better + static VImage convert2disc( const char* convert, + const char* in, const char* disc ) throw( VError ); + // Copy constructor VImage( const VImage &a ); @@ -238,13 +247,9 @@ public: void initdesc( int, int, int, TBandFmt, TCoding, TType, float = 1.0, float = 1.0, int = 0, int = 0 ) throw( VError ); -/* Bindings wrap databased operations at runtime using reflection. - */ -#ifndef SWIG /* Insert automatically generated headers. */ #include "vipsc++.h" -#endif /*SWIG*/ /* No point getting SWIG to wrap these ... we do this by hand later so we can * handle things like "a + 12" correctly. diff --git a/libsrcCC/VImage.cc b/libsrcCC/VImage.cc index 63a42e24..51195620 100644 --- a/libsrcCC/VImage.cc +++ b/libsrcCC/VImage.cc @@ -141,7 +141,7 @@ void VImage::refblock::removeref() throw( VError ) delete this; } -// Init with name ... means open for read. +// Init with name ... mode defaults to "r" VImage::VImage( const char *name, const char *mode ) throw( VError ) { _ref = new refblock; @@ -244,6 +244,22 @@ void VImage::debug_print() im_printdesc( image() ); } +// Like jpeg2vips, but convert to a disc file rather than to memory +// We can handle huge files without running out of RAM +VImage VImage::convert2disc( const char* convert, + const char* in, const char* disc ) throw( VError ) +{ + VImage out( disc, "w" ); + + Vargv _vec( convert ); + + _vec.data(0) = (im_object) in; + _vec.data(1) = out.image(); + _vec.call(); + + return( out ); +} + // Write this to a VImage VImage VImage::write( VImage out ) throw( VError ) { diff --git a/python/vipsCC/Makefile.am b/python/vipsCC/Makefile.am index b4c3d3d4..679c9120 100644 --- a/python/vipsCC/Makefile.am +++ b/python/vipsCC/Makefile.am @@ -1,5 +1,3 @@ - - INCLUDES = -I${top_srcdir}/include @VIPS_CFLAGS@ @VIPS_INCLUDES@ @PYTHON_INCLUDES@ # we install to a directory inside the python area, since we are a module @@ -10,8 +8,13 @@ vipscc_PYTHON = VImage.py VDisplay.py VError.py VMask.py __init__.py # I tried making a suffix rule for this (and defining SUFFIXES) but I couldn;t # get it to work, how annoying # FIXME at some point +# +# need an expanded VImage.h ... SWIG's preprocessor b0rks on includes inside +# class definitions vimagemodule.cxx: VImage.i + cpp -DSWIG -E $(top_srcdir)/include/vips/VImage.h > VImage.h swig -python -c++ -interface $(@:.cxx=) -I$(top_srcdir)/include -o $@ $< + vdisplaymodule.cxx: VDisplay.i swig -python -c++ -interface $(@:.cxx=) -I$(top_srcdir)/include -o $@ $< verrormodule.cxx: VError.i @@ -38,7 +41,7 @@ vmaskmodule_la_LIBADD = ../../libsrcCC/libvipsCC.la $(VIPS_LIBS) nodist_vmaskmodule_la_SOURCES = vmaskmodule.cxx CLEANFILES = \ - vimagemodule.cxx \ + vimagemodule.cxx VImage.h \ verrormodule.cxx vdisplaymodule.cxx vmaskmodule.cxx \ VImage.py VDisplay.py VError.py VMask.py diff --git a/python/vipsCC/VError.i b/python/vipsCC/VError.i index 084eaa62..779c66d8 100644 --- a/python/vipsCC/VError.i +++ b/python/vipsCC/VError.i @@ -10,3 +10,10 @@ %include "std_string.i" %include vips/VError.h + +%extend vips::VError { + const char *__str__ () { + return $self->what (); + } +} + diff --git a/python/vipsCC/VImage.i b/python/vipsCC/VImage.i index f070d325..69da8c93 100644 --- a/python/vipsCC/VImage.i +++ b/python/vipsCC/VImage.i @@ -13,13 +13,6 @@ */ %rename(__assign__) vips::VImage::operator=; -/* We wrap the C++ VImage class as VImage_core, then write the user-visible - * VImage class ourselves with a %pythoncode (see below). Our hand-made VImage - * class wraps all the operators from the VIPS image operation database via - * __getattr__. - */ -%rename(VImage_core) VImage; - %include "std_list.i" %include "std_complex.i" %include "std_vector.i" @@ -35,42 +28,10 @@ namespace std { %template(ImageVector) vector; } -%include vips/VImage.h - -/* Search for a VIPS operation that matches a name and a set of args. +/* Need the expanded VImage.h in this directory, rather than the usual + * vips/VImage.h. SWIG b0rks on #include inside class definitions. */ -%inline %{ - -/* We need to wrap by hand, hmm - */ - -%} - -/* Now wrap SWIG's VImage_core with our own VImage class which does operations - * from the VIPS operation database. - */ -%pythoncode %{ -# proxy class to hold a method name during call -class VImage_method: - def __init__ (self,name): - self.method = name - - def __call__ (self, obj_to_call, arguments): - method = obj_to_call.__getattr__ (self.method) - print "VImage_method: calling ", self.method - print " with args ", arguments - method (arguments) - -class VImage (VImage_core): - def __init (self, *args): - VImage_core.__init__ (self, *args) - def __getattr__ (self, name): - print "VImage getattr: ", name - if (is_a_valid_method (name)): - return VImage_method (name) - else: - raise AttributeError ("unknown method %s" % name) -%} +%include VImage.h /* Helper code for vips_init(). */