From 65ed140ae308638096c371f6e6ff3177f4c249be Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 14 Dec 2011 22:51:14 +0000 Subject: [PATCH] move im_raw2vips() to a class --- ChangeLog | 2 +- TODO | 3 + libvips/foreign/Makefile.am | 1 + libvips/foreign/foreign.c | 12 +++ libvips/foreign/rawload.c | 191 +++++++++++++++++++++++++++++++++ libvips/foreign/vipsload.c | 16 ++- libvips/include/vips/foreign.h | 4 + 7 files changed, 224 insertions(+), 5 deletions(-) create mode 100644 libvips/foreign/rawload.c diff --git a/ChangeLog b/ChangeLog index b8a00e1d..b08790f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,7 +14,7 @@ im_pow*(), im_exp*(), im_ifthenelse(), im_blend(), im_c2amph(), im_c2rect(), im_bandmean(), im_c2real(), im_c2imag(), im_ri2c(), im_jpeg*2vips(), im_vips2jpeg*(), im_tiff2vips(), im_vips2tiff(), im_exr2vips(), - im_fits2vips(), im_vips2fits(), im_analyze2vips() + im_fits2vips(), im_vips2fits(), im_analyze2vips(), im_raw2vips() redone as classes - added argument priorites to help control arg ordering - generate has a 'stop' param to signal successful early termination diff --git a/TODO b/TODO index f1fa3cc5..8e205c16 100644 --- a/TODO +++ b/TODO @@ -2,6 +2,9 @@ - test analyze load +- make sure we have a get_flags_filename everywhere + + - "header fred.png" does not work, since header uses im_open() which uses diff --git a/libvips/foreign/Makefile.am b/libvips/foreign/Makefile.am index 8f9cd59f..896854ea 100644 --- a/libvips/foreign/Makefile.am +++ b/libvips/foreign/Makefile.am @@ -1,6 +1,7 @@ noinst_LTLIBRARIES = libforeign.la libforeign_la_SOURCES = \ + rawload.c \ vipssave.c \ vipsload.c \ analyzeload.c \ diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index ed031f9a..ff2b9c6a 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -358,6 +358,16 @@ vips_foreign_load_print_class( VipsObjectClass *object_class, VipsBuf *buf ) vips_buf_appends( buf, ", header" ); if( class->load ) vips_buf_appends( buf, ", load" ); + + /* Sanity: it's OK to have get_flags() and get_flags_filename() both + * NULL or both not-NULL. + */ + g_assert( (void *) class->get_flags != + (void *) class->get_flags_filename ); + + /* You can omit ->load(), you must not omit ->header(). + */ + g_assert( class->header ); } /* Can this VipsForeign open this file? @@ -1168,6 +1178,7 @@ vips_foreign_operation_init( void ) extern GType vips_foreign_save_tiff_get_type( void ); extern GType vips_foreign_load_vips_get_type( void ); extern GType vips_foreign_save_vips_get_type( void ); + extern GType vips_foreign_load_raw_get_type( void ); #ifdef HAVE_JPEG vips_foreign_load_jpeg_file_get_type(); @@ -1196,6 +1207,7 @@ vips_foreign_operation_init( void ) #endif /*HAVE_OPENEXR*/ vips_foreign_load_analyze_get_type(); + vips_foreign_load_raw_get_type(); vips_foreign_load_vips_get_type(); vips_foreign_save_vips_get_type(); } diff --git a/libvips/foreign/rawload.c b/libvips/foreign/rawload.c new file mode 100644 index 00000000..3830a715 --- /dev/null +++ b/libvips/foreign/rawload.c @@ -0,0 +1,191 @@ +/* load raw data from a file + * + * 14/12/11 + */ + +/* + + 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 + +typedef struct _VipsForeignLoadRaw { + VipsForeignLoad parent_object; + + char *filename; + int width; + int height; + int bands; + guint64 offset; +} VipsForeignLoadRaw; + +typedef VipsForeignLoadClass VipsForeignLoadRawClass; + +G_DEFINE_TYPE( VipsForeignLoadRaw, vips_foreign_load_raw, + VIPS_TYPE_FOREIGN_LOAD ); + +static VipsForeignFlags +vips_foreign_load_raw_get_flags( VipsForeignLoad *load ) +{ + return( VIPS_FOREIGN_PARTIAL ); +} + +static VipsForeignFlags +vips_foreign_load_raw_get_flags_filename( const char *filename ) +{ + return( VIPS_FOREIGN_PARTIAL ); +} + +static int +vips_foreign_load_raw_header( VipsForeignLoad *load ) +{ + VipsForeignLoadRaw *raw = (VipsForeignLoadRaw *) load; + VipsImage *out; + VipsImage *out2; + + if( !(out2 = vips_image_new_from_file_raw( raw->filename, + raw->width, raw->height, raw->bands, raw->offset )) ) + return( -1 ); + + /* Remove the @out that's there now. + */ + g_object_get( load, "out", &out, NULL ); + g_object_unref( out ); + g_object_unref( out ); + + g_object_set( load, "out", out2, NULL ); + + return( 0 ); +} + +static void +vips_foreign_load_raw_class_init( VipsForeignLoadRawClass *class ) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS( class ); + VipsObjectClass *object_class = (VipsObjectClass *) 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 = "rawload"; + object_class->description = _( "load raw data from a file" ); + + load_class->get_flags = vips_foreign_load_raw_get_flags; + load_class->get_flags_filename = + vips_foreign_load_raw_get_flags_filename; + load_class->header = vips_foreign_load_raw_header; + + VIPS_ARG_STRING( class, "filename", 1, + _( "Filename" ), + _( "Filename to load from" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsForeignLoadRaw, filename ), + NULL ); + + VIPS_ARG_INT( class, "width", 10, + _( "Width" ), + _( "Image width in pixels" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsForeignLoadRaw, width ), + 0, 1000000, 0 ); + + VIPS_ARG_INT( class, "height", 11, + _( "Height" ), + _( "Image height in pixels" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsForeignLoadRaw, height ), + 0, 1000000, 0 ); + + VIPS_ARG_INT( class, "bands", 12, + _( "Bands" ), + _( "Number of bands in image" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsForeignLoadRaw, bands ), + 0, 1000000, 0 ); + + VIPS_ARG_UINT64( class, "offset", 13, + _( "Size of header" ), + _( "Offset in bytes from start of file" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsForeignLoadRaw, offset ), + 0, 100000000000, 0 ); + +} + +static void +vips_foreign_load_raw_init( VipsForeignLoadRaw *raw ) +{ +} + +/** + * vips_rawload: + * @filename: file to load + * @out: output image + * @width: width of image in pixels + * @height: height of image in pixels + * @bands: number of image bands + * @offset: offset in bytes from start of file + * @...: %NULL-terminated list of optional named arguments + * + * This operation mmaps the file, setting @out so that access to that + * image will read from the file. + * + * Use functions like vips_copy() to set the pixel type, byte ordering + * and so on. + * + * See also: vips_image_new_from_file(). + * + * Returns: 0 on success, -1 on error. + */ +int +vips_rawload( const char *filename, VipsImage **out, + int width, int height, int bands, ... ) +{ + va_list ap; + int result; + + va_start( ap, bands ); + result = vips_call_split( "rawload", ap, + filename, out, width, height, bands ); + va_end( ap ); + + return( result ); +} + + diff --git a/libvips/foreign/vipsload.c b/libvips/foreign/vipsload.c index 2716f98d..49292244 100644 --- a/libvips/foreign/vipsload.c +++ b/libvips/foreign/vipsload.c @@ -63,19 +63,26 @@ vips_foreign_load_vips_is_a( const char *filename ) } static VipsForeignFlags -vips_foreign_load_vips_get_flags( VipsForeignLoad *load ) +vips_foreign_load_vips_get_flags_filename( const char *filename ) { - VipsForeignLoadVips *vips = (VipsForeignLoadVips *) load; VipsForeignFlags flags; flags = VIPS_FOREIGN_PARTIAL; - if( vips__file_magic( vips->filename ) == VIPS_MAGIC_SPARC ) + if( vips__file_magic( filename ) == VIPS_MAGIC_SPARC ) flags |= VIPS_FOREIGN_BIGENDIAN; return( flags ); } +static VipsForeignFlags +vips_foreign_load_vips_get_flags( VipsForeignLoad *load ) +{ + VipsForeignLoadVips *vips = (VipsForeignLoadVips *) load; + + return( vips_foreign_load_vips_get_flags_filename( vips->filename ) ); +} + static int vips_foreign_load_vips_header( VipsForeignLoad *load ) { @@ -117,6 +124,8 @@ vips_foreign_load_vips_class_init( VipsForeignLoadVipsClass *class ) load_class->is_a = vips_foreign_load_vips_is_a; load_class->get_flags = vips_foreign_load_vips_get_flags; + load_class->get_flags_filename = + vips_foreign_load_vips_get_flags_filename; load_class->header = vips_foreign_load_vips_header; load_class->load = NULL; @@ -132,4 +141,3 @@ static void vips_foreign_load_vips_init( VipsForeignLoadVips *vips ) { } - diff --git a/libvips/include/vips/foreign.h b/libvips/include/vips/foreign.h index 15062bc0..a8727b10 100644 --- a/libvips/include/vips/foreign.h +++ b/libvips/include/vips/foreign.h @@ -331,6 +331,10 @@ int vips_fitssave( VipsImage *in, const char *filename, ... ) int vips_analyzeload( const char *filename, VipsImage **out, ... ) __attribute__((sentinel)); +int vips_rawload( const char *filename, VipsImage **out, + int width, int height, int bands, ... ) + __attribute__((sentinel)); + #ifdef __cplusplus } #endif /*__cplusplus*/