diff --git a/ChangeLog b/ChangeLog index 3b3f4007..9291d06f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -38,6 +38,8 @@ - added vips_object_new - resamplers/interpolators now in a resample package - removed yafrnohalo.c +- added matio as a dependency +- added Matlab save file read 11/9/08 started 7.16.3 - oop typo in manpage for im_project() diff --git a/TODO b/TODO index 1a69157d..6d278e3b 100644 --- a/TODO +++ b/TODO @@ -22,7 +22,11 @@ - update the Portfiles on the mac and on the website from the macports ones -- can we add .mat file import? see libmatio, and PDFs on sourceforge +- try + + vips im_copy skdjjfhwlfj t.v + + stupid error message (does not say "file not found") - add HDR support? diff --git a/configure.in b/configure.in index a4f76df7..703a877b 100644 --- a/configure.in +++ b/configure.in @@ -305,6 +305,20 @@ if test x"$with_OpenEXR" != "xno"; then ]) fi +# matio +AC_ARG_WITH([matio], + AS_HELP_STRING([--without-matio], [build without matio (default: test)])) + +if test x"$with_matio" != "xno"; then + PKG_CHECK_MODULES(MATIO, matio, + [AC_DEFINE(HAVE_MATIO,1,[define if you have matio installed.]) + with_matio=yes + PACKAGES_USED="$PACKAGES_USED matio"], + [AC_MSG_WARN([matio not found; disabling matio support]) + with_matio=no + ]) +fi + # pangoft2 AC_ARG_WITH([pangoft2], AS_HELP_STRING([--without-pangoft2], @@ -451,13 +465,13 @@ fi # Gather all up for VIPS_CFLAGS, VIPS_INCLUDES and VIPS_LIBS # sort includes to get longer, more specific dirs first # helps, for example, selecting graphicsmagick over imagemagick -VIPS_CFLAGS=`for i in $VIPS_CFLAGS $GTHREAD_CFLAGS $REQUIRED_CFLAGS $PANGOFT2_CFLAGS $FFTW3_CFLAGS $MAGICK_CFLAGS $PNG_CFLAGS $EXIF_CFLAGS $OPENEXR_CFLAGS $LIBOIL_CFLAGS -do - echo $i +VIPS_CFLAGS=`for i in $VIPS_CFLAGS $GTHREAD_CFLAGS $REQUIRED_CFLAGS $PANGOFT2_CFLAGS $FFTW3_CFLAGS $MAGICK_CFLAGS $PNG_CFLAGS $EXIF_CFLAGS $MATIO_CFLAGS $OPENEXR_CFLAGS $LIBOIL_CFLAGS +do + echo $i done | sort -ru` VIPS_CFLAGS=`echo $VIPS_CFLAGS` VIPS_INCLUDES="$PNG_INCLUDES $TIFF_INCLUDES $ZIP_INCLUDES $JPEG_INCLUDES $FFTW_INCLUDES $LCMS_INCLUDES" -VIPS_LIBS="$MAGICK_LIBS $PNG_LIBS $TIFF_LIBS $ZIP_LIBS $JPEG_LIBS $GTHREAD_LIBS $REQUIRED_LIBS $PANGOFT2_LIBS $FFTW3_LIBS $FFTW_LIBS $LCMS_LIBS $LIBOIL_LIBS $OPENEXR_LIBS $EXIF_LIBS -lm $CIMG_LIBS" +VIPS_LIBS="$MAGICK_LIBS $PNG_LIBS $TIFF_LIBS $ZIP_LIBS $JPEG_LIBS $GTHREAD_LIBS $REQUIRED_LIBS $PANGOFT2_LIBS $FFTW3_LIBS $FFTW_LIBS $LCMS_LIBS $LIBOIL_LIBS $OPENEXR_LIBS $MATIO_LIBS $EXIF_LIBS -lm $CIMG_LIBS" AC_SUBST(VIPS_CFLAGS) AC_SUBST(VIPS_INCLUDES) @@ -465,9 +479,9 @@ AC_SUBST(VIPS_LIBS) AC_SUBST(PACKAGES_USED) AC_OUTPUT([ - vips-7.17.pc - vipsCC-7.17.pc - vips-7.17.spec + vips-$IM_MAJOR_VERSION.$IM_MINOR_VERSION.pc + vipsCC-$IM_MAJOR_VERSION.$IM_MINOR_VERSION.pc + vips-$IM_MAJOR_VERSION.$IM_MINOR_VERSION.spec Makefile include/vips/version.h include/Makefile @@ -532,6 +546,7 @@ file import with libMagick: $with_magick accelerate loops with liboil: $with_liboil ICC profile support with lcms: $with_lcms file import with OpenEXR: $with_OpenEXR +file import with matio: $with_matio text rendering with pangoft2: $with_pangoft2 file import/export with libpng: $with_png file import/export with libtiff: $with_tiff diff --git a/libsrc/format/Makefile.am b/libsrc/format/Makefile.am index 0fdf0471..82261236 100644 --- a/libsrc/format/Makefile.am +++ b/libsrc/format/Makefile.am @@ -8,6 +8,7 @@ libformat_la_SOURCES = \ im_csv2vips.c \ im_exr2vips.c \ im_jpeg2vips.c \ + im_mat2vips.c \ im_magick2vips.c \ im_png2vips.c \ im_ppm2vips.c \ diff --git a/libsrc/format/format.c b/libsrc/format/format.c index e889f5d6..e6ee41cb 100644 --- a/libsrc/format/format.c +++ b/libsrc/format/format.c @@ -213,6 +213,10 @@ im__format_init( void ) extern GType vips_format_png_get_type(); vips_format_png_get_type(); #endif /*HAVE_PNG*/ +#ifdef HAVE_MATIO + extern GType vips_format_mat_get_type(); + vips_format_mat_get_type(); +#endif /*HAVE_MATIO*/ vips_format_csv_get_type(); vips_format_ppm_get_type(); vips_format_analyze_get_type(); diff --git a/libsrc/format/im_mat2vips.c b/libsrc/format/im_mat2vips.c new file mode 100644 index 00000000..5e4f2076 --- /dev/null +++ b/libsrc/format/im_mat2vips.c @@ -0,0 +1,287 @@ +/* Read matlab save files with libmatio + */ + +/* + + 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 + + */ + +/* +#define DEBUG + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ +#include + +#ifdef HAVE_MATIO + +#include +#include +#include + +#include +#include + +#include + +#ifdef WITH_DMALLOC +#include +#endif /*WITH_DMALLOC*/ + +/* What we track during a Mat-file read. + */ +typedef struct { + char *filename; + IMAGE *out; + + mat_t *mat; + matvar_t *var; +} Read; + +static void +read_destroy( Read *read ) +{ + IM_FREE( read->filename ); + IM_FREEF( Mat_VarFree, read->var ); + IM_FREEF( Mat_Close, read->mat ); + + im_free( read ); +} + +static Read * +read_new( const char *filename, IMAGE *out ) +{ + Read *read; + + if( !(read = IM_NEW( NULL, Read )) ) + return( NULL ); + + read->filename = im_strdup( NULL, filename ); + read->out = out; + read->mat = NULL; + read->var = NULL; + + if( !(read->mat = Mat_Open( filename, MAT_ACC_RDONLY )) ) { + im_error( "mat2vips", + _( "unable to open \"%s\"" ), filename ); + read_destroy( read ); + return( NULL ); + } + + for(;;) { + if( !(read->var = Mat_VarReadNextInfo( read->mat )) ) { + im_error( "mat2vips", + _( "no matrix variables in \"%s\"" ), + filename ); + read_destroy( read ); + return( NULL ); + } + +#ifdef DEBUG + printf( "mat2vips: seen:\n" ); + printf( "var->name == %s\n", read->var->name ); + printf( "var->class_type == %d\n", read->var->class_type ); + printf( "var->rank == %d\n", read->var->rank ); +#endif /*DEBUG*/ + + /* Vector to colour image is OK for us. + */ + if( read->var->rank >= 1 && read->var->rank <= 3 ) + break; + + IM_FREEF( Mat_VarFree, read->var ); + } + + return( read ); +} + +/* Matlab classes -> VIPS band formats. + */ +static int mat2vips_formats[][2] = { + { MAT_C_UINT8, IM_BANDFMT_UCHAR }, + { MAT_C_INT8, IM_BANDFMT_CHAR }, + { MAT_C_UINT16, IM_BANDFMT_USHORT }, + { MAT_C_INT16, IM_BANDFMT_SHORT }, + { MAT_C_UINT32, IM_BANDFMT_UINT }, + { MAT_C_INT32, IM_BANDFMT_INT }, + { MAT_C_SINGLE, IM_BANDFMT_FLOAT }, + { MAT_C_DOUBLE, IM_BANDFMT_DOUBLE } +}; + +static int +mat2vips_get_header( matvar_t *var, IMAGE *im ) +{ + int width, height, bands, format, type; + int i; + + width = 1; + height = 1; + bands = 1; + switch( var->rank ) { + case 3: + bands = var->dims[2]; + + case 2: + height = var->dims[1]; + + case 1: + width = var->dims[0]; + break; + + default: + im_error( "mat2vips", _( "unsupported bands %d\n" ), + var->rank ); + return( -1 ); + } + + if( bands > 1 ) + type = IM_TYPE_MULTIBAND; + else + type = IM_TYPE_B_W; + + for( i = 0; i < IM_NUMBER( mat2vips_formats ); i++ ) + if( mat2vips_formats[i][0] == var->class_type ) + break; + if( i == IM_NUMBER( mat2vips_formats ) ) { + im_error( "mat2vips", _( "unsupported class type %d\n" ), + var->class_type ); + return( -1 ); + } + format = mat2vips_formats[i][1]; + + im_initdesc( im, + width, height, bands, + im_bits_of_fmt( format ), format, + IM_CODING_NONE, type, 1.0, 1.0, 0, 0 ); + + return( 0 ); +} + +static int +mat2vips_header( const char *filename, IMAGE *out ) +{ + Read *read; + +#ifdef DEBUG + printf( "mat2vips_header: reading \"%s\"\n", filename ); +#endif /*DEBUG*/ + + if( !(read = read_new( filename, out )) ) + return( -1 ); + if( mat2vips_get_header( read->var, read->out ) ) { + read_destroy( read ); + return( -1 ); + } + read_destroy( read ); + + return( 0 ); +} + +static int +mat2vips_get_data( mat_t *mat, matvar_t *var, IMAGE *im ) +{ + int y; + + if( Mat_VarReadDataAll( mat, var ) ) { + im_error( "mat2vips", "%s", _( "Mat_VarReadDataAll failed" ) ); + return( -1 ); + } + if( im_outcheck( im ) || + im_setupout( im ) ) + return( -1 ); + + for( y = 0; y < im->Ysize; y++ ) + if( im_writeline( y, im, + var->data + y * IM_IMAGE_SIZEOF_LINE( im ) ) ) + return( -1 ); + + return( 0 ); +} + +static int +mat2vips( const char *filename, IMAGE *out ) +{ + Read *read; + +#ifdef DEBUG + printf( "mat2vips: reading \"%s\"\n", filename ); +#endif /*DEBUG*/ + + if( !(read = read_new( filename, out )) ) + return( -1 ); + if( mat2vips_get_header( read->var, read->out ) || + mat2vips_get_data( read->mat, read->var, read->out ) ) { + read_destroy( read ); + return( -1 ); + } + read_destroy( read ); + + return( 0 ); +} + +static int +ismat( const char *filename ) +{ + mat_t *mat; + + if( !(mat = Mat_Open( filename, MAT_ACC_RDONLY )) ) + return( 0 ); + Mat_Close( mat ); + + return( 1 ); +} + +static const char *mat_suffs[] = { ".mat", NULL }; + +/* mat format adds no new members. + */ +typedef VipsFormat VipsFormatMat; +typedef VipsFormatClass VipsFormatMatClass; + +static void +vips_format_mat_class_init( VipsFormatMatClass *class ) +{ + VipsObjectClass *object_class = (VipsObjectClass *) class; + VipsFormatClass *format_class = (VipsFormatClass *) class; + + object_class->nickname = "mat"; + object_class->description = _( "Matlab" ); + + format_class->is_a = ismat; + format_class->header = mat2vips_header; + format_class->load = mat2vips; + format_class->save = NULL; + format_class->suffs = mat_suffs; +} + +static void +vips_format_mat_init( VipsFormatMat *object ) +{ +} + +G_DEFINE_TYPE( VipsFormatMat, vips_format_mat, VIPS_TYPE_FORMAT ); + +#endif /*HAVE_MATIO*/ diff --git a/libsrc/format/im_png2vips.c b/libsrc/format/im_png2vips.c index 6428883d..1d2328d1 100644 --- a/libsrc/format/im_png2vips.c +++ b/libsrc/format/im_png2vips.c @@ -107,24 +107,12 @@ typedef struct { static void read_destroy( Read *read ) { - if( read->name ) { - im_free( read->name ); - read->name = NULL; - } - if( read->fp ) { - fclose( read->fp ); - read->fp = NULL; - } + IM_FREE( read->name ); + IM_FREEF( fclose, read->fp ); if( read->pPng ) png_destroy_read_struct( &read->pPng, &read->pInfo, NULL ); - if( read->row_pointer ) { - im_free( read->row_pointer ); - read->row_pointer = NULL; - } - if( read->data ) { - im_free( read->data ); - read->data = NULL; - } + IM_FREE( read->row_pointer ); + IM_FREE( read->data ); im_free( read ); }