From 6864739351d5a7d1d777365a710c788e86ce570b Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 20 Dec 2011 10:10:53 +0000 Subject: [PATCH] move matio read to new system --- TODO | 10 +- configure.in | 6 + libvips/foreign/Makefile.am | 12 ++ libvips/foreign/foreign.c | 36 ++++ libvips/foreign/matlab.c | 305 +++++++++++++++++++++++++++++++++ libvips/foreign/matlab.h | 47 +++++ libvips/foreign/matload.c | 136 +++++++++++++++ libvips/foreign/ppm.c | 2 + libvips/format/matlab.c | 280 +----------------------------- libvips/include/vips/foreign.h | 3 + 10 files changed, 558 insertions(+), 279 deletions(-) create mode 100644 libvips/foreign/matlab.c create mode 100644 libvips/foreign/matlab.h create mode 100644 libvips/foreign/matload.c diff --git a/TODO b/TODO index 6e279db4..2729c603 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,8 @@ - vips2bufpng() is leaky -- radiance, matlab to go still +- test matio load + +- radiance to go still - saverawfd should be renamed saveraw_fd, cf. pngsave_buffer @@ -26,12 +28,6 @@ -- "header fred.png" does not work, since header uses im_open() which uses - VipsForeign - - - - - make the old format/vips.c into a stub as well? diff --git a/configure.in b/configure.in index 385d47c2..19be989a 100644 --- a/configure.in +++ b/configure.in @@ -484,6 +484,12 @@ if test x"$with_matio" != "xno"; then ]) fi +if test x"$with_openslide" = x"yes"; then + AM_CONDITIONAL(HAVE_MATIO, true) +else + AM_CONDITIONAL(HAVE_MATIO, false) +fi + # cfitsio AC_ARG_WITH([cfitsio], AS_HELP_STRING([--without-cfitsio], [build without cfitsio (default: test)])) diff --git a/libvips/foreign/Makefile.am b/libvips/foreign/Makefile.am index fe8765e1..88e9eec5 100644 --- a/libvips/foreign/Makefile.am +++ b/libvips/foreign/Makefile.am @@ -20,6 +20,18 @@ libforeign_la_SOURCES = \ EXTRA_DIST = +if HAVE_MATIO +libforeign_la_SOURCES += \ + matlab.h \ + matlab.c \ + matload.c +else +EXTRA_DIST += \ + matlab.h \ + matlab.c \ + matload.c +endif + if HAVE_MAGICK libforeign_la_SOURCES += \ magick.h \ diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 7d4fc670..7a5b1584 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -1194,6 +1194,7 @@ vips_foreign_write_options( VipsImage *in, const char *filename ) void vips_foreign_operation_init( void ) { + extern GType vips_foreign_load_mat_get_type( void ); extern GType vips_foreign_load_ppm_get_type( void ); extern GType vips_foreign_save_ppm_get_type( void ); extern GType vips_foreign_load_png_get_type( void ); @@ -1237,6 +1238,10 @@ vips_foreign_operation_init( void ) vips_foreign_save_png_buffer_get_type(); #endif /*HAVE_PNG*/ +#ifdef HAVE_MATIO + vips_foreign_load_mat_get_type(); +#endif /*HAVE_MATIO*/ + #ifdef HAVE_JPEG vips_foreign_load_jpeg_file_get_type(); vips_foreign_load_jpeg_buffer_get_type(); @@ -1870,3 +1875,34 @@ vips_pngsave_buffer( VipsImage *in, void **buf, size_t *len, ... ) return( result ); } + +/** + * vips_matload: + * @filename: file to load + * @out: output image + * @...: %NULL-terminated list of optional named arguments + * + * Read a Matlab save file into a VIPS image. + * + * This operation searches the save + * file for the first array variable with between 1 and 3 dimensions and loads + * it as an image. It will not handle complex images. It does not handle + * sparse matrices. + * + * See also: vips_image_new_from_file(). + * + * Returns: 0 on success, -1 on error. + */ +int +vips_matload( const char *filename, VipsImage **out, ... ) +{ + va_list ap; + int result; + + va_start( ap, out ); + result = vips_call_split( "matload", ap, filename, out ); + va_end( ap ); + + return( result ); +} + diff --git a/libvips/foreign/matlab.c b/libvips/foreign/matlab.c new file mode 100644 index 00000000..6c4e4d88 --- /dev/null +++ b/libvips/foreign/matlab.c @@ -0,0 +1,305 @@ +/* Read matlab save files with libmatio + * + * 4/8/09 + * - transpose on load, assemble planes into bands (thanks Mikhail) + */ + +/* + + 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 + + */ + +/* + + Remaining issues: + ++ it will not do complex images + ++ it will not handle sparse matricies + ++ it loads the first variable in the file with between 1 and 3 dimensions, + is this sensible behaviour? + ++ load only, no save + + */ + +/* +#define DEBUG + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ +#include + +#include +#include +#include + +#include +#include + +#include + +#include "matlab.h" + +/* What we track during a Mat-file read. + */ +typedef struct { + char *filename; + VipsImage *out; + + mat_t *mat; + matvar_t *var; +} Read; + +static void +read_destroy( Read *read ) +{ + VIPS_FREE( read->filename ); + VIPS_FREEF( Mat_VarFree, read->var ); + VIPS_FREEF( Mat_Close, read->mat ); + + vips_free( read ); +} + +static Read * +read_new( const char *filename, VipsImage *out ) +{ + Read *read; + + if( !(read = VIPS_NEW( NULL, Read )) ) + return( NULL ); + + read->filename = vips_strdup( NULL, filename ); + read->out = out; + read->mat = NULL; + read->var = NULL; + + if( !(read->mat = Mat_Open( filename, MAT_ACC_RDONLY )) ) { + vips_error( "mat2vips", + _( "unable to open \"%s\"" ), filename ); + read_destroy( read ); + return( NULL ); + } + + for(;;) { + if( !(read->var = Mat_VarReadNextInfo( read->mat )) ) { + vips_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; + + VIPS_FREEF( Mat_VarFree, read->var ); + } + + return( read ); +} + +/* Matlab classes -> VIPS band formats. + */ +static int mat2vips_formats[][2] = { + { MAT_C_UINT8, VIPS_FORMAT_UCHAR }, + { MAT_C_INT8, VIPS_FORMAT_CHAR }, + { MAT_C_UINT16, VIPS_FORMAT_USHORT }, + { MAT_C_INT16, VIPS_FORMAT_SHORT }, + { MAT_C_UINT32, VIPS_FORMAT_UINT }, + { MAT_C_INT32, VIPS_FORMAT_INT }, + { MAT_C_SINGLE, VIPS_FORMAT_FLOAT }, + { MAT_C_DOUBLE, VIPS_FORMAT_DOUBLE } +}; + +static int +mat2vips_get_header( matvar_t *var, VipsImage *im ) +{ + int width, height, bands; + VipsBandFormat format; + VipsInterpretation interpretation; + 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: + vips_error( "mat2vips", + _( "unsupported rank %d\n" ), var->rank ); + return( -1 ); + } + + if( bands > 1 ) + interpretation = VIPS_INTERPRETATION_MULTIBAND; + else + interpretation = VIPS_INTERPRETATION_B_W; + + for( i = 0; i < VIPS_NUMBER( mat2vips_formats ); i++ ) + if( mat2vips_formats[i][0] == var->class_type ) + break; + if( i == VIPS_NUMBER( mat2vips_formats ) ) { + vips_error( "mat2vips", _( "unsupported class type %d\n" ), + var->class_type ); + return( -1 ); + } + format = mat2vips_formats[i][1]; + + vips_image_init_fields( im, + width, height, bands, + format, + VIPS_CODING_NONE, interpretation, 1.0, 1.0 ); + + return( 0 ); +} + +int +vips__mat_header( const char *filename, VipsImage *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, VipsImage *im ) +{ + int y; + PEL *buffer; + const int es = VIPS_IMAGE_SIZEOF_ELEMENT( im ); + + /* Matlab images are plane-separate, so we have to assemble bands in + * image-size chunks. + */ + const int is = es * im->Xsize * im->Ysize; + + if( Mat_VarReadDataAll( mat, var ) ) { + vips_error( "mat2vips", "%s", + _( "Mat_VarReadDataAll failed" ) ); + return( -1 ); + } + + /* Matlab images are in columns, so we have to transpose into + * scanlines with this buffer. + */ + if( !(buffer = VIPS_ARRAY( im, VIPS_IMAGE_SIZEOF_LINE( im ), PEL )) ) + return( -1 ); + + for( y = 0; y < im->Ysize; y++ ) { + const PEL *p = var->data + y * es; + int x; + PEL *q; + + q = buffer; + for( x = 0; x < im->Xsize; x++ ) { + int b; + + for( b = 0; b < im->Bands; b++ ) { + const PEL *p2 = p + b * is; + int z; + + for( z = 0; z < es; z++ ) + q[z] = p2[z]; + + q += es; + } + + p += es * im->Ysize; + } + + if( vips_image_write_line( im, y, buffer ) ) + return( -1 ); + } + + return( 0 ); +} + +int +vips__mat_load( const char *filename, VipsImage *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 ); +} + +int +vips__mat_ismat( const char *filename ) +{ + mat_t *mat; + + if( !(mat = Mat_Open( filename, MAT_ACC_RDONLY )) ) + return( 0 ); + Mat_Close( mat ); + + return( 1 ); +} + +const char *vips__mat_suffs[] = { ".mat", NULL }; diff --git a/libvips/foreign/matlab.h b/libvips/foreign/matlab.h new file mode 100644 index 00000000..603dd491 --- /dev/null +++ b/libvips/foreign/matlab.h @@ -0,0 +1,47 @@ +/* common defs for matio read/write + */ + +/* + + Copyright (C) 1991-2005 The National Gallery + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU 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 General Public License for more details. + + You should have received a copy of the GNU 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 VIPS_MAT_H +#define VIPS_MAT_H + +#ifdef __cplusplus +extern "C" { +#endif /*__cplusplus*/ + +extern const char *vips__mat_suffs[]; + +int vips__mat_load( const char *filename, VipsImage *out ); +int vips__mat_header( const char *filename, VipsImage *out ); +int vips__mat_ismat( const char *filename ); + +#ifdef __cplusplus +} +#endif /*__cplusplus*/ + +#endif /*VIPS_MAT_H*/ diff --git a/libvips/foreign/matload.c b/libvips/foreign/matload.c new file mode 100644 index 00000000..a98905fb --- /dev/null +++ b/libvips/foreign/matload.c @@ -0,0 +1,136 @@ +/* load matlab from a file + * + * 5/12/11 + * - from tiffload.c + */ + +/* + + 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 + +#include +#include +#include + +#include +#include +#include + +#include "matlab.h" + +typedef struct _VipsForeignLoadMat { + VipsForeignLoad parent_object; + + /* Filename for load. + */ + char *filename; + +} VipsForeignLoadMat; + +typedef VipsForeignLoadClass VipsForeignLoadMatClass; + +G_DEFINE_TYPE( VipsForeignLoadMat, vips_foreign_load_mat, + VIPS_TYPE_FOREIGN_LOAD ); + +static VipsForeignFlags +vips_foreign_load_mat_get_flags_filename( const char *filename ) +{ + return( 0 ); +} + +static VipsForeignFlags +vips_foreign_load_mat_get_flags( VipsForeignLoad *load ) +{ + VipsForeignLoadMat *mat = (VipsForeignLoadMat *) load; + + return( vips_foreign_load_mat_get_flags_filename( mat->filename ) ); +} + +static int +vips_foreign_load_mat_header( VipsForeignLoad *load ) +{ + VipsForeignLoadMat *mat = (VipsForeignLoadMat *) load; + + if( vips__mat_header( mat->filename, load->out ) ) + return( -1 ); + + return( 0 ); +} + +static int +vips_foreign_load_mat_load( VipsForeignLoad *load ) +{ + VipsForeignLoadMat *mat = (VipsForeignLoadMat *) load; + + if( vips__mat_load( mat->filename, load->real ) ) + return( -1 ); + + return( 0 ); +} + +static void +vips_foreign_load_mat_class_init( VipsForeignLoadMatClass *class ) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS( class ); + VipsObjectClass *object_class = (VipsObjectClass *) class; + VipsForeignClass *foreign_class = (VipsForeignClass *) class; + VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class; + + gobject_class->set_property = vips_object_set_property; + gobject_class->get_property = vips_object_get_property; + + object_class->nickname = "matload"; + object_class->description = _( "load mat from file" ); + + foreign_class->suffs = vips__mat_suffs; + + load_class->is_a = vips__mat_ismat; + load_class->get_flags_filename = + vips_foreign_load_mat_get_flags_filename; + load_class->get_flags = vips_foreign_load_mat_get_flags; + load_class->header = vips_foreign_load_mat_header; + load_class->load = vips_foreign_load_mat_load; + + VIPS_ARG_STRING( class, "filename", 1, + _( "Filename" ), + _( "Filename to load from" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsForeignLoadMat, filename ), + NULL ); +} + +static void +vips_foreign_load_mat_init( VipsForeignLoadMat *mat ) +{ +} diff --git a/libvips/foreign/ppm.c b/libvips/foreign/ppm.c index 5447ba92..6c939e42 100644 --- a/libvips/foreign/ppm.c +++ b/libvips/foreign/ppm.c @@ -71,6 +71,8 @@ #include #include +#include "ppm.h" + /* The largest number/field/whatever we can read. */ #define MAX_THING (80) diff --git a/libvips/format/matlab.c b/libvips/format/matlab.c index 064fb5a1..93c06a7b 100644 --- a/libvips/format/matlab.c +++ b/libvips/format/matlab.c @@ -1,7 +1,7 @@ /* Read matlab save files with libmatio * - * 4/8/09 - * - transpose on load, assemble planes into bands (thanks Mikhail) + * 20/12/11 + * - just a compat stub */ /* @@ -30,279 +30,25 @@ */ -/* - - Remaining issues: - -+ it will not do complex images - -+ it will not handle sparse matricies - -+ it loads the first variable in the file with between 1 and 3 dimensions, - is this sensible behaviour? - -+ load only, no save - - */ - -/* -#define DEBUG - */ - #ifdef HAVE_CONFIG_H #include #endif /*HAVE_CONFIG_H*/ #include -#ifdef HAVE_MATIO - -#include -#include -#include - #include -#include -#include - -/* 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( "im_mat2vips", - _( "unable to open \"%s\"" ), filename ); - read_destroy( read ); - return( NULL ); - } - - for(;;) { - if( !(read->var = Mat_VarReadNextInfo( read->mat )) ) { - im_error( "im_mat2vips", - _( "no matrix variables in \"%s\"" ), - filename ); - read_destroy( read ); - return( NULL ); - } - -#ifdef DEBUG - printf( "im_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( "im_mat2vips", - _( "unsupported rank %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( "im_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; - PEL *buffer; - const int es = IM_IMAGE_SIZEOF_ELEMENT( im ); - - /* Matlab images are plane-separate, so we have to assemble bands in - * image-size chunks. - */ - const int is = es * im->Xsize * im->Ysize; - - if( Mat_VarReadDataAll( mat, var ) ) { - im_error( "im_mat2vips", "%s", - _( "Mat_VarReadDataAll failed" ) ); - return( -1 ); - } - if( im_outcheck( im ) || - im_setupout( im ) ) - return( -1 ); - - /* Matlab images are in columns, so we have to transpose into - * scanlines with this buffer. - */ - if( !(buffer = IM_ARRAY( im, IM_IMAGE_SIZEOF_LINE( im ), PEL )) ) - return( -1 ); - - for( y = 0; y < im->Ysize; y++ ) { - const PEL *p = var->data + y * es; - int x; - PEL *q; - - q = buffer; - for( x = 0; x < im->Xsize; x++ ) { - int b; - - for( b = 0; b < im->Bands; b++ ) { - const PEL *p2 = p + b * is; - int z; - - for( z = 0; z < es; z++ ) - q[z] = p2[z]; - - q += es; - } - - p += es * im->Ysize; - } - - if( im_writeline( y, im, buffer ) ) - return( -1 ); - } - - return( 0 ); -} - -/** - * im_mat2vips: - * @filename: file to load - * @out: image to write to - * - * Read a Matlab save file into a VIPS image. - * - * This operation searches the save - * file for the first array variable with between 1 and 3 dimensions and loads - * it as an image. It will not handle complex images. It does not handle - * sparse matrices. - * - * See also: #VipsFormat. - * - * Returns: 0 on success, -1 on error. - */ int im_mat2vips( const char *filename, IMAGE *out ) { - Read *read; + VipsImage *t; -#ifdef DEBUG - printf( "mat2vips: reading \"%s\"\n", filename ); -#endif /*DEBUG*/ - - if( !(read = read_new( filename, out )) ) + if( vips_ppmload( filename, &t, NULL ) ) return( -1 ); - if( mat2vips_get_header( read->var, read->out ) || - mat2vips_get_data( read->mat, read->var, read->out ) ) { - read_destroy( read ); + if( vips_image_write( t, out ) ) { + g_object_unref( t ); return( -1 ); } - read_destroy( read ); + g_object_unref( t ); return( 0 ); } @@ -310,19 +56,11 @@ im_mat2vips( const char *filename, IMAGE *out ) static int ismat( const char *filename ) { - mat_t *mat; - - if( !(mat = Mat_Open( filename, MAT_ACC_RDONLY )) ) - return( 0 ); - Mat_Close( mat ); - - return( 1 ); + return( vips_foreign_is_a( "matload", filename ) ); } static const char *mat_suffs[] = { ".mat", NULL }; -/* mat format adds no new members. - */ typedef VipsFormat VipsFormatMat; typedef VipsFormatClass VipsFormatMatClass; @@ -336,7 +74,6 @@ vips_format_mat_class_init( VipsFormatMatClass *class ) object_class->description = _( "Matlab" ); format_class->is_a = ismat; - format_class->header = mat2vips_header; format_class->load = im_mat2vips; format_class->save = NULL; format_class->suffs = mat_suffs; @@ -349,4 +86,3 @@ vips_format_mat_init( VipsFormatMat *object ) G_DEFINE_TYPE( VipsFormatMat, vips_format_mat, VIPS_TYPE_FORMAT ); -#endif /*HAVE_MATIO*/ diff --git a/libvips/include/vips/foreign.h b/libvips/include/vips/foreign.h index 98470c3d..a8ab2dfe 100644 --- a/libvips/include/vips/foreign.h +++ b/libvips/include/vips/foreign.h @@ -361,6 +361,9 @@ int vips_ppmload( const char *filename, VipsImage **out, ... ) int vips_ppmsave( VipsImage *in, const char *filename, ... ) __attribute__((sentinel)); +int vips_matload( const char *filename, VipsImage **out, ... ) + __attribute__((sentinel)); + #ifdef __cplusplus } #endif /*__cplusplus*/