From 23a777127cff35b72728b1059b7da0f0bee6fa88 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 29 Nov 2011 11:10:56 +0000 Subject: [PATCH 1/4] new file systems works --- TODO | 31 ++++++++++-- libvips/file/jpeg.h | 2 +- libvips/file/jpeg2vips.c | 105 +++++++++++++++++---------------------- libvips/file/jpegsave.c | 2 +- libvips/file/vips2jpeg.c | 17 +++---- 5 files changed, 84 insertions(+), 73 deletions(-) diff --git a/TODO b/TODO index 1045d114..8ff06135 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,33 @@ -- fix up jpeg2vips.c - fix up jpegload.c +- rename file as VipsForeign - added classes for read and write jpeg buffers + at the moment we have: + + VipsFile (filename, priority, suffs) + VipsFileLoad (disc, flags, out, real, is_a, get_flags, header, load) + VipsFileLoadJpeg (shrink, fail) + VipsFileSave (in, ready, saveable, format_table) + VipsFileSaveJpeg (Q, profile) + + we want jpeg*_buffer to have everything jpeg* has, except filename and + suffs + + reorganise as + + VipsForeign (priority) + VipsForeignLoad (disc, flags, out, real, get_flags, header, load) + VipsForeignLoadJpeg (shrink, fail) + VipsForeignLoadJpegFile (filename, is_a) + VipsForeignLoadJpegBuffer (buffer) + VipsForeignSave (in, ready, saveable, format_table) + VipsForeignSaveJpeg (Q, profile) + VipsForeignSaveJpegFile (filename, suffs) + VipsForeignSaveJpegBuffer (buffer) + + + + +- add classes for read and write jpeg buffers make compat wrappers for old im_jpeg2vips() and im_vips2jpeg() diff --git a/libvips/file/jpeg.h b/libvips/file/jpeg.h index 74663f1d..c5d00bfb 100644 --- a/libvips/file/jpeg.h +++ b/libvips/file/jpeg.h @@ -53,7 +53,7 @@ void vips__new_error_exit( j_common_ptr cinfo ); int vips__jpeg_write_file( VipsImage *in, const char *filename, int Q, const char *profile ); int vips__jpeg_write_buffer( VipsImage *in, - void **obuf, int *olen, int Q, const char *profile ); + void **obuf, size_t *olen, int Q, const char *profile ); int vips__isjpeg( const char *filename ); int vips__jpeg_read_file( const char *name, VipsImage *out, diff --git a/libvips/file/jpeg2vips.c b/libvips/file/jpeg2vips.c index 923904bc..10901787 100644 --- a/libvips/file/jpeg2vips.c +++ b/libvips/file/jpeg2vips.c @@ -303,7 +303,7 @@ attach_exif_entry( ExifEntry *entry, VipsExif *ve ) /* Can't do anything sensible with the error return. */ - (void) im_meta_set_string( ve->image, + (void) vips_image_set_string( ve->image, vips_buf_all( &name ), vips_buf_all( &value ) ); } @@ -366,7 +366,7 @@ set_vips_resolution( IMAGE *im, ExifData *ed ) if( get_entry_rational( ed, EXIF_TAG_X_RESOLUTION, &xres ) || get_entry_rational( ed, EXIF_TAG_Y_RESOLUTION, &yres ) || get_entry_short( ed, EXIF_TAG_RESOLUTION_UNIT, &unit ) ) { - im_warn( "im_jpeg2vips", + vips_warn( "VipsJpeg", "%s", _( "error reading resolution" ) ); return; } @@ -387,7 +387,7 @@ set_vips_resolution( IMAGE *im, ExifData *ed ) break; default: - im_warn( "im_jpeg2vips", "%s", _( "bad resolution unit" ) ); + vips_warn( "VipsJpeg", "%s", _( "bad resolution unit" ) ); return; } @@ -401,14 +401,11 @@ attach_thumbnail( IMAGE *im, ExifData *ed ) if( ed->size > 0 ) { char *thumb_copy; - thumb_copy = im_malloc( NULL, ed->size ); + thumb_copy = g_malloc( ed->size ); memcpy( thumb_copy, ed->data, ed->size ); - if( im_meta_set_blob( im, "jpeg-thumbnail-data", - (im_callback_fn) im_free, thumb_copy, ed->size ) ) { - im_free( thumb_copy ); - return( -1 ); - } + vips_image_set_blob( im, "jpeg-thumbnail-data", + (VipsCallbackFn) g_free, thumb_copy, ed->size ); } return( 0 ); @@ -422,7 +419,7 @@ read_exif( IMAGE *im, void *data, int data_length ) /* Only use the first one. */ - if( im_header_get_typeof( im, IM_META_EXIF_NAME ) ) { + if( vips_image_get_typeof( im, VIPS_META_EXIF_NAME ) ) { #ifdef DEBUG printf( "read_exif: second EXIF block, ignoring\n" ); #endif /*DEBUG*/ @@ -436,14 +433,11 @@ read_exif( IMAGE *im, void *data, int data_length ) /* Always attach a copy of the unparsed exif data. */ - if( !(data_copy = im_malloc( NULL, data_length )) ) + if( !(data_copy = vips_malloc( NULL, data_length )) ) return( -1 ); memcpy( data_copy, data, data_length ); - if( im_meta_set_blob( im, IM_META_EXIF_NAME, - (im_callback_fn) im_free, data_copy, data_length ) ) { - im_free( data_copy ); - return( -1 ); - } + vips_image_set_blob( im, VIPS_META_EXIF_NAME, + (VipsCallbackFn) vips_free, data_copy, data_length ); #ifdef HAVE_EXIF { @@ -490,13 +484,13 @@ read_exif( IMAGE *im, void *data, int data_length ) } static int -read_xmp( IMAGE *im, void *data, int data_length ) +read_xmp( IMAGE *im, void *data, size_t data_length ) { char *data_copy; /* XMP sections start "http". Only use the first one. */ - if( im_header_get_typeof( im, VIPS_META_XMP_NAME ) ) { + if( vips_image_get_typeof( im, VIPS_META_XMP_NAME ) ) { #ifdef DEBUG printf( "read_xmp: second XMP block, ignoring\n" ); #endif /*DEBUG*/ @@ -510,14 +504,11 @@ read_xmp( IMAGE *im, void *data, int data_length ) /* Always attach a copy of the unparsed exif data. */ - if( !(data_copy = im_malloc( NULL, data_length )) ) + if( !(data_copy = vips_malloc( NULL, data_length )) ) return( -1 ); memcpy( data_copy, data, data_length ); - if( im_meta_set_blob( im, VIPS_META_XMP_NAME, - (im_callback_fn) im_free, data_copy, data_length ) ) { - im_free( data_copy ); - return( -1 ); - } + vips_image_set_blob( im, VIPS_META_XMP_NAME, + (VipsCallbackFn) vips_free, data_copy, data_length ); return( 0 ); } @@ -535,13 +526,13 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo, IMAGE *out, gboolean *invert_pels, int shrink ) { jpeg_saved_marker_ptr p; - int type; + VipsInterpretation interpretation; /* Capture app2 sections here for assembly. */ void *app2_data[MAX_APP2_SECTIONS] = { 0 }; - int app2_data_length[MAX_APP2_SECTIONS] = { 0 }; - int data_length; + size_t app2_data_length[MAX_APP2_SECTIONS] = { 0 }; + size_t data_length; int i; /* Read JPEG header. libjpeg will set out_color_space sanely for us @@ -555,11 +546,11 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo, *invert_pels = FALSE; switch( cinfo->out_color_space ) { case JCS_GRAYSCALE: - type = IM_TYPE_B_W; + interpretation = VIPS_INTERPRETATION_B_W; break; case JCS_CMYK: - type = IM_TYPE_CMYK; + interpretation = VIPS_INTERPRETATION_CMYK; /* Photoshop writes CMYK JPEG inverted :-( Maybe this is a * way to spot photoshop CMYK JPGs. */ @@ -569,22 +560,23 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo, case JCS_RGB: default: - type = IM_TYPE_sRGB; + interpretation = VIPS_INTERPRETATION_sRGB; break; } /* Set VIPS header. */ - im_initdesc( out, - cinfo->output_width, cinfo->output_height, - cinfo->output_components, - IM_BBITS_BYTE, IM_BANDFMT_UCHAR, IM_CODING_NONE, type, - 1.0, 1.0, 0, 0 ); + vips_image_init_fields( out, + cinfo->output_width, cinfo->output_height, + cinfo->output_components, + VIPS_FORMAT_UCHAR, VIPS_CODING_NONE, + interpretation, + 1.0, 1.0 ); /* Interlaced jpegs need lots of memory to read, so our caller needs * to know. */ - (void) im_meta_set_int( out, "jpeg-multiscan", + (void) vips_image_set_int( out, "jpeg-multiscan", jpeg_has_multiple_scans( cinfo ) ); /* Look for EXIF and ICC profile. @@ -609,12 +601,12 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo, /* Possible EXIF or XMP data. */ if( p->data_length > 4 && - im_isprefix( "Exif", (char *) p->data ) && + vips_isprefix( "Exif", (char *) p->data ) && read_exif( out, p->data, p->data_length ) ) return( -1 ); if( p->data_length > 4 && - im_isprefix( "http", (char *) p->data ) && + vips_isprefix( "http", (char *) p->data ) && read_xmp( out, p->data, p->data_length ) ) return( -1 ); @@ -624,7 +616,7 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo, /* ICC profile. */ if( p->data_length > 14 && - im_isprefix( "ICC_PROFILE", + vips_isprefix( "ICC_PROFILE", (char *) p->data ) ) { /* cur_marker numbers from 1, according to * spec. @@ -659,7 +651,7 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo, data_length ); #endif /*DEBUG*/ - if( !(data = im_malloc( NULL, data_length )) ) + if( !(data = vips_malloc( NULL, data_length )) ) return( -1 ); p = 0; @@ -668,11 +660,8 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo, p += app2_data_length[i]; } - if( im_meta_set_blob( out, IM_META_ICC_NAME, - (im_callback_fn) im_free, data, data_length ) ) { - im_free( data ); - return( -1 ); - } + vips_image_set_blob( out, VIPS_META_ICC_NAME, + (VipsCallbackFn) vips_free, data, data_length ); } return( 0 ); @@ -689,7 +678,7 @@ read_jpeg_image( struct jpeg_decompress_struct *cinfo, IMAGE *out, /* Check VIPS. */ - if( im_outcheck( out ) || im_setupout( out ) ) + if( vips_image_wio_output( out ) ) return( -1 ); /* Get size of output line and make a buffer. @@ -714,7 +703,7 @@ read_jpeg_image( struct jpeg_decompress_struct *cinfo, IMAGE *out, for( x = 0; x < sz; x++ ) row_pointer[0][x] = 255 - row_pointer[0][x]; } - if( im_writeline( y, out, row_pointer[0] ) ) + if( vips_image_write_line( out, y, row_pointer[0] ) ) return( -1 ); } @@ -728,12 +717,9 @@ read_jpeg_image( struct jpeg_decompress_struct *cinfo, IMAGE *out, /* Read a JPEG file into a VIPS image. */ int -vips__jpeg2vips( const char *name, VipsImage *out, gboolean header_only, +vips__jpeg2vips( const char *filename, VipsImage *out, gboolean header_only, int shrink, gboolean fail ) { - char filename[FILENAME_MAX]; - char mode[FILENAME_MAX]; - char *p, *q; struct jpeg_decompress_struct cinfo; ErrorManager eman; FILE *fp; @@ -743,8 +729,8 @@ vips__jpeg2vips( const char *name, VipsImage *out, gboolean header_only, /* Make jpeg dcompression object. */ cinfo.err = jpeg_std_error( &eman.pub ); - eman.pub.error_exit = new_error_exit; - eman.pub.output_message = new_output_message; + eman.pub.error_exit = vips__new_error_exit; + eman.pub.output_message = vips__new_output_message; eman.fp = NULL; if( setjmp( eman.jmp ) ) { /* Here for longjmp() from new_error_exit(). @@ -757,7 +743,7 @@ vips__jpeg2vips( const char *name, VipsImage *out, gboolean header_only, /* Make input. */ - if( !(fp = im__file_open_read( filename, NULL, FALSE )) ) + if( !(fp = vips__file_open_read( filename, NULL, FALSE )) ) return( -1 ); eman.fp = fp; jpeg_stdio_src( &cinfo, fp ); @@ -781,13 +767,14 @@ vips__jpeg2vips( const char *name, VipsImage *out, gboolean header_only, if( eman.pub.num_warnings != 0 ) { if( fail ) { - im_error( "im_jpeg2vips", "%s", im_error_buffer() ); + vips_error( "VipsJpeg", "%s", vips_error_buffer() ); result = -1; } else { - im_warn( "im_jpeg2vips", _( "read gave %ld warnings" ), + vips_warn( "VipsJpeg", + _( "read gave %ld warnings" ), eman.pub.num_warnings ); - im_warn( "im_jpeg2vips", "%s", im_error_buffer() ); + vips_warn( "VipsJpeg", "%s", vips_error_buffer() ); } } @@ -979,8 +966,8 @@ vips__bufjpeg2vips( void *buf, size_t len, VipsImage *out, /* Make jpeg dcompression object. */ cinfo.err = jpeg_std_error( &eman.pub ); - eman.pub.error_exit = new_error_exit; - eman.pub.output_message = new_output_message; + eman.pub.error_exit = vips__new_error_exit; + eman.pub.output_message = vips__new_output_message; eman.fp = NULL; if( setjmp( eman.jmp ) ) { /* Here for longjmp() from new_error_exit(). diff --git a/libvips/file/jpegsave.c b/libvips/file/jpegsave.c index cba0635c..f170a507 100644 --- a/libvips/file/jpegsave.c +++ b/libvips/file/jpegsave.c @@ -103,7 +103,7 @@ vips_file_save_jpeg_build( VipsObject *object ) build( object ) ) return( -1 ); - if( vips__jpeg_write_file( save->in, file->filename, + if( vips__jpeg_write_file( save->ready, file->filename, jpeg->Q, jpeg->profile ) ) return( -1 ); diff --git a/libvips/file/vips2jpeg.c b/libvips/file/vips2jpeg.c index b7f03d8c..a4def301 100644 --- a/libvips/file/vips2jpeg.c +++ b/libvips/file/vips2jpeg.c @@ -177,7 +177,6 @@ static void write_destroy( Write *write ) { jpeg_destroy_compress( &write->cinfo ); - VIPS_UNREF( write->in ); VIPS_FREEF( fclose, write->eman.fp ); VIPS_FREE( write->row_pointer ); VIPS_FREE( write->profile_bytes ); @@ -852,8 +851,8 @@ typedef struct _Block { struct _Block *next; JOCTET *data; /* Allocated area */ - int size; /* Max size */ - int used; /* How much has been used */ + size_t size; /* Max size */ + size_t used; /* How much has been used */ } Block; static Block * @@ -898,10 +897,10 @@ block_append( Block *block ) return( new ); } -static int +static size_t block_length( Block *block ) { - int len; + size_t len; len = 0; for( block = block->first; block; block = block->next ) @@ -960,8 +959,8 @@ typedef struct { /* Copy the compressed area here. */ - char **obuf; /* Allocated buffer, and size */ - int *olen; + void **obuf; /* Allocated buffer, and size */ + size_t *olen; } OutputBuffer; /* Init dest method. @@ -1041,7 +1040,7 @@ term_destination( j_compress_ptr cinfo ) /* Set dest to one of our objects. */ static void -buf_dest( j_compress_ptr cinfo, char **obuf, int *olen ) +buf_dest( j_compress_ptr cinfo, void **obuf, size_t *olen ) { OutputBuffer *buf; @@ -1073,7 +1072,7 @@ buf_dest( j_compress_ptr cinfo, char **obuf, int *olen ) int vips__jpeg_write_buffer( VipsImage *in, - char **obuf, int *olen, int Q, const char *profile ) + void **obuf, size_t *olen, int Q, const char *profile ) { Write *write; From 56fb2126b815259b17f22797a8f0cdac22daa4fb Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 29 Nov 2011 11:43:08 +0000 Subject: [PATCH 2/4] rename VipsFile as VipsForeign --- configure.in | 2 +- libvips/Makefile.am | 4 +- libvips/{file => foreign}/Makefile.am | 6 +- libvips/{file/file.c => foreign/foreign.c} | 276 ++++++++++----------- libvips/{file => foreign}/jpeg.h | 0 libvips/{file => foreign}/jpeg2vips.c | 0 libvips/{file => foreign}/jpegload.c | 76 +++--- libvips/{file => foreign}/jpegsave.c | 34 +-- libvips/{file => foreign}/vips2jpeg.c | 0 libvips/{file => foreign}/vipsload.c | 36 +-- libvips/{file => foreign}/vipssave.c | 25 +- libvips/include/vips/Makefile.am | 4 +- libvips/include/vips/enumtypes.h | 6 +- libvips/include/vips/file.h | 239 ------------------ libvips/include/vips/foreign.h | 239 ++++++++++++++++++ libvips/include/vips/vips.h | 2 +- libvips/iofuncs/Makefile.am | 2 +- libvips/iofuncs/enumtypes.c | 12 +- libvips/iofuncs/image.c | 6 +- libvips/iofuncs/init.c | 2 +- libvips/iofuncs/object.c | 4 +- 21 files changed, 488 insertions(+), 487 deletions(-) rename libvips/{file => foreign}/Makefile.am (70%) rename libvips/{file/file.c => foreign/foreign.c} (72%) rename libvips/{file => foreign}/jpeg.h (100%) rename libvips/{file => foreign}/jpeg2vips.c (100%) rename libvips/{file => foreign}/jpegload.c (90%) rename libvips/{file => foreign}/jpegsave.c (77%) rename libvips/{file => foreign}/vips2jpeg.c (100%) rename libvips/{file => foreign}/vipsload.c (66%) rename libvips/{file => foreign}/vipssave.c (75%) delete mode 100644 libvips/include/vips/file.h create mode 100644 libvips/include/vips/foreign.h diff --git a/configure.in b/configure.in index 2fba6c00..d51edd22 100644 --- a/configure.in +++ b/configure.in @@ -635,7 +635,7 @@ AC_OUTPUT([ libvips/convolution/Makefile libvips/deprecated/Makefile libvips/format/Makefile - libvips/file/Makefile + libvips/foreign/Makefile libvips/freq_filt/Makefile libvips/histograms_lut/Makefile libvips/inplace/Makefile diff --git a/libvips/Makefile.am b/libvips/Makefile.am index 3999b2be..62304d2e 100644 --- a/libvips/Makefile.am +++ b/libvips/Makefile.am @@ -10,7 +10,7 @@ C_LIB = endif SUBDIRS = \ - file \ + foreign \ include \ arithmetic \ resample \ @@ -53,7 +53,7 @@ libvips_la_LIBADD = \ deprecated/libdeprecated.la \ $(C_LIB) \ format/libformat.la \ - file/libfile.la \ + foreign/libforeign.la \ freq_filt/libfreq_filt.la \ histograms_lut/libhistograms_lut.la \ inplace/libinplace.la \ diff --git a/libvips/file/Makefile.am b/libvips/foreign/Makefile.am similarity index 70% rename from libvips/file/Makefile.am rename to libvips/foreign/Makefile.am index 50cc385d..4cf0a521 100644 --- a/libvips/file/Makefile.am +++ b/libvips/foreign/Makefile.am @@ -1,6 +1,6 @@ -noinst_LTLIBRARIES = libfile.la +noinst_LTLIBRARIES = libforeign.la -libfile_la_SOURCES = \ +libforeign_la_SOURCES = \ vips2jpeg.c \ jpeg2vips.c \ jpeg.h \ @@ -8,6 +8,6 @@ libfile_la_SOURCES = \ jpegsave.c \ vipssave.c \ vipsload.c \ - file.c + foreign.c INCLUDES = -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@ diff --git a/libvips/file/file.c b/libvips/foreign/foreign.c similarity index 72% rename from libvips/file/file.c rename to libvips/foreign/foreign.c index ada5fb45..b5061a47 100644 --- a/libvips/file/file.c +++ b/libvips/foreign/foreign.c @@ -56,48 +56,48 @@ * * If you define a new file, support for * it automatically appears in all VIPS user-interfaces. It will also be - * transparently supported by vips_image_new_from_file() and friends. + * transparently supported by vips_image_new_from_foreign() and friends. * - * VIPS comes with VipsFile for TIFF, JPEG, PNG, Analyze, PPM, OpenEXR, CSV, + * VIPS comes with VipsForeign for TIFF, JPEG, PNG, Analyze, PPM, OpenEXR, CSV, * Matlab, Radiance, RAW, VIPS and one that wraps libMagick. */ /** - * VipsFileFlags: - * @VIPS_FILE_NONE: no flags set - * @VIPS_FILE_PARTIAL: the image may be read lazilly - * @VIPS_FILE_BIGENDIAN: image pixels are most-significant byte first + * VipsForeignFlags: + * @VIPS_FOREIGN_NONE: no flags set + * @VIPS_FOREIGN_PARTIAL: the image may be read lazilly + * @VIPS_FOREIGN_BIGENDIAN: image pixels are most-significant byte first * * Some hints about the image loader. * - * @VIPS_FILE_PARTIAL means that the image can be read directly from the + * @VIPS_FOREIGN_PARTIAL means that the image can be read directly from the * file without needing to be unpacked to a temporary image first. * - * @VIPS_FILE_BIGENDIAN means that image pixels are most-significant byte + * @VIPS_FOREIGN_BIGENDIAN means that image pixels are most-significant byte * first. Depending on the native byte order of the host machine, you may * need to swap bytes. See copy_swap(). */ /** - * VipsFile: + * VipsForeign: * - * #VipsFile has these virtual methods: + * #VipsForeign has these virtual methods: * * |[ - * typedef struct _VipsFileClass { + * typedef struct _VipsForeignClass { * VipsObjectClass parent_class; * * gboolean (*is_a)( const char *filename ); * int (*header)( const char *filename, VipsImage *out ); * int (*load)( const char *filename, VipsImage *out ); * int (*save)( VipsImage *in, const char *filename ); - * VipsFileFlags (*get_flags)( const char *filename ); + * VipsForeignFlags (*get_flags)( const char *filename ); * int priority; * const char **suffs; - * } VipsFileClass; + * } VipsForeignClass; * ]| * - * Add a new file to VIPS by subclassing VipsFile. Subclasses need to + * Add a new file to VIPS by subclassing VipsForeign. Subclasses need to * implement at least load() or save(). * * These members are: @@ -179,7 +179,7 @@ * At the command-line, use: * * |[ - * vips --list classes | grep File + * vips --list classes | grep Foreign * ]| * * To see a list of all the supported files. @@ -187,14 +187,14 @@ * For example, the TIFF file is defined like this: * |[ -typedef VipsFile VipsFileTiff; -typedef VipsFileClass VipsFileTiffClass; +typedef VipsForeign VipsForeignTiff; +typedef VipsForeignClass VipsForeignTiffClass; static void -vips_file_tiff_class_init( VipsFileTiffClass *class ) +vips_foreign_tiff_class_init( VipsForeignTiffClass *class ) { VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsFileClass *file_class = (VipsFileClass *) class; + VipsForeignClass *file_class = (VipsForeignClass *) class; object_class->nickname = "tiff"; object_class->description = _( "TIFF" ); @@ -208,14 +208,14 @@ vips_file_tiff_class_init( VipsFileTiffClass *class ) } static void -vips_file_tiff_init( VipsFileTiff *object ) +vips_foreign_tiff_init( VipsForeignTiff *object ) { } -G_DEFINE_TYPE( VipsFileTiff, vips_file_tiff, VIPS_TYPE_FILE ); +G_DEFINE_TYPE( VipsForeignTiff, vips_foreign_tiff, VIPS_TYPE_FOREIGN ); ]| * - * Then call vips_file_tiff_get_type() somewhere in your init code to link + * Then call vips_foreign_tiff_get_type() somewhere in your init code to link * the file into VIPS (though of course the tiff file is linked in for you * already). * @@ -224,15 +224,15 @@ G_DEFINE_TYPE( VipsFileTiff, vips_file_tiff, VIPS_TYPE_FILE ); /* Abstract base class for image files. */ -G_DEFINE_ABSTRACT_TYPE( VipsFile, vips_file, VIPS_TYPE_OPERATION ); +G_DEFINE_ABSTRACT_TYPE( VipsForeign, vips_foreign, VIPS_TYPE_OPERATION ); static void -vips_file_print_class( VipsObjectClass *object_class, VipsBuf *buf ) +vips_foreign_print_class( VipsObjectClass *object_class, VipsBuf *buf ) { - VipsFileClass *class = VIPS_FILE_CLASS( object_class ); + VipsForeignClass *class = VIPS_FOREIGN_CLASS( object_class ); const char **p; - VIPS_OBJECT_CLASS( vips_file_parent_class )-> + VIPS_OBJECT_CLASS( vips_foreign_parent_class )-> print_class( object_class, buf ); vips_buf_appends( buf, " " ); @@ -251,7 +251,7 @@ vips_file_print_class( VipsObjectClass *object_class, VipsBuf *buf ) } static void -vips_file_class_init( VipsFileClass *class ) +vips_foreign_class_init( VipsForeignClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *object_class = (VipsObjectClass *) class; @@ -261,27 +261,27 @@ vips_file_class_init( VipsFileClass *class ) object_class->nickname = "file"; object_class->description = _( "load and save image files" ); - object_class->print_class = vips_file_print_class; + object_class->print_class = vips_foreign_print_class; VIPS_ARG_STRING( class, "filename", 1, - _( "Filename" ), - _( "File filename" ), + _( "Foreignname" ), + _( "Foreign filename" ), VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET( VipsFile, filename ), + G_STRUCT_OFFSET( VipsForeign, filename ), NULL ); } static void -vips_file_init( VipsFile *object ) +vips_foreign_init( VipsForeign *object ) { } /* To iterate over supported files we build a temp list of subclasses of - * VipsFile, sort by priority, iterate, and free. + * VipsForeign, sort by priority, iterate, and free. */ static void * -file_add_class( VipsFileClass *file, GSList **files ) +file_add_class( VipsForeignClass *file, GSList **files ) { /* Append so we don't reverse the list of files. */ @@ -291,19 +291,19 @@ file_add_class( VipsFileClass *file, GSList **files ) } static gint -file_compare( VipsFileClass *a, VipsFileClass *b ) +file_compare( VipsForeignClass *a, VipsForeignClass *b ) { return( b->priority - a->priority ); } /** - * vips_file_map: - * @base: base class to search below (eg. "VipsFileLoad") - * @fn: function to apply to each #VipsFileClass + * vips_foreign_map: + * @base: base class to search below (eg. "VipsForeignLoad") + * @fn: function to apply to each #VipsForeignClass * @a: user data * @b: user data * - * Apply a function to every #VipsFileClass that VIPS knows about. Files + * Apply a function to every #VipsForeignClass that VIPS knows about. Foreigns * are presented to the function in priority order. * * Like all VIPS map functions, if @fn returns %NULL, iteration continues. If @@ -315,7 +315,7 @@ file_compare( VipsFileClass *a, VipsFileClass *b ) * Returns: the result of iteration */ void * -vips_file_map( const char *base, VipsSListMap2Fn fn, void *a, void *b ) +vips_foreign_map( const char *base, VipsSListMap2Fn fn, void *a, void *b ) { GSList *files; void *result; @@ -334,24 +334,24 @@ vips_file_map( const char *base, VipsSListMap2Fn fn, void *a, void *b ) /* Abstract base class for image load. */ -G_DEFINE_ABSTRACT_TYPE( VipsFileLoad, vips_file_load, VIPS_TYPE_FILE ); +G_DEFINE_ABSTRACT_TYPE( VipsForeignLoad, vips_foreign_load, VIPS_TYPE_FOREIGN ); static void -vips_file_load_dispose( GObject *gobject ) +vips_foreign_load_dispose( GObject *gobject ) { - VipsFileLoad *load = VIPS_FILE_LOAD( gobject ); + VipsForeignLoad *load = VIPS_FOREIGN_LOAD( gobject ); VIPS_UNREF( load->real ); - G_OBJECT_CLASS( vips_file_load_parent_class )->dispose( gobject ); + G_OBJECT_CLASS( vips_foreign_load_parent_class )->dispose( gobject ); } static void -vips_file_load_print_class( VipsObjectClass *object_class, VipsBuf *buf ) +vips_foreign_load_print_class( VipsObjectClass *object_class, VipsBuf *buf ) { - VipsFileLoadClass *class = VIPS_FILE_LOAD_CLASS( object_class ); + VipsForeignLoadClass *class = VIPS_FOREIGN_LOAD_CLASS( object_class ); - VIPS_OBJECT_CLASS( vips_file_load_parent_class )-> + VIPS_OBJECT_CLASS( vips_foreign_load_parent_class )-> print_class( object_class, buf ); if( class->is_a ) @@ -364,13 +364,13 @@ vips_file_load_print_class( VipsObjectClass *object_class, VipsBuf *buf ) vips_buf_appends( buf, ", load" ); } -/* Can this VipsFile open this file? +/* Can this VipsForeign open this file? */ static void * -vips_file_load_new_from_file_sub( VipsFileLoadClass *load_class, +vips_foreign_load_new_from_foreign_sub( VipsForeignLoadClass *load_class, const char *filename ) { - VipsFileClass *class = VIPS_FILE_CLASS( load_class ); + VipsForeignClass *class = VIPS_FOREIGN_CLASS( load_class ); if( load_class->is_a ) { if( load_class->is_a( filename ) ) @@ -383,31 +383,31 @@ vips_file_load_new_from_file_sub( VipsFileLoadClass *load_class, } /** - * vips_file_find_load: + * vips_foreign_find_load: * @filename: file to find a file for * * Searches for an operation you could use to load a file. * - * See also: vips_file_read(). + * See also: vips_foreign_read(). * * Returns: the nmae of an operation on success, %NULL on error */ const char * -vips_file_find_load( const char *filename ) +vips_foreign_find_load( const char *filename ) { - VipsFileLoadClass *load_class; + VipsForeignLoadClass *load_class; if( !vips_existsf( "%s", filename ) ) { - vips_error( "VipsFileLoad", + vips_error( "VipsForeignLoad", _( "file \"%s\" not found" ), filename ); return( NULL ); } - if( !(load_class = (VipsFileLoadClass *) vips_file_map( - "VipsFileLoad", - (VipsSListMap2Fn) vips_file_load_new_from_file_sub, + if( !(load_class = (VipsForeignLoadClass *) vips_foreign_map( + "VipsForeignLoad", + (VipsSListMap2Fn) vips_foreign_load_new_from_foreign_sub, (void *) filename, NULL )) ) { - vips_error( "VipsFileLoad", + vips_error( "VipsForeignLoad", _( "file \"%s\" not a known file" ), filename ); return( NULL ); } @@ -416,18 +416,18 @@ vips_file_find_load( const char *filename ) } static VipsObject * -vips_file_load_new_from_string( const char *string ) +vips_foreign_load_new_from_string( const char *string ) { const char *file_op; GType type; - VipsFileLoad *load; + VipsForeignLoad *load; - if( !(file_op = vips_file_find_load( string )) ) + if( !(file_op = vips_foreign_find_load( string )) ) return( NULL ); type = g_type_from_name( file_op ); g_assert( type ); - load = VIPS_FILE_LOAD( g_object_new( type, NULL ) ); + load = VIPS_FOREIGN_LOAD( g_object_new( type, NULL ) ); g_object_set( load, "filename", string, NULL ); @@ -467,10 +467,10 @@ vips_get_disc_threshold( void ) * on the new image. */ static void * -vips_file_load_start_cb( VipsImage *out, void *a, void *dummy ) +vips_foreign_load_start_cb( VipsImage *out, void *a, void *dummy ) { - VipsFileLoad *load = VIPS_FILE_LOAD( a ); - VipsFileLoadClass *class = VIPS_FILE_LOAD_GET_CLASS( a ); + VipsForeignLoad *load = VIPS_FOREIGN_LOAD( a ); + VipsForeignLoadClass *class = VIPS_FOREIGN_LOAD_GET_CLASS( a ); if( !load->real ) { const size_t disc_threshold = vips_get_disc_threshold(); @@ -485,7 +485,7 @@ vips_file_load_start_cb( VipsImage *out, void *a, void *dummy ) */ if( load->disc && disc_threshold && - (load->flags & VIPS_FILE_PARTIAL) && + (load->flags & VIPS_FOREIGN_PARTIAL) && image_size > disc_threshold ) if( !(load->real = vips_image_new_disc_temp( "%s.v" )) ) return( NULL ); @@ -511,7 +511,7 @@ vips_file_load_start_cb( VipsImage *out, void *a, void *dummy ) /* Just pointer-copy. */ static int -vips_file_load_generate_cb( VipsRegion *or, +vips_foreign_load_generate_cb( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop ) { VipsRegion *ir = (VipsRegion *) seq; @@ -532,10 +532,10 @@ vips_file_load_generate_cb( VipsRegion *or, } static int -vips_file_load_build( VipsObject *object ) +vips_foreign_load_build( VipsObject *object ) { - VipsFileLoad *load = VIPS_FILE_LOAD( object ); - VipsFileLoadClass *class = VIPS_FILE_LOAD_GET_CLASS( object ); + VipsForeignLoad *load = VIPS_FOREIGN_LOAD( object ); + VipsForeignLoadClass *class = VIPS_FOREIGN_LOAD_GET_CLASS( object ); g_object_set( object, "out", vips_image_new(), NULL ); @@ -543,7 +543,7 @@ vips_file_load_build( VipsObject *object ) class->get_flags( load ) ) return( -1 ); - if( VIPS_OBJECT_CLASS( vips_file_load_parent_class )-> + if( VIPS_OBJECT_CLASS( vips_foreign_load_parent_class )-> build( object ) ) return( -1 ); @@ -569,8 +569,8 @@ vips_file_load_build( VipsObject *object ) * pixels for @out from @real on demand. */ if( vips_image_generate( load->out, - vips_file_load_start_cb, - vips_file_load_generate_cb, + vips_foreign_load_start_cb, + vips_foreign_load_generate_cb, vips_stop_one, load, NULL ) ) return( -1 ); @@ -580,18 +580,18 @@ vips_file_load_build( VipsObject *object ) } static void -vips_file_load_class_init( VipsFileLoadClass *class ) +vips_foreign_load_class_init( VipsForeignLoadClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *object_class = (VipsObjectClass *) class; - gobject_class->dispose = vips_file_load_dispose; + gobject_class->dispose = vips_foreign_load_dispose; gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; - object_class->build = vips_file_load_build; - object_class->print_class = vips_file_load_print_class; - object_class->new_from_string = vips_file_load_new_from_string; + object_class->build = vips_foreign_load_build; + object_class->print_class = vips_foreign_load_print_class; + object_class->new_from_string = vips_foreign_load_new_from_string; object_class->nickname = "fileload"; object_class->description = _( "file loaders" ); @@ -599,26 +599,26 @@ vips_file_load_class_init( VipsFileLoadClass *class ) _( "Output" ), _( "Output image" ), VIPS_ARGUMENT_REQUIRED_OUTPUT, - G_STRUCT_OFFSET( VipsFileLoad, out ) ); + G_STRUCT_OFFSET( VipsForeignLoad, out ) ); VIPS_ARG_ENUM( class, "flags", 6, _( "Flags" ), _( "Flags for this file" ), VIPS_ARGUMENT_OPTIONAL_OUTPUT, - G_STRUCT_OFFSET( VipsFileLoad, flags ), - VIPS_TYPE_FILE_FLAGS, VIPS_FILE_NONE ); + G_STRUCT_OFFSET( VipsForeignLoad, flags ), + VIPS_TYPE_FOREIGN_FLAGS, VIPS_FOREIGN_NONE ); VIPS_ARG_BOOL( class, "disc", 7, _( "Disc" ), _( "Open to disc" ), VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsFileLoad, disc ), + G_STRUCT_OFFSET( VipsForeignLoad, disc ), TRUE ); } static void -vips_file_load_init( VipsFileLoad *load ) +vips_foreign_load_init( VipsForeignLoad *load ) { load->disc = TRUE; } @@ -626,24 +626,24 @@ vips_file_load_init( VipsFileLoad *load ) /* Abstract base class for image savers. */ -G_DEFINE_ABSTRACT_TYPE( VipsFileSave, vips_file_save, VIPS_TYPE_FILE ); +G_DEFINE_ABSTRACT_TYPE( VipsForeignSave, vips_foreign_save, VIPS_TYPE_FOREIGN ); static void -vips_file_save_dispose( GObject *gobject ) +vips_foreign_save_dispose( GObject *gobject ) { - VipsFileSave *save = VIPS_FILE_SAVE( gobject ); + VipsForeignSave *save = VIPS_FOREIGN_SAVE( gobject ); VIPS_UNREF( save->ready ); - G_OBJECT_CLASS( vips_file_save_parent_class )->dispose( gobject ); + G_OBJECT_CLASS( vips_foreign_save_parent_class )->dispose( gobject ); } static void -vips_file_save_print_class( VipsObjectClass *object_class, VipsBuf *buf ) +vips_foreign_save_print_class( VipsObjectClass *object_class, VipsBuf *buf ) { - VipsFileSaveClass *class = VIPS_FILE_SAVE_CLASS( object_class ); + VipsForeignSaveClass *class = VIPS_FOREIGN_SAVE_CLASS( object_class ); - VIPS_OBJECT_CLASS( vips_file_save_parent_class )-> + VIPS_OBJECT_CLASS( vips_foreign_save_parent_class )-> print_class( object_class, buf ); vips_buf_appendf( buf, ", %s", @@ -653,10 +653,10 @@ vips_file_save_print_class( VipsObjectClass *object_class, VipsBuf *buf ) /* Can we write this filename with this file? */ static void * -vips_file_save_new_from_filename_sub( VipsFileSaveClass *save_class, +vips_foreign_save_new_from_foreignname_sub( VipsForeignSaveClass *save_class, const char *filename ) { - VipsFileClass *class = VIPS_FILE_CLASS( save_class ); + VipsForeignClass *class = VIPS_FOREIGN_CLASS( save_class ); if( vips_filename_suffix_match( filename, class->suffs ) ) return( save_class ); @@ -665,25 +665,25 @@ vips_file_save_new_from_filename_sub( VipsFileSaveClass *save_class, } /** - * vips_file_find_save: + * vips_foreign_find_save: * @filename: name to find a file for * * Searches for an operation you could use to save a file. * - * See also: vips_file_write(). + * See also: vips_foreign_write(). * * Returns: the name of an operation on success, %NULL on error */ const char * -vips_file_find_save( const char *filename ) +vips_foreign_find_save( const char *filename ) { - VipsFileSaveClass *save_class; + VipsForeignSaveClass *save_class; - if( !(save_class = (VipsFileSaveClass *) vips_file_map( - "VipsFileSave", - (VipsSListMap2Fn) vips_file_save_new_from_filename_sub, + if( !(save_class = (VipsForeignSaveClass *) vips_foreign_map( + "VipsForeignSave", + (VipsSListMap2Fn) vips_foreign_save_new_from_foreignname_sub, (void *) filename, NULL )) ) { - vips_error( "VipsFileSave", + vips_error( "VipsForeignSave", _( "\"%s\" is not a supported image file." ), filename ); @@ -694,18 +694,18 @@ vips_file_find_save( const char *filename ) } static VipsObject * -vips_file_save_new_from_string( const char *string ) +vips_foreign_save_new_from_string( const char *string ) { const char *file_op; GType type; - VipsFileSave *save; + VipsForeignSave *save; - if( !(file_op = vips_file_find_save( string )) ) + if( !(file_op = vips_foreign_find_save( string )) ) return( NULL ); type = g_type_from_name( file_op ); g_assert( type ); - save = VIPS_FILE_SAVE( g_object_new( type, NULL ) ); + save = VIPS_FOREIGN_SAVE( g_object_new( type, NULL ) ); g_object_set( save, "filename", string, NULL ); @@ -716,9 +716,9 @@ vips_file_save_new_from_string( const char *string ) /* Generate the saveable image. */ static int -vips_file_convert_saveable( VipsFileSave *save ) +vips_foreign_convert_saveable( VipsForeignSave *save ) { - VipsFileSaveClass *class = VIPS_FILE_SAVE_GET_CLASS( save ); + VipsForeignSaveClass *class = VIPS_FOREIGN_SAVE_GET_CLASS( save ); VipsImage *in = save->in; /* in holds a reference to the output of our chain as we build it. @@ -910,17 +910,17 @@ vips_file_convert_saveable( VipsFileSave *save ) } static int -vips_file_save_build( VipsObject *object ) +vips_foreign_save_build( VipsObject *object ) { - VipsFileSave *save = VIPS_FILE_SAVE( object ); + VipsForeignSave *save = VIPS_FOREIGN_SAVE( object ); /* - VipsFile *file = VIPS_FILE( object ); + VipsForeign *file = VIPS_FOREIGN( object ); */ - if( vips_file_convert_saveable( save ) ) + if( vips_foreign_convert_saveable( save ) ) return( -1 ); - if( VIPS_OBJECT_CLASS( vips_file_save_parent_class )-> + if( VIPS_OBJECT_CLASS( vips_foreign_save_parent_class )-> build( object ) ) return( -1 ); @@ -928,18 +928,18 @@ vips_file_save_build( VipsObject *object ) } static void -vips_file_save_class_init( VipsFileSaveClass *class ) +vips_foreign_save_class_init( VipsForeignSaveClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *object_class = (VipsObjectClass *) class; - gobject_class->dispose = vips_file_save_dispose; + gobject_class->dispose = vips_foreign_save_dispose; gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; - object_class->build = vips_file_save_build; - object_class->print_class = vips_file_save_print_class; - object_class->new_from_string = vips_file_save_new_from_string; + object_class->build = vips_foreign_save_build; + object_class->print_class = vips_foreign_save_print_class; + object_class->new_from_string = vips_foreign_save_new_from_string; object_class->nickname = "filesave"; object_class->description = _( "file savers" ); @@ -947,35 +947,35 @@ vips_file_save_class_init( VipsFileSaveClass *class ) _( "Input" ), _( "Image to save" ), VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET( VipsFileSave, in ) ); + G_STRUCT_OFFSET( VipsForeignSave, in ) ); } static void -vips_file_save_init( VipsFileSave *object ) +vips_foreign_save_init( VipsForeignSave *object ) { } /** - * vips_file_read: + * vips_foreign_read: * @filename: file to load * @out: output image * @...: %NULL-terminated list of optional named arguments * * Loads @filename into @out using the loader recommended by - * vips_file_find_load(). + * vips_foreign_find_load(). * - * See also: vips_file_write(). + * See also: vips_foreign_write(). * * Returns: 0 on success, -1 on error */ int -vips_file_read( const char *filename, VipsImage **out, ... ) +vips_foreign_read( const char *filename, VipsImage **out, ... ) { const char *operation; va_list ap; int result; - if( !(operation = vips_file_find_load( filename )) ) + if( !(operation = vips_foreign_find_load( filename )) ) return( -1 ); va_start( ap, out ); @@ -986,25 +986,25 @@ vips_file_read( const char *filename, VipsImage **out, ... ) } /** - * vips_file_write: + * vips_foreign_write: * @in: image to write * @filename: file to write to * * Saves @in to @filename using the saver recommended by - * vips_file_find_save(). + * vips_foreign_find_save(). * - * See also: vips_file_read(). + * See also: vips_foreign_read(). * * Returns: 0 on success, -1 on error */ int -vips_file_write( VipsImage *in, const char *filename, ... ) +vips_foreign_write( VipsImage *in, const char *filename, ... ) { const char *operation; va_list ap; int result; - if( !(operation = vips_file_find_save( filename )) ) + if( !(operation = vips_foreign_find_save( filename )) ) return( -1 ); va_start( ap, filename ); @@ -1018,17 +1018,17 @@ vips_file_write( VipsImage *in, const char *filename, ... ) * instead? */ void -vips_file_operation_init( void ) +vips_foreign_operation_init( void ) { - extern GType vips_file_load_jpeg_get_type( void ); - extern GType vips_file_save_jpeg_get_type( void ); - extern GType vips_file_load_vips_get_type( void ); - extern GType vips_file_save_vips_get_type( void ); + extern GType vips_foreign_load_jpeg_get_type( void ); + extern GType vips_foreign_save_jpeg_get_type( void ); + extern GType vips_foreign_load_vips_get_type( void ); + extern GType vips_foreign_save_vips_get_type( void ); #ifdef HAVE_JPEG - vips_file_load_jpeg_get_type(); - vips_file_save_jpeg_get_type(); + vips_foreign_load_jpeg_get_type(); + vips_foreign_save_jpeg_get_type(); #endif /*HAVE_JPEG*/ - vips_file_load_vips_get_type(); - vips_file_save_vips_get_type(); + vips_foreign_load_vips_get_type(); + vips_foreign_save_vips_get_type(); } diff --git a/libvips/file/jpeg.h b/libvips/foreign/jpeg.h similarity index 100% rename from libvips/file/jpeg.h rename to libvips/foreign/jpeg.h diff --git a/libvips/file/jpeg2vips.c b/libvips/foreign/jpeg2vips.c similarity index 100% rename from libvips/file/jpeg2vips.c rename to libvips/foreign/jpeg2vips.c diff --git a/libvips/file/jpegload.c b/libvips/foreign/jpegload.c similarity index 90% rename from libvips/file/jpegload.c rename to libvips/foreign/jpegload.c index d1d386a3..03d925ba 100644 --- a/libvips/file/jpegload.c +++ b/libvips/foreign/jpegload.c @@ -114,8 +114,8 @@ #include "jpeg.h" -typedef struct _VipsFileLoadJpeg { - VipsFileLoad parent_object; +typedef struct _VipsForeignLoadJpeg { + VipsForeignLoad parent_object; /* Shrink by this much during load. */ @@ -129,16 +129,16 @@ typedef struct _VipsFileLoadJpeg { */ gboolean invert_pels; -} VipsFileLoadJpeg; +} VipsForeignLoadJpeg; -typedef VipsFileLoadClass VipsFileLoadJpegClass; +typedef VipsForeignLoadClass VipsForeignLoadJpegClass; -G_DEFINE_TYPE( VipsFileLoadJpeg, vips_file_load_jpeg, VIPS_TYPE_FILE_LOAD ); +G_DEFINE_TYPE( VipsForeignLoadJpeg, vips_foreign_load_jpeg, VIPS_TYPE_FOREIGN_LOAD ); static int -vips_file_load_jpeg_build( VipsObject *object ) +vips_foreign_load_jpeg_build( VipsObject *object ) { - VipsFileLoadJpeg *jpeg = (VipsFileLoadJpeg *) object; + VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) object; if( jpeg->shrink != 1 && jpeg->shrink != 2 && @@ -149,7 +149,7 @@ vips_file_load_jpeg_build( VipsObject *object ) return( -1 ); } - if( VIPS_OBJECT_CLASS( vips_file_load_jpeg_parent_class )-> + if( VIPS_OBJECT_CLASS( vips_foreign_load_jpeg_parent_class )-> build( object ) ) return( -1 ); @@ -157,7 +157,7 @@ vips_file_load_jpeg_build( VipsObject *object ) } static gboolean -vips_file_load_jpeg_is_a( const char *filename ) +vips_foreign_load_jpeg_is_a( const char *filename ) { unsigned char buf[2]; @@ -172,7 +172,7 @@ vips_file_load_jpeg_is_a( const char *filename ) * do 255-pel. */ static int -vips_file_load_jpeg_read_header( VipsFileLoadJpeg *jpeg, +vips_foreign_load_jpeg_read_header( VipsForeignLoadJpeg *jpeg, struct jpeg_decompress_struct *cinfo, VipsImage *out ) { int type; @@ -630,7 +630,7 @@ read_xmp( IMAGE *im, void *data, int data_length ) #define MAX_APP2_SECTIONS (100) static int -vips_file_load_jpeg_meta( VipsFileLoadJpeg *jpeg, +vips_foreign_load_jpeg_meta( VipsForeignLoadJpeg *jpeg, struct jpeg_decompress_struct *cinfo, VipsImage *out ) { /* Capture app2 sections here for assembly. @@ -652,7 +652,7 @@ vips_file_load_jpeg_meta( VipsFileLoadJpeg *jpeg, for( p = cinfo->marker_list; p; p = p->next ) { #ifdef DEBUG { - printf( "vips_file_load_jpeg_read_header: " + printf( "vips_foreign_load_jpeg_read_header: " "seen %d bytes of APP%d\n", p->data_length, p->marker - JPEG_APP0 ); @@ -683,7 +683,7 @@ vips_file_load_jpeg_meta( VipsFileLoadJpeg *jpeg, /* ICC profile. */ if( p->data_length > 14 && - im_isprefix( "ICC_PROFILE", + im_isprefix( "ICC_PROFOREIGN", (char *) p->data ) ) { /* cur_marker numbers from 1, according to * spec. @@ -714,7 +714,7 @@ vips_file_load_jpeg_meta( VipsFileLoadJpeg *jpeg, int x; #ifdef DEBUG - printf( "vips_file_load_jpeg_read_header: " + printf( "vips_foreign_load_jpeg_read_header: " "assembled %d byte ICC profile\n", data_length ); #endif /*DEBUG*/ @@ -735,10 +735,10 @@ vips_file_load_jpeg_meta( VipsFileLoadJpeg *jpeg, /* Read just the image header into ->out. */ static int -vips_file_load_jpeg_header( VipsFileLoad *load ) +vips_foreign_load_jpeg_header( VipsForeignLoad *load ) { - VipsFile *file = VIPS_FILE( load ); - VipsFileLoadJpeg *jpeg = (VipsFileLoadJpeg *) load; + VipsForeign *file = VIPS_FOREIGN( load ); + VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load; struct jpeg_decompress_struct cinfo; ErrorManager eman; @@ -774,12 +774,12 @@ vips_file_load_jpeg_header( VipsFileLoad *load ) /* Convert! */ - result = vips_file_load_jpeg_read_header( jpeg, &cinfo, load->out ); + result = vips_foreign_load_jpeg_read_header( jpeg, &cinfo, load->out ); /* Get extra metadata too. */ if( !result ) - result = vips_file_load_jpeg_meta( jpeg, &cinfo, load->out ); + result = vips_foreign_load_jpeg_meta( jpeg, &cinfo, load->out ); /* Close and tidy. */ @@ -793,7 +793,7 @@ vips_file_load_jpeg_header( VipsFileLoad *load ) /* Read a cinfo to a VIPS image. */ static int -vips_file_load_jpeg_read_image( VipsFileLoadJpeg *jpeg, +vips_foreign_load_jpeg_read_image( VipsForeignLoadJpeg *jpeg, struct jpeg_decompress_struct *cinfo, VipsImage *out ) { int x, y, sz; @@ -838,10 +838,10 @@ vips_file_load_jpeg_read_image( VipsFileLoadJpeg *jpeg, } static int -vips_file_load_jpeg_load( VipsFileLoad *load ) +vips_foreign_load_jpeg_load( VipsForeignLoad *load ) { - VipsFile *file = VIPS_FILE( load ); - VipsFileLoadJpeg *jpeg = (VipsFileLoadJpeg *) load; + VipsForeign *file = VIPS_FOREIGN( load ); + VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load; struct jpeg_decompress_struct cinfo; ErrorManager eman; @@ -872,9 +872,9 @@ vips_file_load_jpeg_load( VipsFileLoad *load ) /* Convert! */ - result = vips_file_load_jpeg_read_header( jpeg, &cinfo, load->real ); + result = vips_foreign_load_jpeg_read_header( jpeg, &cinfo, load->real ); if( !result ) - result = vips_file_load_jpeg_read_image( jpeg, + result = vips_foreign_load_jpeg_read_image( jpeg, &cinfo, load->real ); /* Close and tidy. @@ -885,15 +885,15 @@ vips_file_load_jpeg_load( VipsFileLoad *load ) if( eman.pub.num_warnings != 0 ) { if( jpeg->fail ) { - vips_error( "VipsFileLoadJpeg", + vips_error( "VipsForeignLoadJpeg", "%s", vips_error_buffer() ); result = -1; } else { - vips_warn( "VipsFileLoadJpeg", + vips_warn( "VipsForeignLoadJpeg", _( "read gave %ld warnings" ), eman.pub.num_warnings ); - vips_warn( "VipsFileLoadJpeg", + vips_warn( "VipsForeignLoadJpeg", "%s", vips_error_buffer() ); } } @@ -904,43 +904,43 @@ vips_file_load_jpeg_load( VipsFileLoad *load ) static const char *jpeg_suffs[] = { ".jpg", ".jpeg", ".jpe", NULL }; static void -vips_file_load_jpeg_class_init( VipsFileLoadJpegClass *class ) +vips_foreign_load_jpeg_class_init( VipsForeignLoadJpegClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsFileClass *file_class = (VipsFileClass *) class; - VipsFileLoadClass *load_class = (VipsFileLoadClass *) class; + VipsForeignClass *file_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 = "jpegload"; object_class->description = _( "load jpeg from file" ); - object_class->build = vips_file_load_jpeg_build; + object_class->build = vips_foreign_load_jpeg_build; file_class->suffs = jpeg_suffs; - load_class->is_a = vips_file_load_jpeg_is_a; - load_class->header = vips_file_load_jpeg_header; - load_class->load = vips_file_load_jpeg_load; + load_class->is_a = vips_foreign_load_jpeg_is_a; + load_class->header = vips_foreign_load_jpeg_header; + load_class->load = vips_foreign_load_jpeg_load; VIPS_ARG_INT( class, "shrink", 10, _( "Shrink" ), _( "Shrink factor on load" ), VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsFileLoadJpeg, shrink ), + G_STRUCT_OFFSET( VipsForeignLoadJpeg, shrink ), 1, 16, 1 ); VIPS_ARG_BOOL( class, "fail", 11, _( "Fail" ), _( "Fail on first warning" ), VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsFileLoadJpeg, fail ), + G_STRUCT_OFFSET( VipsForeignLoadJpeg, fail ), FALSE ); } static void -vips_file_load_jpeg_init( VipsFileLoadJpeg *jpeg ) +vips_foreign_load_jpeg_init( VipsForeignLoadJpeg *jpeg ) { jpeg->shrink = 1; } diff --git a/libvips/file/jpegsave.c b/libvips/foreign/jpegsave.c similarity index 77% rename from libvips/file/jpegsave.c rename to libvips/foreign/jpegsave.c index f170a507..4d2f874b 100644 --- a/libvips/file/jpegsave.c +++ b/libvips/foreign/jpegsave.c @@ -75,8 +75,8 @@ #include "jpeg.h" -typedef struct _VipsFileSaveJpeg { - VipsFileSave parent_object; +typedef struct _VipsForeignSaveJpeg { + VipsForeignSave parent_object; /* Quality factor. */ @@ -86,20 +86,20 @@ typedef struct _VipsFileSaveJpeg { */ char *profile; -} VipsFileSaveJpeg; +} VipsForeignSaveJpeg; -typedef VipsFileSaveClass VipsFileSaveJpegClass; +typedef VipsForeignSaveClass VipsForeignSaveJpegClass; -G_DEFINE_TYPE( VipsFileSaveJpeg, vips_file_save_jpeg, VIPS_TYPE_FILE_SAVE ); +G_DEFINE_TYPE( VipsForeignSaveJpeg, vips_foreign_save_jpeg, VIPS_TYPE_FOREIGN_SAVE ); static int -vips_file_save_jpeg_build( VipsObject *object ) +vips_foreign_save_jpeg_build( VipsObject *object ) { - VipsFile *file = (VipsFile *) object; - VipsFileSave *save = (VipsFileSave *) object; - VipsFileSaveJpeg *jpeg = (VipsFileSaveJpeg *) object; + VipsForeign *file = (VipsForeign *) object; + VipsForeignSave *save = (VipsForeignSave *) object; + VipsForeignSaveJpeg *jpeg = (VipsForeignSaveJpeg *) object; - if( VIPS_OBJECT_CLASS( vips_file_save_jpeg_parent_class )-> + if( VIPS_OBJECT_CLASS( vips_foreign_save_jpeg_parent_class )-> build( object ) ) return( -1 ); @@ -122,19 +122,19 @@ static int bandfmt_jpeg[10] = { static const char *jpeg_suffs[] = { ".jpg", ".jpeg", ".jpe", NULL }; static void -vips_file_save_jpeg_class_init( VipsFileSaveJpegClass *class ) +vips_foreign_save_jpeg_class_init( VipsForeignSaveJpegClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsFileClass *file_class = (VipsFileClass *) class; - VipsFileSaveClass *save_class = (VipsFileSaveClass *) class; + VipsForeignClass *file_class = (VipsForeignClass *) class; + VipsForeignSaveClass *save_class = (VipsForeignSaveClass *) class; gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; object_class->nickname = "jpegsave"; object_class->description = _( "save image to jpeg file" ); - object_class->build = vips_file_save_jpeg_build; + object_class->build = vips_foreign_save_jpeg_build; file_class->suffs = jpeg_suffs; @@ -145,19 +145,19 @@ vips_file_save_jpeg_class_init( VipsFileSaveJpegClass *class ) _( "Q" ), _( "Q factor" ), VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsFileSaveJpeg, Q ), + G_STRUCT_OFFSET( VipsForeignSaveJpeg, Q ), 1, 100, 75 ); VIPS_ARG_STRING( class, "profile", 11, _( "profile" ), _( "ICC profile to embed" ), VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsFileSaveJpeg, profile ), + G_STRUCT_OFFSET( VipsForeignSaveJpeg, profile ), NULL ); } static void -vips_file_save_jpeg_init( VipsFileSaveJpeg *jpeg ) +vips_foreign_save_jpeg_init( VipsForeignSaveJpeg *jpeg ) { jpeg->Q = 75; } diff --git a/libvips/file/vips2jpeg.c b/libvips/foreign/vips2jpeg.c similarity index 100% rename from libvips/file/vips2jpeg.c rename to libvips/foreign/vips2jpeg.c diff --git a/libvips/file/vipsload.c b/libvips/foreign/vipsload.c similarity index 66% rename from libvips/file/vipsload.c rename to libvips/foreign/vipsload.c index ed123649..70b6056f 100644 --- a/libvips/file/vipsload.c +++ b/libvips/foreign/vipsload.c @@ -44,38 +44,38 @@ #include #include -typedef VipsFileLoad VipsFileLoadVips; -typedef VipsFileLoadClass VipsFileLoadVipsClass; +typedef VipsForeignLoad VipsForeignLoadVips; +typedef VipsForeignLoadClass VipsForeignLoadVipsClass; -G_DEFINE_TYPE( VipsFileLoadVips, vips_file_load_vips, VIPS_TYPE_FILE_LOAD ); +G_DEFINE_TYPE( VipsForeignLoadVips, vips_foreign_load_vips, VIPS_TYPE_FOREIGN_LOAD ); static gboolean -vips_file_load_vips_is_a( const char *filename ) +vips_foreign_load_vips_is_a( const char *filename ) { return( vips__file_magic( filename ) ); } static int -vips_file_load_vips_get_flags( VipsFileLoad *load ) +vips_foreign_load_vips_get_flags( VipsForeignLoad *load ) { - VipsFile *file = VIPS_FILE( load ); + VipsForeign *file = VIPS_FOREIGN( load ); - load->flags = VIPS_FILE_PARTIAL; + load->flags = VIPS_FOREIGN_PARTIAL; if( vips__file_magic( file->filename ) == VIPS_MAGIC_INTEL ) { - printf( "vips_file_load_vips_get_flags: " + printf( "vips_foreign_load_vips_get_flags: " "%s is intel, setting bigendian\n", file->filename ); - load->flags |= VIPS_FILE_BIGENDIAN; + load->flags |= VIPS_FOREIGN_BIGENDIAN; } return( 0 ); } static int -vips_file_load_vips_header( VipsFileLoad *load ) +vips_foreign_load_vips_header( VipsForeignLoad *load ) { - VipsFile *file = VIPS_FILE( load ); + VipsForeign *file = VIPS_FOREIGN( load ); VipsImage *out; VipsImage *out2; @@ -96,25 +96,25 @@ vips_file_load_vips_header( VipsFileLoad *load ) static const char *vips_suffs[] = { ".v", NULL }; static void -vips_file_load_vips_class_init( VipsFileLoadVipsClass *class ) +vips_foreign_load_vips_class_init( VipsForeignLoadVipsClass *class ) { VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsFileClass *file_class = (VipsFileClass *) class; - VipsFileLoadClass *load_class = (VipsFileLoadClass *) class; + VipsForeignClass *file_class = (VipsForeignClass *) class; + VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class; object_class->nickname = "vipsload"; object_class->description = _( "load vips from file" ); file_class->suffs = vips_suffs; - load_class->is_a = vips_file_load_vips_is_a; - load_class->get_flags = vips_file_load_vips_get_flags; - load_class->header = vips_file_load_vips_header; + load_class->is_a = vips_foreign_load_vips_is_a; + load_class->get_flags = vips_foreign_load_vips_get_flags; + load_class->header = vips_foreign_load_vips_header; load_class->load = NULL; } static void -vips_file_load_vips_init( VipsFileLoadVips *vips ) +vips_foreign_load_vips_init( VipsForeignLoadVips *vips ) { } diff --git a/libvips/file/vipssave.c b/libvips/foreign/vipssave.c similarity index 75% rename from libvips/file/vipssave.c rename to libvips/foreign/vipssave.c index 57080ea1..a629dd4c 100644 --- a/libvips/file/vipssave.c +++ b/libvips/foreign/vipssave.c @@ -46,18 +46,19 @@ #include -typedef VipsFileSave VipsFileSaveVips; -typedef VipsFileSaveClass VipsFileSaveVipsClass; +typedef VipsForeignSave VipsForeignSaveVips; +typedef VipsForeignSaveClass VipsForeignSaveVipsClass; -G_DEFINE_TYPE( VipsFileSaveVips, vips_file_save_vips, VIPS_TYPE_FILE_SAVE ); +G_DEFINE_TYPE( VipsForeignSaveVips, vips_foreign_save_vips, + VIPS_TYPE_FOREIGN_SAVE ); static int -vips_file_save_vips_build( VipsObject *object ) +vips_foreign_save_vips_build( VipsObject *object ) { - VipsFile *file = (VipsFile *) object; - VipsFileSave *save = (VipsFileSave *) object; + VipsForeign *file = (VipsForeign *) object; + VipsForeignSave *save = (VipsForeignSave *) object; - if( VIPS_OBJECT_CLASS( vips_file_save_vips_parent_class )-> + if( VIPS_OBJECT_CLASS( vips_foreign_save_vips_parent_class )-> build( object ) ) return( -1 ); @@ -91,15 +92,15 @@ static int vips_bandfmt_vips[10] = { static const char *vips_suffs[] = { ".v", NULL }; static void -vips_file_save_vips_class_init( VipsFileSaveVipsClass *class ) +vips_foreign_save_vips_class_init( VipsForeignSaveVipsClass *class ) { VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsFileClass *file_class = (VipsFileClass *) class; - VipsFileSaveClass *save_class = (VipsFileSaveClass *) class; + VipsForeignClass *file_class = (VipsForeignClass *) class; + VipsForeignSaveClass *save_class = (VipsForeignSaveClass *) class; object_class->nickname = "vipssave"; object_class->description = _( "save image to vips file" ); - object_class->build = vips_file_save_vips_build; + object_class->build = vips_foreign_save_vips_build; file_class->suffs = vips_suffs; @@ -108,7 +109,7 @@ vips_file_save_vips_class_init( VipsFileSaveVipsClass *class ) } static void -vips_file_save_vips_init( VipsFileSaveVips *vips ) +vips_foreign_save_vips_init( VipsForeignSaveVips *vips ) { } diff --git a/libvips/include/vips/Makefile.am b/libvips/include/vips/Makefile.am index 8ff58f75..e8a54ef9 100644 --- a/libvips/include/vips/Makefile.am +++ b/libvips/include/vips/Makefile.am @@ -14,7 +14,7 @@ pkginclude_HEADERS = \ error.h \ operation.h \ format.h \ - file.h \ + foreign.h \ inplace.h \ generate.h \ header.h \ @@ -57,7 +57,7 @@ EXTRA_DIST = version.h.in internal.h enumtemplate # well vips_scan_headers = \ ${top_srcdir}/libvips/include/vips/memory.h \ - ${top_srcdir}/libvips/include/vips/file.h \ + ${top_srcdir}/libvips/include/vips/foreign.h \ ${top_srcdir}/libvips/include/vips/arithmetic.h \ ${top_srcdir}/libvips/include/vips/conversion.h \ ${top_srcdir}/libvips/include/vips/util.h \ diff --git a/libvips/include/vips/enumtypes.h b/libvips/include/vips/enumtypes.h index 27ab323c..da662b48 100644 --- a/libvips/include/vips/enumtypes.h +++ b/libvips/include/vips/enumtypes.h @@ -6,9 +6,9 @@ G_BEGIN_DECLS -/* enumerations from "../../../libvips/include/vips/file.h" */ -GType vips_file_flags_get_type (void) G_GNUC_CONST; -#define VIPS_TYPE_FILE_FLAGS (vips_file_flags_get_type()) +/* enumerations from "../../../libvips/include/vips/foreign.h" */ +GType vips_foreign_flags_get_type (void) G_GNUC_CONST; +#define VIPS_TYPE_FOREIGN_FLAGS (vips_foreign_flags_get_type()) GType vips_saveable_get_type (void) G_GNUC_CONST; #define VIPS_TYPE_SAVEABLE (vips_saveable_get_type()) /* enumerations from "../../../libvips/include/vips/arithmetic.h" */ diff --git a/libvips/include/vips/file.h b/libvips/include/vips/file.h deleted file mode 100644 index 7c27e78a..00000000 --- a/libvips/include/vips/file.h +++ /dev/null @@ -1,239 +0,0 @@ -/* Base type for supported image files. Subclass this to add a new - * file. - */ - -/* - - 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 - - */ - -#ifndef VIPS_FILE_H -#define VIPS_FILE_H - -#ifdef __cplusplus -extern "C" { -#endif /*__cplusplus*/ - -#define VIPS_TYPE_FILE (vips_file_get_type()) -#define VIPS_FILE( obj ) \ - (G_TYPE_CHECK_INSTANCE_CAST( (obj), \ - VIPS_TYPE_FILE, VipsFile )) -#define VIPS_FILE_CLASS( klass ) \ - (G_TYPE_CHECK_CLASS_CAST( (klass), \ - VIPS_TYPE_FILE, VipsFileClass)) -#define VIPS_IS_FILE( obj ) \ - (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_FILE )) -#define VIPS_IS_FILE_CLASS( klass ) \ - (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_FILE )) -#define VIPS_FILE_GET_CLASS( obj ) \ - (G_TYPE_INSTANCE_GET_CLASS( (obj), \ - VIPS_TYPE_FILE, VipsFileClass )) - -typedef struct _VipsFile { - VipsOperation parent_object; - /*< public >*/ - - /* Filename for load or save. - */ - char *filename; - -} VipsFile; - -typedef struct _VipsFileClass { - VipsOperationClass parent_class; - - /*< public >*/ - - /* Loop over files in this order, default 0. We need this because - * some files can be read by several loaders (eg. tiff can be read - * by the libMagick loader as well as by the tiff loader), and we want - * to make sure the better loader comes first. - */ - int priority; - - /* Null-terminated list of recommended suffixes, eg. ".tif", ".tiff". - * This can be used by both load and save, so it's in the base class. - */ - const char **suffs; - -} VipsFileClass; - -GType vips_file_get_type( void ); - -/* Map over and find files. This uses type introspection to loop over - * subclasses of VipsFile. - */ -void *vips_file_map( const char *base, VipsSListMap2Fn fn, void *a, void *b ); - -#define VIPS_TYPE_FILE_LOAD (vips_file_load_get_type()) -#define VIPS_FILE_LOAD( obj ) \ - (G_TYPE_CHECK_INSTANCE_CAST( (obj), \ - VIPS_TYPE_FILE_LOAD, VipsFileLoad )) -#define VIPS_FILE_LOAD_CLASS( klass ) \ - (G_TYPE_CHECK_CLASS_CAST( (klass), \ - VIPS_TYPE_FILE_LOAD, VipsFileLoadClass)) -#define VIPS_IS_FILE_LOAD( obj ) \ - (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_FILE_LOAD )) -#define VIPS_IS_FILE_LOAD_CLASS( klass ) \ - (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_FILE_LOAD )) -#define VIPS_FILE_LOAD_GET_CLASS( obj ) \ - (G_TYPE_INSTANCE_GET_CLASS( (obj), \ - VIPS_TYPE_FILE_LOAD, VipsFileLoadClass )) - -/* Image file properties. - */ -typedef enum { - VIPS_FILE_NONE = 0, /* No flags set */ - VIPS_FILE_PARTIAL = 1, /* Lazy read OK (eg. tiled tiff) */ - VIPS_FILE_BIGENDIAN = 2 /* Most-significant byte first */ -} VipsFileFlags; - -typedef struct _VipsFileLoad { - VipsFile parent_object; - /*< public >*/ - - /* Open to disc (default is to open to memory). - */ - gboolean disc; - - /* Flags read from the file. - */ - VipsFileFlags flags; - - /* The image we generate. - */ - VipsImage *out; - - /* The behind-the-scenes real image we decompress to. This can be a - * disc file or a memory buffer. - */ - VipsImage *real; - -} VipsFileLoad; - -typedef struct _VipsFileLoadClass { - VipsFileClass parent_class; - - /*< public >*/ - - /* Is a file in this format. - */ - gboolean (*is_a)( const char * ); - - /* Get the flags for this file. - */ - int (*get_flags)( VipsFileLoad * ); - - /* Set the header fields in @out from @filename. If you can read the - * whole image as well with no performance cost (as with vipsload), - * leave ->load() NULL and only @header will be used. - */ - int (*header)( VipsFileLoad * ); - - /* Read the whole image into @real. It gets copied to @out later. - */ - int (*load)( VipsFileLoad * ); - -} VipsFileLoadClass; - -GType vips_file_load_get_type( void ); - -const char *vips_file_find_load( const char *filename ); - -#define VIPS_TYPE_FILE_SAVE (vips_file_save_get_type()) -#define VIPS_FILE_SAVE( obj ) \ - (G_TYPE_CHECK_INSTANCE_CAST( (obj), \ - VIPS_TYPE_FILE_SAVE, VipsFileSave )) -#define VIPS_FILE_SAVE_CLASS( klass ) \ - (G_TYPE_CHECK_CLASS_CAST( (klass), \ - VIPS_TYPE_FILE_SAVE, VipsFileSaveClass)) -#define VIPS_IS_FILE_SAVE( obj ) \ - (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_FILE_SAVE )) -#define VIPS_IS_FILE_SAVE_CLASS( klass ) \ - (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_FILE_SAVE )) -#define VIPS_FILE_SAVE_GET_CLASS( obj ) \ - (G_TYPE_INSTANCE_GET_CLASS( (obj), \ - VIPS_TYPE_FILE_SAVE, VipsFileSaveClass )) - -/** - * VipsSaveable: - * @VIPS_SAVEABLE_RGB: 1 or 3 bands (eg. PPM) - * @VIPS_SAVEABLE_RGBA: 1, 2, 3 or 4 bands (eg. PNG) - * @VIPS_SAVEABLE_RGB_CMYK: 1, 3 or 4 bands (eg. JPEG) - * @VIPS_SAVEABLE_ANY: any number of bands (eg. TIFF) - * - * See also: #VipsFileSave. - */ -typedef enum { - VIPS_SAVEABLE_RGB, - VIPS_SAVEABLE_RGBA, - VIPS_SAVEABLE_RGB_CMYK, - VIPS_SAVEABLE_ANY, - VIPS_SAVEABLE_LAST -} VipsSaveable; - -typedef struct _VipsFileSave { - VipsFile parent_object; - /*< public >*/ - - /* The image we are to save. - */ - VipsImage *in; - - /* The image converted to a saveable format (eg. 8-bit RGB). - */ - VipsImage *ready; - -} VipsFileSave; - -typedef struct _VipsFileSaveClass { - VipsFileClass parent_class; - - /*< public >*/ - - /* How this format treats bands. - */ - VipsSaveable saveable; - - /* How this format treats band formats. - */ - VipsBandFormat *format_table; -} VipsFileSaveClass; - -GType vips_file_save_get_type( void ); - -const char *vips_file_find_save( const char *filename ); - -/* Read/write an image convenience functions. - */ -int vips_file_read( const char *filename, VipsImage **out, ... ); -int vips_file_write( VipsImage *in, const char *filename, ... ); - -void vips_file_operation_init( void ); - -#ifdef __cplusplus -} -#endif /*__cplusplus*/ - -#endif /*VIPS_FILE_H*/ diff --git a/libvips/include/vips/foreign.h b/libvips/include/vips/foreign.h new file mode 100644 index 00000000..a2d12580 --- /dev/null +++ b/libvips/include/vips/foreign.h @@ -0,0 +1,239 @@ +/* Base type for supported image foreigns. Subclass this to add a new + * foreign. + */ + +/* + + This foreign 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 foreigns are distributed with VIPS - http://www.vips.ecs.soton.ac.uk + + */ + +#ifndef VIPS_FOREIGN_H +#define VIPS_FOREIGN_H + +#ifdef __cplusplus +extern "C" { +#endif /*__cplusplus*/ + +#define VIPS_TYPE_FOREIGN (vips_foreign_get_type()) +#define VIPS_FOREIGN( obj ) \ + (G_TYPE_CHECK_INSTANCE_CAST( (obj), \ + VIPS_TYPE_FOREIGN, VipsForeign )) +#define VIPS_FOREIGN_CLASS( klass ) \ + (G_TYPE_CHECK_CLASS_CAST( (klass), \ + VIPS_TYPE_FOREIGN, VipsForeignClass)) +#define VIPS_IS_FOREIGN( obj ) \ + (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_FOREIGN )) +#define VIPS_IS_FOREIGN_CLASS( klass ) \ + (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_FOREIGN )) +#define VIPS_FOREIGN_GET_CLASS( obj ) \ + (G_TYPE_INSTANCE_GET_CLASS( (obj), \ + VIPS_TYPE_FOREIGN, VipsForeignClass )) + +typedef struct _VipsForeign { + VipsOperation parent_object; + /*< public >*/ + + /* Filename for load or save. + */ + char *filename; + +} VipsForeign; + +typedef struct _VipsForeignClass { + VipsOperationClass parent_class; + + /*< public >*/ + + /* Loop over foreigns in this order, default 0. We need this because + * some foreigns can be read by several loaders (eg. tiff can be read + * by the libMagick loader as well as by the tiff loader), and we want + * to make sure the better loader comes first. + */ + int priority; + + /* Null-terminated list of recommended suffixes, eg. ".tif", ".tiff". + * This can be used by both load and save, so it's in the base class. + */ + const char **suffs; + +} VipsForeignClass; + +GType vips_foreign_get_type( void ); + +/* Map over and find foreigns. This uses type introspection to loop over + * subclasses of VipsForeign. + */ +void *vips_foreign_map( const char *base, VipsSListMap2Fn fn, void *a, void *b ); + +#define VIPS_TYPE_FOREIGN_LOAD (vips_foreign_load_get_type()) +#define VIPS_FOREIGN_LOAD( obj ) \ + (G_TYPE_CHECK_INSTANCE_CAST( (obj), \ + VIPS_TYPE_FOREIGN_LOAD, VipsForeignLoad )) +#define VIPS_FOREIGN_LOAD_CLASS( klass ) \ + (G_TYPE_CHECK_CLASS_CAST( (klass), \ + VIPS_TYPE_FOREIGN_LOAD, VipsForeignLoadClass)) +#define VIPS_IS_FOREIGN_LOAD( obj ) \ + (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_FOREIGN_LOAD )) +#define VIPS_IS_FOREIGN_LOAD_CLASS( klass ) \ + (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_FOREIGN_LOAD )) +#define VIPS_FOREIGN_LOAD_GET_CLASS( obj ) \ + (G_TYPE_INSTANCE_GET_CLASS( (obj), \ + VIPS_TYPE_FOREIGN_LOAD, VipsForeignLoadClass )) + +/* Image foreign properties. + */ +typedef enum { + VIPS_FOREIGN_NONE = 0, /* No flags set */ + VIPS_FOREIGN_PARTIAL = 1, /* Lazy read OK (eg. tiled tiff) */ + VIPS_FOREIGN_BIGENDIAN = 2 /* Most-significant byte first */ +} VipsForeignFlags; + +typedef struct _VipsForeignLoad { + VipsForeign parent_object; + /*< public >*/ + + /* Open to disc (default is to open to memory). + */ + gboolean disc; + + /* Flags read from the foreign. + */ + VipsForeignFlags flags; + + /* The image we generate. + */ + VipsImage *out; + + /* The behind-the-scenes real image we decompress to. This can be a + * disc foreign or a memory buffer. + */ + VipsImage *real; + +} VipsForeignLoad; + +typedef struct _VipsForeignLoadClass { + VipsForeignClass parent_class; + + /*< public >*/ + + /* Is a foreign in this format. + */ + gboolean (*is_a)( const char * ); + + /* Get the flags for this foreign. + */ + int (*get_flags)( VipsForeignLoad * ); + + /* Set the header fields in @out from @foreignname. If you can read the + * whole image as well with no performance cost (as with vipsload), + * leave ->load() NULL and only @header will be used. + */ + int (*header)( VipsForeignLoad * ); + + /* Read the whole image into @real. It gets copied to @out later. + */ + int (*load)( VipsForeignLoad * ); + +} VipsForeignLoadClass; + +GType vips_foreign_load_get_type( void ); + +const char *vips_foreign_find_load( const char *foreignname ); + +#define VIPS_TYPE_FOREIGN_SAVE (vips_foreign_save_get_type()) +#define VIPS_FOREIGN_SAVE( obj ) \ + (G_TYPE_CHECK_INSTANCE_CAST( (obj), \ + VIPS_TYPE_FOREIGN_SAVE, VipsForeignSave )) +#define VIPS_FOREIGN_SAVE_CLASS( klass ) \ + (G_TYPE_CHECK_CLASS_CAST( (klass), \ + VIPS_TYPE_FOREIGN_SAVE, VipsForeignSaveClass)) +#define VIPS_IS_FOREIGN_SAVE( obj ) \ + (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_FOREIGN_SAVE )) +#define VIPS_IS_FOREIGN_SAVE_CLASS( klass ) \ + (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_FOREIGN_SAVE )) +#define VIPS_FOREIGN_SAVE_GET_CLASS( obj ) \ + (G_TYPE_INSTANCE_GET_CLASS( (obj), \ + VIPS_TYPE_FOREIGN_SAVE, VipsForeignSaveClass )) + +/** + * VipsSaveable: + * @VIPS_SAVEABLE_RGB: 1 or 3 bands (eg. PPM) + * @VIPS_SAVEABLE_RGBA: 1, 2, 3 or 4 bands (eg. PNG) + * @VIPS_SAVEABLE_RGB_CMYK: 1, 3 or 4 bands (eg. JPEG) + * @VIPS_SAVEABLE_ANY: any number of bands (eg. TIFF) + * + * See also: #VipsForeignSave. + */ +typedef enum { + VIPS_SAVEABLE_RGB, + VIPS_SAVEABLE_RGBA, + VIPS_SAVEABLE_RGB_CMYK, + VIPS_SAVEABLE_ANY, + VIPS_SAVEABLE_LAST +} VipsSaveable; + +typedef struct _VipsForeignSave { + VipsForeign parent_object; + /*< public >*/ + + /* The image we are to save. + */ + VipsImage *in; + + /* The image converted to a saveable format (eg. 8-bit RGB). + */ + VipsImage *ready; + +} VipsForeignSave; + +typedef struct _VipsForeignSaveClass { + VipsForeignClass parent_class; + + /*< public >*/ + + /* How this format treats bands. + */ + VipsSaveable saveable; + + /* How this format treats band formats. + */ + VipsBandFormat *format_table; +} VipsForeignSaveClass; + +GType vips_foreign_save_get_type( void ); + +const char *vips_foreign_find_save( const char *filename ); + +/* Read/write an image convenience functions. + */ +int vips_foreign_read( const char *filename, VipsImage **out, ... ); +int vips_foreign_write( VipsImage *in, const char *filename, ... ); + +void vips_foreign_operation_init( void ); + +#ifdef __cplusplus +} +#endif /*__cplusplus*/ + +#endif /*VIPS_FOREIGN_H*/ diff --git a/libvips/include/vips/vips.h b/libvips/include/vips/vips.h index f8833eb8..6108a4b0 100644 --- a/libvips/include/vips/vips.h +++ b/libvips/include/vips/vips.h @@ -116,7 +116,7 @@ extern "C" { #include #include #include -#include +#include #include diff --git a/libvips/iofuncs/Makefile.am b/libvips/iofuncs/Makefile.am index 784f936b..6674a666 100644 --- a/libvips/iofuncs/Makefile.am +++ b/libvips/iofuncs/Makefile.am @@ -41,7 +41,7 @@ INCLUDES = -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@ # well vips_scan_headers = \ ${top_srcdir}/libvips/include/vips/memory.h \ - ${top_srcdir}/libvips/include/vips/file.h \ + ${top_srcdir}/libvips/include/vips/foreign.h \ ${top_srcdir}/libvips/include/vips/conversion.h \ ${top_srcdir}/libvips/include/vips/arithmetic.h \ ${top_srcdir}/libvips/include/vips/util.h \ diff --git a/libvips/iofuncs/enumtypes.c b/libvips/iofuncs/enumtypes.c index ef3548b7..93d73650 100644 --- a/libvips/iofuncs/enumtypes.c +++ b/libvips/iofuncs/enumtypes.c @@ -4,21 +4,21 @@ /* auto-generated enums for vips introspection */ #include -/* enumerations from "../../libvips/include/vips/file.h" */ +/* enumerations from "../../libvips/include/vips/foreign.h" */ GType -vips_file_flags_get_type( void ) +vips_foreign_flags_get_type( void ) { static GType etype = 0; if( etype == 0 ) { static const GEnumValue values[] = { - {VIPS_FILE_NONE, "VIPS_FILE_NONE", "none"}, - {VIPS_FILE_PARTIAL, "VIPS_FILE_PARTIAL", "partial"}, - {VIPS_FILE_BIGENDIAN, "VIPS_FILE_BIGENDIAN", "bigendian"}, + {VIPS_FOREIGN_NONE, "VIPS_FOREIGN_NONE", "none"}, + {VIPS_FOREIGN_PARTIAL, "VIPS_FOREIGN_PARTIAL", "partial"}, + {VIPS_FOREIGN_BIGENDIAN, "VIPS_FOREIGN_BIGENDIAN", "bigendian"}, {0, NULL, NULL} }; - etype = g_enum_register_static( "VipsFileFlags", values ); + etype = g_enum_register_static( "VipsForeignFlags", values ); } return( etype ); diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index d24d979d..4ccaed2a 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -472,7 +472,7 @@ vips_image_rewind( VipsObject *object ) static void vips_image_save_cb( VipsImage *image, int *result, char *filename ) { - if( vips_file_write( image, filename, NULL ) ) + if( vips_foreign_write( image, filename, NULL ) ) *result = -1; g_free( filename ); @@ -628,7 +628,7 @@ vips_image_build( VipsObject *object ) else { VipsImage *t; - if( vips_file_read( filename, &t, NULL ) ) + if( vips_foreign_read( filename, &t, NULL ) ) return( -1 ); image->dtype = VIPS_IMAGE_PARTIAL; @@ -645,7 +645,7 @@ vips_image_build( VipsObject *object ) { const char *file_op; - if( !(file_op = vips_file_find_save( filename )) ) + if( !(file_op = vips_foreign_find_save( filename )) ) return( -1 ); if( strcmp( file_op, "VipsFileSaveVips" ) == 0 ) diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index a51079a1..bf0b51f1 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -231,7 +231,7 @@ vips_init( const char *argv0 ) */ vips_arithmetic_operation_init(); vips_conversion_operation_init(); - vips_file_operation_init(); + vips_foreign_operation_init(); /* Load up any plugins in the vips libdir. We don't error on failure, * it's too annoying to have VIPS refuse to start because of a broken diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index fcfe2a91..524edcb5 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -1232,7 +1232,7 @@ vips_object_set_argument_from_string( VipsObject *object, g_assert( argument_class->flags & VIPS_ARGUMENT_INPUT ); if( g_type_is_a( otype, VIPS_TYPE_IMAGE ) && - (oclass = g_type_class_ref( VIPS_TYPE_FILE_LOAD )) ) { + (oclass = g_type_class_ref( VIPS_TYPE_FOREIGN_LOAD )) ) { VipsObject *new_object; VipsImage *out; @@ -1418,7 +1418,7 @@ vips_object_get_argument_to_string( VipsObject *object, g_assert( argument_class->flags & VIPS_ARGUMENT_OUTPUT ); if( g_type_is_a( otype, VIPS_TYPE_IMAGE ) && - (oclass = g_type_class_ref( VIPS_TYPE_FILE_SAVE )) ) { + (oclass = g_type_class_ref( VIPS_TYPE_FOREIGN_SAVE )) ) { VipsObject *new_object; VipsImage *in; From 935c713e71ef7fae2ad47a7121f5e1b2b94b9b8a Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 29 Nov 2011 12:11:33 +0000 Subject: [PATCH 3/4] sort out jpegload --- TODO | 16 +- libvips/foreign/jpeg2vips.c | 9 +- libvips/foreign/jpegload.c | 734 +-------------------------------- libvips/foreign/jpegsave.c | 8 +- libvips/foreign/vipsload.c | 14 +- libvips/foreign/vipssave.c | 8 +- libvips/include/vips/foreign.h | 9 +- libvips/iofuncs/image.c | 5 +- 8 files changed, 54 insertions(+), 749 deletions(-) diff --git a/TODO b/TODO index 8ff06135..530f63fe 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,9 @@ +- test vips_foreign_load_vips_get_flags(), sense inverted? -- rename file as VipsForeign - at the moment we have: + + +- at the moment we have: VipsFile (filename, priority, suffs) VipsFileLoad (disc, flags, out, real, is_a, get_flags, header, load) @@ -24,6 +26,16 @@ VipsForeignSaveJpegFile (filename, suffs) VipsForeignSaveJpegBuffer (buffer) + how do we do 'pick a loader by filename'? we need to find all subclasses of + VipsForeign which implement suffs? + + we're going to need to register loaders and savers on a separate list + somewhere :-( + + or have load-from-file as an interface? + + + diff --git a/libvips/foreign/jpeg2vips.c b/libvips/foreign/jpeg2vips.c index 10901787..ce1c8ddf 100644 --- a/libvips/foreign/jpeg2vips.c +++ b/libvips/foreign/jpeg2vips.c @@ -717,8 +717,8 @@ read_jpeg_image( struct jpeg_decompress_struct *cinfo, IMAGE *out, /* Read a JPEG file into a VIPS image. */ int -vips__jpeg2vips( const char *filename, VipsImage *out, gboolean header_only, - int shrink, gboolean fail ) +vips__jpeg_read_file( const char *filename, VipsImage *out, + gboolean header_only, int shrink, gboolean fail ) { struct jpeg_decompress_struct cinfo; ErrorManager eman; @@ -954,9 +954,8 @@ buf_source (j_decompress_ptr cinfo, void *buf, size_t len) } int -vips__bufjpeg2vips( void *buf, size_t len, VipsImage *out, - gboolean header_only, - int shrink, int fail ) +vips__jpeg_read_buffer( void *buf, size_t len, VipsImage *out, + gboolean header_only, int shrink, int fail ) { struct jpeg_decompress_struct cinfo; ErrorManager eman; diff --git a/libvips/foreign/jpegload.c b/libvips/foreign/jpegload.c index 03d925ba..b6f07354 100644 --- a/libvips/foreign/jpegload.c +++ b/libvips/foreign/jpegload.c @@ -133,7 +133,8 @@ typedef struct _VipsForeignLoadJpeg { typedef VipsForeignLoadClass VipsForeignLoadJpegClass; -G_DEFINE_TYPE( VipsForeignLoadJpeg, vips_foreign_load_jpeg, VIPS_TYPE_FOREIGN_LOAD ); +G_DEFINE_TYPE( VipsForeignLoadJpeg, vips_foreign_load_jpeg, + VIPS_TYPE_FOREIGN_LOAD ); static int vips_foreign_load_jpeg_build( VipsObject *object ) @@ -159,577 +160,7 @@ vips_foreign_load_jpeg_build( VipsObject *object ) static gboolean vips_foreign_load_jpeg_is_a( const char *filename ) { - unsigned char buf[2]; - - if( vips__get_bytes( filename, buf, 2 ) ) - if( (int) buf[0] == 0xff && (int) buf[1] == 0xd8 ) - return( TRUE ); - - return( FALSE ); -} - -/* Read a cinfo to a VIPS image. Set invert_pels if the pixel reader needs to - * do 255-pel. - */ -static int -vips_foreign_load_jpeg_read_header( VipsForeignLoadJpeg *jpeg, - struct jpeg_decompress_struct *cinfo, VipsImage *out ) -{ - int type; - - /* Read JPEG header. libjpeg will set out_color_space sanely for us - * for YUV YCCK etc. - */ - jpeg_read_header( cinfo, TRUE ); - cinfo->scale_denom = jpeg->shrink; - cinfo->scale_num = 1; - jpeg_calc_output_dimensions( cinfo ); - - switch( cinfo->out_color_space ) { - case JCS_GRAYSCALE: - type = IM_TYPE_B_W; - break; - - case JCS_CMYK: - type = IM_TYPE_CMYK; - /* Photoshop writes CMYK JPEG inverted :-( Maybe this is a - * way to spot photoshop CMYK JPGs. - */ - if( cinfo->saw_Adobe_marker ) - jpeg->invert_pels = TRUE; - break; - - case JCS_RGB: - default: - type = IM_TYPE_sRGB; - break; - } - - /* Set VIPS header. - */ - vips_image_init_fields( out, - cinfo->output_width, cinfo->output_height, - cinfo->output_components, - VIPS_FORMAT_UCHAR, VIPS_CODING_NONE, type, - 1.0, 1.0 ); - - return( 0 ); -} - -#ifdef HAVE_EXIF -#ifdef DEBUG_VERBOSE -/* Print exif for debugging ... hacked from exif-0.6.9/actions.c - */ -static void -show_tags( ExifData *data ) -{ - int i; - unsigned int tag; - const char *name; - - printf( "show EXIF tags:\n" ); - - for( i = 0; i < EXIF_IFD_COUNT; i++ ) - printf( "%-7.7s", exif_ifd_get_name( i ) ); - printf( "\n" ); - - for( tag = 0; tag < 0xffff; tag++ ) { - name = exif_tag_get_title( tag ); - if( !name ) - continue; - printf( " 0x%04x %-29.29s", tag, name ); - for( i = 0; i < EXIF_IFD_COUNT; i++ ) - if( exif_content_get_entry( data->ifd[i], tag ) ) - printf( " * " ); - else - printf( " - " ); - printf( "\n" ); - } -} - -static void -show_entry( ExifEntry *entry, void *client ) -{ - char exif_text[256]; - - printf( "%s", exif_tag_get_title( entry->tag ) ); - printf( "|" ); - printf( "%s", exif_entry_get_value( entry, exif_text, 256 ) ); - printf( "|" ); - printf( "%s", exif_format_get_name( entry->format ) ); - printf( "|" ); - printf( "%d bytes", entry->size ); - printf( "\n" ); -} - -static void -show_ifd( ExifContent *content, void *client ) -{ - exif_content_foreach_entry( content, show_entry, client ); - printf( "-\n" ); -} - -void -show_values( ExifData *data ) -{ - ExifByteOrder order; - - order = exif_data_get_byte_order( data ); - printf( "EXIF tags in '%s' byte order\n", - exif_byte_order_get_name( order ) ); - - printf( "%-20.20s", "Tag" ); - printf( "|" ); - printf( "%-58.58s", "Value" ); - printf( "\n" ); - - exif_data_foreach_content( data, show_ifd, NULL ); - - if( data->size ) - printf( "contains thumbnail of %d bytes\n", data->size ); -} -#endif /*DEBUG_VERBOSE*/ -#endif /*HAVE_EXIF*/ - -#ifdef HAVE_EXIF - -static int -vips_exif_get_int( ExifData *ed, - ExifEntry *entry, unsigned long component, int *out ) -{ - ExifByteOrder bo = exif_data_get_byte_order( ed ); - size_t sizeof_component = entry->size / entry->components; - size_t offset = component * sizeof_component; - - if( entry->format == EXIF_FORMAT_SHORT ) - *out = exif_get_short( entry->data + offset, bo ); - else if( entry->format == EXIF_FORMAT_SSHORT ) - *out = exif_get_sshort( entry->data + offset, bo ); - else if( entry->format == EXIF_FORMAT_LONG ) - /* This won't work for huge values, but who cares. - */ - *out = (int) exif_get_long( entry->data + offset, bo ); - else if( entry->format == EXIF_FORMAT_SLONG ) - *out = exif_get_slong( entry->data + offset, bo ); - else - return( -1 ); - - return( 0 ); -} - -static int -vips_exif_get_double( ExifData *ed, - ExifEntry *entry, unsigned long component, double *out ) -{ - ExifByteOrder bo = exif_data_get_byte_order( ed ); - size_t sizeof_component = entry->size / entry->components; - size_t offset = component * sizeof_component; - - if( entry->format == EXIF_FORMAT_RATIONAL ) { - ExifRational value; - - value = exif_get_rational( entry->data + offset, bo ); - *out = (double) value.numerator / value.denominator; - } - else if( entry->format == EXIF_FORMAT_SRATIONAL ) { - ExifSRational value; - - value = exif_get_srational( entry->data + offset, bo ); - *out = (double) value.numerator / value.denominator; - } - else - return( -1 ); - - return( 0 ); -} - -/* Save an exif value to a string in a way that we can restore. We only bother - * for the simple formats (that a client might try to change) though. - * - * Keep in sync with vips_exif_from_s() in vips2jpeg. - */ -static void -vips_exif_to_s( ExifData *ed, ExifEntry *entry, VipsBuf *buf ) -{ - unsigned long i; - int iv; - double dv; - char txt[256]; - - if( entry->format == EXIF_FORMAT_ASCII ) - vips_buf_appendf( buf, "%s ", entry->data ); - - else if( entry->components < 10 && - !vips_exif_get_int( ed, entry, 0, &iv ) ) { - for( i = 0; i < entry->components; i++ ) { - vips_exif_get_int( ed, entry, i, &iv ); - vips_buf_appendf( buf, "%d ", iv ); - } - } - else if( entry->components < 10 && - !vips_exif_get_double( ed, entry, 0, &dv ) ) { - for( i = 0; i < entry->components; i++ ) { - vips_exif_get_double( ed, entry, i, &dv ); - /* Need to be locale independent. - */ - g_ascii_dtostr( txt, 256, dv ); - vips_buf_appendf( buf, "%s ", txt ); - } - } - else - vips_buf_appendf( buf, "%s ", - exif_entry_get_value( entry, txt, 256 ) ); - - vips_buf_appendf( buf, "(%s, %s, %lu components, %d bytes)", - exif_entry_get_value( entry, txt, 256 ), - exif_format_get_name( entry->format ), - entry->components, - entry->size ); -} - -typedef struct _VipsExif { - VipsImage *image; - ExifData *ed; -} VipsExif; - -static void -attach_exif_entry( ExifEntry *entry, VipsExif *ve ) -{ - char name_txt[256]; - VipsBuf name = VIPS_BUF_STATIC( name_txt ); - char value_txt[256]; - VipsBuf value = VIPS_BUF_STATIC( value_txt ); - - vips_buf_appendf( &name, "exif-%s", exif_tag_get_title( entry->tag ) ); - vips_exif_to_s( ve->ed, entry, &value ); - - /* Can't do anything sensible with the error return. - */ - (void) im_meta_set_string( ve->image, - vips_buf_all( &name ), vips_buf_all( &value ) ); -} - -static void -attach_exif_content( ExifContent *content, VipsExif *ve ) -{ - exif_content_foreach_entry( content, - (ExifContentForeachEntryFunc) attach_exif_entry, ve ); -} - -/* Just find the first occurence of the tag (is this correct?) - */ -static ExifEntry * -find_entry( ExifData *ed, ExifTag tag ) -{ - int i; - - for( i = 0; i < EXIF_IFD_COUNT; i++ ) { - ExifEntry *entry; - - if( (entry = exif_content_get_entry( ed->ifd[i], tag )) ) - return( entry ); - } - - return( NULL ); -} - -static int -get_entry_rational( ExifData *ed, ExifTag tag, double *out ) -{ - ExifEntry *entry; - - if( !(entry = find_entry( ed, tag )) || - entry->format != EXIF_FORMAT_RATIONAL || - entry->components != 1 ) - return( -1 ); - - return( vips_exif_get_double( ed, entry, 0, out ) ); -} - -static int -get_entry_short( ExifData *ed, ExifTag tag, int *out ) -{ - ExifEntry *entry; - - if( !(entry = find_entry( ed, tag )) || - entry->format != EXIF_FORMAT_SHORT || - entry->components != 1 ) - return( -1 ); - - return( vips_exif_get_int( ed, entry, 0, out ) ); -} - -static void -set_vips_resolution( IMAGE *im, ExifData *ed ) -{ - double xres, yres; - int unit; - - if( get_entry_rational( ed, EXIF_TAG_X_RESOLUTION, &xres ) || - get_entry_rational( ed, EXIF_TAG_Y_RESOLUTION, &yres ) || - get_entry_short( ed, EXIF_TAG_RESOLUTION_UNIT, &unit ) ) { - im_warn( "im_jpeg2vips", - "%s", _( "error reading resolution" ) ); - return; - } - - switch( unit ) { - case 2: - /* In inches. - */ - xres /= 25.4; - yres /= 25.4; - break; - - case 3: - /* In cm. - */ - xres /= 10.0; - yres /= 10.0; - break; - - default: - im_warn( "im_jpeg2vips", "%s", _( "bad resolution unit" ) ); - return; - } - - im->Xres = xres; - im->Yres = yres; -} - -static int -attach_thumbnail( IMAGE *im, ExifData *ed ) -{ - if( ed->size > 0 ) { - char *thumb_copy; - - thumb_copy = im_malloc( NULL, ed->size ); - memcpy( thumb_copy, ed->data, ed->size ); - - if( im_meta_set_blob( im, "jpeg-thumbnail-data", - (im_callback_fn) im_free, thumb_copy, ed->size ) ) { - im_free( thumb_copy ); - return( -1 ); - } - } - - return( 0 ); -} -#endif /*HAVE_EXIF*/ - -static int -read_exif( IMAGE *im, void *data, int data_length ) -{ - char *data_copy; - - /* Only use the first one. - */ - if( im_header_get_typeof( im, IM_META_EXIF_NAME ) ) { -#ifdef DEBUG - printf( "read_exif: second EXIF block, ignoring\n" ); -#endif /*DEBUG*/ - - return( 0 ); - } - -#ifdef DEBUG - printf( "read_exif: attaching %d bytes of exif\n", data_length ); -#endif /*DEBUG*/ - - /* Always attach a copy of the unparsed exif data. - */ - if( !(data_copy = im_malloc( NULL, data_length )) ) - return( -1 ); - memcpy( data_copy, data, data_length ); - if( im_meta_set_blob( im, IM_META_EXIF_NAME, - (im_callback_fn) im_free, data_copy, data_length ) ) { - im_free( data_copy ); - return( -1 ); - } - -#ifdef HAVE_EXIF -{ - ExifData *ed; - - if( !(ed = exif_data_new_from_data( data, data_length )) ) - return( -1 ); - - if( ed->size > 0 ) { - VipsExif ve; - -#ifdef DEBUG_VERBOSE - show_tags( ed ); - show_values( ed ); -#endif /*DEBUG_VERBOSE*/ - - /* Attach informational fields for what we find. - - FIXME ... better to have this in the UI layer? - - Or we could attach non-human-readable tags here (int, - double etc) and then move the human stuff to the UI - layer? - - */ - ve.image = im; - ve.ed = ed; - exif_data_foreach_content( ed, - (ExifDataForeachContentFunc) attach_exif_content, &ve ); - - /* Look for resolution fields and use them to set the VIPS - * xres/yres fields. - */ - set_vips_resolution( im, ed ); - - attach_thumbnail( im, ed ); - } - - exif_data_free( ed ); -} -#endif /*HAVE_EXIF*/ - - return( 0 ); -} - -static int -read_xmp( IMAGE *im, void *data, int data_length ) -{ - char *data_copy; - - /* XMP sections start "http". Only use the first one. - */ - if( im_header_get_typeof( im, VIPS_META_XMP_NAME ) ) { -#ifdef DEBUG - printf( "read_xmp: second XMP block, ignoring\n" ); -#endif /*DEBUG*/ - - return( 0 ); - } - -#ifdef DEBUG - printf( "read_xmp: attaching %d bytes of XMP\n", data_length ); -#endif /*DEBUG*/ - - /* Always attach a copy of the unparsed exif data. - */ - if( !(data_copy = im_malloc( NULL, data_length )) ) - return( -1 ); - memcpy( data_copy, data, data_length ); - if( im_meta_set_blob( im, VIPS_META_XMP_NAME, - (im_callback_fn) im_free, data_copy, data_length ) ) { - im_free( data_copy ); - return( -1 ); - } - - return( 0 ); -} - -/* Number of app2 sections we can capture. Each one can be 64k, so 6400k should - * be enough for anyone (haha). - */ -#define MAX_APP2_SECTIONS (100) - -static int -vips_foreign_load_jpeg_meta( VipsForeignLoadJpeg *jpeg, - struct jpeg_decompress_struct *cinfo, VipsImage *out ) -{ - /* Capture app2 sections here for assembly. - */ - void *app2_data[MAX_APP2_SECTIONS] = { 0 }; - int app2_data_length[MAX_APP2_SECTIONS] = { 0 }; - int data_length; - jpeg_saved_marker_ptr p; - int i; - - /* Interlaced jpegs need lots of memory to read, so our caller needs - * to know. - */ - vips_image_set_int( out, "jpeg-multiscan", - jpeg_has_multiple_scans( cinfo ) ); - - /* Look for EXIF and ICC profile. - */ - for( p = cinfo->marker_list; p; p = p->next ) { -#ifdef DEBUG -{ - printf( "vips_foreign_load_jpeg_read_header: " - "seen %d bytes of APP%d\n", - p->data_length, - p->marker - JPEG_APP0 ); - - for( i = 0; i < 10; i++ ) - printf( "\t%d) '%c' (%d)\n", - i, p->data[i], p->data[i] ); -} -#endif /*DEBUG*/ - - switch( p->marker ) { - case JPEG_APP0 + 1: - /* Possible EXIF or XMP data. - */ - if( p->data_length > 4 && - im_isprefix( "Exif", (char *) p->data ) && - read_exif( out, p->data, p->data_length ) ) - return( -1 ); - - if( p->data_length > 4 && - im_isprefix( "http", (char *) p->data ) && - read_xmp( out, p->data, p->data_length ) ) - return( -1 ); - - break; - - case JPEG_APP0 + 2: - /* ICC profile. - */ - if( p->data_length > 14 && - im_isprefix( "ICC_PROFOREIGN", - (char *) p->data ) ) { - /* cur_marker numbers from 1, according to - * spec. - */ - int cur_marker = p->data[12] - 1; - - if( cur_marker >= 0 && - cur_marker < MAX_APP2_SECTIONS ) { - app2_data[cur_marker] = p->data + 14; - app2_data_length[cur_marker] = - p->data_length - 14; - } - } - break; - - default: - break; - } - } - - /* Assemble ICC sections. - */ - data_length = 0; - for( i = 0; i < MAX_APP2_SECTIONS && app2_data[i]; i++ ) - data_length += app2_data_length[i]; - if( data_length ) { - unsigned char *data; - int x; - -#ifdef DEBUG - printf( "vips_foreign_load_jpeg_read_header: " - "assembled %d byte ICC profile\n", - data_length ); -#endif /*DEBUG*/ - - data = g_malloc( data_length ); - x = 0; - for( i = 0; i < MAX_APP2_SECTIONS && app2_data[i]; i++ ) { - memcpy( data + x, app2_data[i], app2_data_length[i] ); - x += app2_data_length[i]; - } - vips_image_set_blob( out, VIPS_META_ICC_NAME, - (VipsCallbackFn) g_free, data, data_length ); - } - - return( 0 ); + return( vips__isjpeg( filename ) ); } /* Read just the image header into ->out. @@ -737,102 +168,12 @@ vips_foreign_load_jpeg_meta( VipsForeignLoadJpeg *jpeg, static int vips_foreign_load_jpeg_header( VipsForeignLoad *load ) { - VipsForeign *file = VIPS_FOREIGN( load ); + VipsForeign *foreign = VIPS_FOREIGN( load ); VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load; - struct jpeg_decompress_struct cinfo; - ErrorManager eman; - FILE *fp; - int result; - - /* Make jpeg dcompression object. - */ - cinfo.err = jpeg_std_error( &eman.pub ); - eman.pub.error_exit = vips__new_error_exit; - eman.pub.output_message = vips__new_output_message; - eman.fp = NULL; - if( setjmp( eman.jmp ) ) { - /* Here for longjmp() from vips__new_error_exit(). - */ - jpeg_destroy_decompress( &cinfo ); - + if( vips__jpeg_read_file( foreign->filename, load->out, + TRUE, jpeg->shrink, jpeg->fail ) ) return( -1 ); - } - jpeg_create_decompress( &cinfo ); - - /* Make input. - */ - if( !(fp = vips__file_open_read( file->filename, NULL, FALSE )) ) - return( -1 ); - eman.fp = fp; - jpeg_stdio_src( &cinfo, fp ); - - /* Need to read in APP1 (EXIF metadata) and APP2 (ICC profile). - */ - jpeg_save_markers( &cinfo, JPEG_APP0 + 1, 0xffff ); - jpeg_save_markers( &cinfo, JPEG_APP0 + 2, 0xffff ); - - /* Convert! - */ - result = vips_foreign_load_jpeg_read_header( jpeg, &cinfo, load->out ); - - /* Get extra metadata too. - */ - if( !result ) - result = vips_foreign_load_jpeg_meta( jpeg, &cinfo, load->out ); - - /* Close and tidy. - */ - fclose( fp ); - eman.fp = NULL; - jpeg_destroy_decompress( &cinfo ); - - return( result ); -} - -/* Read a cinfo to a VIPS image. - */ -static int -vips_foreign_load_jpeg_read_image( VipsForeignLoadJpeg *jpeg, - struct jpeg_decompress_struct *cinfo, VipsImage *out ) -{ - int x, y, sz; - JSAMPROW row_pointer[1]; - - /* Check VIPS. - */ - if( vips_image_wio_output( out ) ) - return( -1 ); - - /* Get size of output line and make a buffer. - */ - sz = cinfo->output_width * cinfo->output_components; - row_pointer[0] = (JSAMPLE *) (*cinfo->mem->alloc_large) - ( (j_common_ptr) cinfo, JPOOL_IMAGE, sz ); - - /* Start up decompressor. - */ - jpeg_start_decompress( cinfo ); - - /* Process image. - */ - for( y = 0; y < out->Ysize; y++ ) { - /* We set an error handler that longjmps() out, so I don't - * think this can fail. - */ - jpeg_read_scanlines( cinfo, &row_pointer[0], 1 ); - - if( jpeg->invert_pels ) { - for( x = 0; x < sz; x++ ) - row_pointer[0][x] = 255 - row_pointer[0][x]; - } - if( vips_image_write_line( out, y, row_pointer[0] ) ) - return( -1 ); - } - - /* Stop decompressor. - */ - jpeg_finish_decompress( cinfo ); return( 0 ); } @@ -840,65 +181,14 @@ vips_foreign_load_jpeg_read_image( VipsForeignLoadJpeg *jpeg, static int vips_foreign_load_jpeg_load( VipsForeignLoad *load ) { - VipsForeign *file = VIPS_FOREIGN( load ); + VipsForeign *foreign = VIPS_FOREIGN( load ); VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load; - struct jpeg_decompress_struct cinfo; - ErrorManager eman; - FILE *fp; - int result; - - /* Make jpeg dcompression object. - */ - cinfo.err = jpeg_std_error( &eman.pub ); - eman.pub.error_exit = vips__new_error_exit; - eman.pub.output_message = vips__new_output_message; - eman.fp = NULL; - if( setjmp( eman.jmp ) ) { - /* Here for longjmp() from vips__new_error_exit(). - */ - jpeg_destroy_decompress( &cinfo ); - + if( vips__jpeg_read_file( foreign->filename, load->real, + FALSE, jpeg->shrink, jpeg->fail ) ) return( -1 ); - } - jpeg_create_decompress( &cinfo ); - /* Make input. - */ - if( !(fp = vips__file_open_read( file->filename, NULL, FALSE )) ) - return( -1 ); - eman.fp = fp; - jpeg_stdio_src( &cinfo, fp ); - - /* Convert! - */ - result = vips_foreign_load_jpeg_read_header( jpeg, &cinfo, load->real ); - if( !result ) - result = vips_foreign_load_jpeg_read_image( jpeg, - &cinfo, load->real ); - - /* Close and tidy. - */ - fclose( fp ); - eman.fp = NULL; - jpeg_destroy_decompress( &cinfo ); - - if( eman.pub.num_warnings != 0 ) { - if( jpeg->fail ) { - vips_error( "VipsForeignLoadJpeg", - "%s", vips_error_buffer() ); - result = -1; - } - else { - vips_warn( "VipsForeignLoadJpeg", - _( "read gave %ld warnings" ), - eman.pub.num_warnings ); - vips_warn( "VipsForeignLoadJpeg", - "%s", vips_error_buffer() ); - } - } - - return( result ); + return( 0 ); } static const char *jpeg_suffs[] = { ".jpg", ".jpeg", ".jpe", NULL }; @@ -908,7 +198,7 @@ vips_foreign_load_jpeg_class_init( VipsForeignLoadJpegClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsForeignClass *file_class = (VipsForeignClass *) class; + VipsForeignClass *foreign_class = (VipsForeignClass *) class; VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class; gobject_class->set_property = vips_object_set_property; @@ -918,7 +208,7 @@ vips_foreign_load_jpeg_class_init( VipsForeignLoadJpegClass *class ) object_class->description = _( "load jpeg from file" ); object_class->build = vips_foreign_load_jpeg_build; - file_class->suffs = jpeg_suffs; + foreign_class->suffs = jpeg_suffs; load_class->is_a = vips_foreign_load_jpeg_is_a; load_class->header = vips_foreign_load_jpeg_header; diff --git a/libvips/foreign/jpegsave.c b/libvips/foreign/jpegsave.c index 4d2f874b..ac975ec9 100644 --- a/libvips/foreign/jpegsave.c +++ b/libvips/foreign/jpegsave.c @@ -95,7 +95,7 @@ G_DEFINE_TYPE( VipsForeignSaveJpeg, vips_foreign_save_jpeg, VIPS_TYPE_FOREIGN_SA static int vips_foreign_save_jpeg_build( VipsObject *object ) { - VipsForeign *file = (VipsForeign *) object; + VipsForeign *foreign = (VipsForeign *) object; VipsForeignSave *save = (VipsForeignSave *) object; VipsForeignSaveJpeg *jpeg = (VipsForeignSaveJpeg *) object; @@ -103,7 +103,7 @@ vips_foreign_save_jpeg_build( VipsObject *object ) build( object ) ) return( -1 ); - if( vips__jpeg_write_file( save->ready, file->filename, + if( vips__jpeg_write_file( save->ready, foreign->filename, jpeg->Q, jpeg->profile ) ) return( -1 ); @@ -126,7 +126,7 @@ vips_foreign_save_jpeg_class_init( VipsForeignSaveJpegClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsForeignClass *file_class = (VipsForeignClass *) class; + VipsForeignClass *foreign_class = (VipsForeignClass *) class; VipsForeignSaveClass *save_class = (VipsForeignSaveClass *) class; gobject_class->set_property = vips_object_set_property; @@ -136,7 +136,7 @@ vips_foreign_save_jpeg_class_init( VipsForeignSaveJpegClass *class ) object_class->description = _( "save image to jpeg file" ); object_class->build = vips_foreign_save_jpeg_build; - file_class->suffs = jpeg_suffs; + foreign_class->suffs = jpeg_suffs; save_class->saveable = VIPS_SAVEABLE_RGB_CMYK; save_class->format_table = bandfmt_jpeg; diff --git a/libvips/foreign/vipsload.c b/libvips/foreign/vipsload.c index 70b6056f..6cb34161 100644 --- a/libvips/foreign/vipsload.c +++ b/libvips/foreign/vipsload.c @@ -58,14 +58,14 @@ vips_foreign_load_vips_is_a( const char *filename ) static int vips_foreign_load_vips_get_flags( VipsForeignLoad *load ) { - VipsForeign *file = VIPS_FOREIGN( load ); + VipsForeign *foreign = VIPS_FOREIGN( load ); load->flags = VIPS_FOREIGN_PARTIAL; - if( vips__file_magic( file->filename ) == VIPS_MAGIC_INTEL ) { + if( vips__file_magic( foreign->filename ) == VIPS_MAGIC_INTEL ) { printf( "vips_foreign_load_vips_get_flags: " "%s is intel, setting bigendian\n", - file->filename ); + foreign->filename ); load->flags |= VIPS_FOREIGN_BIGENDIAN; } @@ -75,11 +75,11 @@ vips_foreign_load_vips_get_flags( VipsForeignLoad *load ) static int vips_foreign_load_vips_header( VipsForeignLoad *load ) { - VipsForeign *file = VIPS_FOREIGN( load ); + VipsForeign *foreign = VIPS_FOREIGN( load ); VipsImage *out; VipsImage *out2; - if( !(out2 = vips_image_new_from_file( file->filename )) ) + if( !(out2 = vips_image_new_from_file( foreign->filename )) ) return( -1 ); /* Remove the @out that's there now. @@ -99,13 +99,13 @@ static void vips_foreign_load_vips_class_init( VipsForeignLoadVipsClass *class ) { VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsForeignClass *file_class = (VipsForeignClass *) class; + VipsForeignClass *foreign_class = (VipsForeignClass *) class; VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class; object_class->nickname = "vipsload"; object_class->description = _( "load vips from file" ); - file_class->suffs = vips_suffs; + foreign_class->suffs = vips_suffs; load_class->is_a = vips_foreign_load_vips_is_a; load_class->get_flags = vips_foreign_load_vips_get_flags; diff --git a/libvips/foreign/vipssave.c b/libvips/foreign/vipssave.c index a629dd4c..49b25c27 100644 --- a/libvips/foreign/vipssave.c +++ b/libvips/foreign/vipssave.c @@ -55,14 +55,14 @@ G_DEFINE_TYPE( VipsForeignSaveVips, vips_foreign_save_vips, static int vips_foreign_save_vips_build( VipsObject *object ) { - VipsForeign *file = (VipsForeign *) object; + VipsForeign *foreign = (VipsForeign *) object; VipsForeignSave *save = (VipsForeignSave *) object; if( VIPS_OBJECT_CLASS( vips_foreign_save_vips_parent_class )-> build( object ) ) return( -1 ); - if( vips_image_write_to_file( save->ready, file->filename ) ) + if( vips_image_write_to_file( save->ready, foreign->filename ) ) return( -1 ); return( 0 ); @@ -95,14 +95,14 @@ static void vips_foreign_save_vips_class_init( VipsForeignSaveVipsClass *class ) { VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsForeignClass *file_class = (VipsForeignClass *) class; + VipsForeignClass *foreign_class = (VipsForeignClass *) class; VipsForeignSaveClass *save_class = (VipsForeignSaveClass *) class; object_class->nickname = "vipssave"; object_class->description = _( "save image to vips file" ); object_class->build = vips_foreign_save_vips_build; - file_class->suffs = vips_suffs; + foreign_class->suffs = vips_suffs; save_class->saveable = VIPS_SAVEABLE_ANY; save_class->format_table = vips_bandfmt_vips; diff --git a/libvips/include/vips/foreign.h b/libvips/include/vips/foreign.h index a2d12580..62f29d95 100644 --- a/libvips/include/vips/foreign.h +++ b/libvips/include/vips/foreign.h @@ -65,8 +65,8 @@ typedef struct _VipsForeignClass { /*< public >*/ - /* Loop over foreigns in this order, default 0. We need this because - * some foreigns can be read by several loaders (eg. tiff can be read + /* Loop over formats in this order, default 0. We need this because + * some formats can be read by several loaders (eg. tiff can be read * by the libMagick loader as well as by the tiff loader), and we want * to make sure the better loader comes first. */ @@ -81,10 +81,11 @@ typedef struct _VipsForeignClass { GType vips_foreign_get_type( void ); -/* Map over and find foreigns. This uses type introspection to loop over +/* Map over and find formats. This uses type introspection to loop over * subclasses of VipsForeign. */ -void *vips_foreign_map( const char *base, VipsSListMap2Fn fn, void *a, void *b ); +void *vips_foreign_map( const char *base, + VipsSListMap2Fn fn, void *a, void *b ); #define VIPS_TYPE_FOREIGN_LOAD (vips_foreign_load_get_type()) #define VIPS_FOREIGN_LOAD( obj ) \ diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 4ccaed2a..84c0ca58 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -602,6 +602,9 @@ vips_image_build( VipsObject *object ) VipsImage *t; VipsImage *t2; + printf( "vips_image_build: " + "byteswapping vips read\n" ); + /* Open the image in t, then byteswap to this * image. */ @@ -648,7 +651,7 @@ vips_image_build( VipsObject *object ) if( !(file_op = vips_foreign_find_save( filename )) ) return( -1 ); - if( strcmp( file_op, "VipsFileSaveVips" ) == 0 ) + if( strcmp( file_op, "VipsForeignSaveVips" ) == 0 ) image->dtype = VIPS_IMAGE_OPENOUT; else { image->dtype = VIPS_IMAGE_PARTIAL; From c906b4aa66cc961260ae5a70354ccb616ce064a8 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 29 Nov 2011 14:53:25 +0000 Subject: [PATCH 4/4] sync --- TODO | 89 ++++++++++++++++++++++++++++++++-- libvips/foreign/foreign.c | 2 +- libvips/include/vips/foreign.h | 16 +++--- 3 files changed, 94 insertions(+), 13 deletions(-) diff --git a/TODO b/TODO index 530f63fe..8fdc6171 100644 --- a/TODO +++ b/TODO @@ -1,14 +1,76 @@ -- test vips_foreign_load_vips_get_flags(), sense inverted? +- argh this is horrible + how about adding a property 'fileloader' ... define this and your object + will be tested by vips_foreign_find_load() + + or! put is_a etc. in VipsForeign but only set them for classes which support + it and leave NULL otherwise + + consider just properties ... at the moment we have: + + VipsForeign (filename) + VipsForeignLoad (disc, flags) + VipsForeignLoadJpeg (shrink, fail) + VipsForeignLoadVips + VipsForeignSave (in) + VipsForeignSaveJpeg (Q, profile) + VipsForeignSaveVips + + how about: + + VipsForeign + VipsForeignLoad (disc, flags) + VipsForeignLoadJpeg (shrink, fail) + VipsForeignLoadJpegBuffer (buffer) + VipsForeignLoadJpegFile (filename) + VipsForeignLoadVips (source-filename) + VipsForeignLoadTiff (source-filename, page) + VipsForeignSave (in) + VipsForeignSaveJpeg (Q, profile) + VipsForeignSaveJpegFile (filename) + VipsForeignSaveJpegBuffer (buffer) + VipsForeignSaveVips (dest-filename) + VipsForeignSaveTiff (dest-filename, pyramid, comp, etc.) + + so all we do is nmove the filename prop of the load/save subclasses, not too + bad + + +- we can make the interfaces we need much simpler if we use properties for all + data members ... eg. fetch "flags" property if we can + + put 'priority' in VipsForeignClass + + interfaces become + + interface load (header, load) + interface load-from-file (is_a) + interface load-from-buffer (buffer) + + interface save (ready, saveable, format_table) + interface save-to-file (filename, suffs) + interface save-to-buffer (buffer) + + classes are + + VipsForeign (priority) + VipsForeignLoad (disc, flags, out, real, get_flags, header, load) + VipsForeignLoadJpeg (shrink, fail) + VipsForeignLoadJpegFile (filename, is_a) + VipsForeignLoadJpegBuffer (buffer) + VipsForeignSave (in, ready, saveable, format_table) + VipsForeignSaveJpeg (Q, profile) + VipsForeignSaveJpegFile (filename, suffs) + VipsForeignSaveJpegBuffer (buffer) - at the moment we have: - VipsFile (filename, priority, suffs) - VipsFileLoad (disc, flags, out, real, is_a, get_flags, header, load) + VipsFile (filename) + VipsFileLoad (disc, flags) VipsFileLoadJpeg (shrink, fail) - VipsFileSave (in, ready, saveable, format_table) + VipsFileSave (in) VipsFileSaveJpeg (Q, profile) we want jpeg*_buffer to have everything jpeg* has, except filename and @@ -34,9 +96,28 @@ or have load-from-file as an interface? + interface load (priority, disc, flags, out, get_flags, header, load) + interface load-from-file (filename, is_a) + interface load-from-buffer (buffer) + + interface save (priority, in, ready, saveable, format_table) + interface save-to-file (filename, suffs) + interface save-to-buffer (buffer) + + then walk VipsForeign and test whether each class implements load-from-file + + can interfaces have data members? + + read up on gobject interfaces +- test vips_foreign_load_vips_get_flags(), sense inverted? + + we have various printf()s left in the byteswap codepath + + test this, if we can .. perhaps add a swap-magic flag to edvips? + - add classes for read and write jpeg buffers diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index b5061a47..ce6648fb 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -264,7 +264,7 @@ vips_foreign_class_init( VipsForeignClass *class ) object_class->print_class = vips_foreign_print_class; VIPS_ARG_STRING( class, "filename", 1, - _( "Foreignname" ), + _( "Filename" ), _( "Foreign filename" ), VIPS_ARGUMENT_REQUIRED_INPUT, G_STRUCT_OFFSET( VipsForeign, filename ), diff --git a/libvips/include/vips/foreign.h b/libvips/include/vips/foreign.h index 62f29d95..931ccd5c 100644 --- a/libvips/include/vips/foreign.h +++ b/libvips/include/vips/foreign.h @@ -35,6 +35,14 @@ extern "C" { #endif /*__cplusplus*/ +/* Image file load properties. + */ +typedef enum { + VIPS_FOREIGN_NONE = 0, /* No flags set */ + VIPS_FOREIGN_PARTIAL = 1, /* Lazy read OK (eg. tiled tiff) */ + VIPS_FOREIGN_BIGENDIAN = 2 /* Most-significant byte first */ +} VipsForeignFlags; + #define VIPS_TYPE_FOREIGN (vips_foreign_get_type()) #define VIPS_FOREIGN( obj ) \ (G_TYPE_CHECK_INSTANCE_CAST( (obj), \ @@ -102,14 +110,6 @@ void *vips_foreign_map( const char *base, (G_TYPE_INSTANCE_GET_CLASS( (obj), \ VIPS_TYPE_FOREIGN_LOAD, VipsForeignLoadClass )) -/* Image foreign properties. - */ -typedef enum { - VIPS_FOREIGN_NONE = 0, /* No flags set */ - VIPS_FOREIGN_PARTIAL = 1, /* Lazy read OK (eg. tiled tiff) */ - VIPS_FOREIGN_BIGENDIAN = 2 /* Most-significant byte first */ -} VipsForeignFlags; - typedef struct _VipsForeignLoad { VipsForeign parent_object; /*< public >*/