diff --git a/TODO b/TODO index 2dd3f4ce..7a560fa4 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,12 @@ -- image.c has far too many includes +- pre/post/close should be on VipsObject, not VipsImage + decls for im_local etc. are now in image.h, move them to object.h and the + code to object.c + + also see im_bits_of_fmt() + + decls for type_map etc. are now in object.h, move the code to object.c diff --git a/libvips/include/vips/callback.h b/libvips/include/vips/callback.h index 12bd53f2..dc05ffc7 100644 --- a/libvips/include/vips/callback.h +++ b/libvips/include/vips/callback.h @@ -34,9 +34,6 @@ extern "C" { #endif /*__cplusplus*/ -/* Also used for eg. im_local() and friends. - */ -typedef int (*im_callback_fn)( void *a, void *b ); int im_add_close_callback( IMAGE *im, im_callback_fn fn, void *a, void *b ); int im_add_preclose_callback( IMAGE *im, im_callback_fn fn, void *a, void *b ); diff --git a/libvips/include/vips/check.h b/libvips/include/vips/check.h index 49779ba1..d2530797 100644 --- a/libvips/include/vips/check.h +++ b/libvips/include/vips/check.h @@ -36,52 +36,52 @@ extern "C" { #endif /*__cplusplus*/ -int im_rwcheck( IMAGE *im ); -int im_iocheck( IMAGE *in, IMAGE *out ); -int im_incheck( IMAGE *im ); -int im_outcheck( IMAGE *im ); -int im_piocheck( IMAGE *in, IMAGE *out ); -int im_pincheck( IMAGE *im ); -int im_poutcheck( IMAGE *im ); +int im_rwcheck( VipsImage *im ); +int im_iocheck( VipsImage *in, VipsImage *out ); +int im_incheck( VipsImage *im ); +int im_outcheck( VipsImage *im ); +int im_piocheck( VipsImage *in, VipsImage *out ); +int im_pincheck( VipsImage *im ); +int im_poutcheck( VipsImage *im ); -int im_check_uncoded( const char *domain, IMAGE *im ); -int im_check_coding_known( const char *domain, IMAGE *im ); -int im_check_coding_labq( const char *domain, IMAGE *im ); -int im_check_coding_rad( const char *domain, IMAGE *im ); -int im_check_coding_noneorlabq( const char *domain, IMAGE *im ); -int im_check_coding_same( const char *domain, IMAGE *im1, IMAGE *im2 ); -int im_check_mono( const char *domain, IMAGE *im ); -int im_check_bands_1or3( const char *domain, IMAGE *in ); -int im_check_bands( const char *domain, IMAGE *im, int bands ); -int im_check_bands_1orn( const char *domain, IMAGE *im1, IMAGE *im2 ); -int im_check_bands_1orn_unary( const char *domain, IMAGE *im, int n ); -int im_check_bands_same( const char *domain, IMAGE *im1, IMAGE *im2 ); -int im_check_bandno( const char *domain, IMAGE *im, int bandno ); -int im_check_int( const char *domain, IMAGE *im ); -int im_check_uint( const char *domain, IMAGE *im ); -int im_check_uintorf( const char *domain, IMAGE *im ); -int im_check_noncomplex( const char *domain, IMAGE *im ); -int im_check_complex( const char *domain, IMAGE *im ); -int im_check_format( const char *domain, IMAGE *im, VipsBandFmt fmt ); -int im_check_u8or16( const char *domain, IMAGE *im ); -int im_check_8or16( const char *domain, IMAGE *im ); -int im_check_u8or16orf( const char *domain, IMAGE *im ); -int im_check_format_same( const char *domain, IMAGE *im1, IMAGE *im2 ); -int im_check_size_same( const char *domain, IMAGE *im1, IMAGE *im2 ); -int im_check_vector( const char *domain, int n, IMAGE *im ); -int im_check_hist( const char *domain, IMAGE *im ); +int im_check_uncoded( const char *domain, VipsImage *im ); +int im_check_coding_known( const char *domain, VipsImage *im ); +int im_check_coding_labq( const char *domain, VipsImage *im ); +int im_check_coding_rad( const char *domain, VipsImage *im ); +int im_check_coding_noneorlabq( const char *domain, VipsImage *im ); +int im_check_coding_same( const char *domain, VipsImage *im1, VipsImage *im2 ); +int im_check_mono( const char *domain, VipsImage *im ); +int im_check_bands_1or3( const char *domain, VipsImage *in ); +int im_check_bands( const char *domain, VipsImage *im, int bands ); +int im_check_bands_1orn( const char *domain, VipsImage *im1, VipsImage *im2 ); +int im_check_bands_1orn_unary( const char *domain, VipsImage *im, int n ); +int im_check_bands_same( const char *domain, VipsImage *im1, VipsImage *im2 ); +int im_check_bandno( const char *domain, VipsImage *im, int bandno ); +int im_check_int( const char *domain, VipsImage *im ); +int im_check_uint( const char *domain, VipsImage *im ); +int im_check_uintorf( const char *domain, VipsImage *im ); +int im_check_noncomplex( const char *domain, VipsImage *im ); +int im_check_complex( const char *domain, VipsImage *im ); +int im_check_format( const char *domain, VipsImage *im, VipsBandFormat fmt ); +int im_check_u8or16( const char *domain, VipsImage *im ); +int im_check_8or16( const char *domain, VipsImage *im ); +int im_check_u8or16orf( const char *domain, VipsImage *im ); +int im_check_format_same( const char *domain, VipsImage *im1, VipsImage *im2 ); +int im_check_size_same( const char *domain, VipsImage *im1, VipsImage *im2 ); +int im_check_vector( const char *domain, int n, VipsImage *im ); +int im_check_hist( const char *domain, VipsImage *im ); int im_check_imask( const char *domain, INTMASK *mask ); int im_check_dmask( const char *domain, DOUBLEMASK *mask ); -gboolean vips_bandfmt_isint( VipsBandFmt fmt ); -gboolean vips_bandfmt_isuint( VipsBandFmt fmt ); -gboolean vips_bandfmt_isfloat( VipsBandFmt fmt ); -gboolean vips_bandfmt_iscomplex( VipsBandFmt fmt ); +gboolean vips_bandfmt_isint( VipsBandFormat fmt ); +gboolean vips_bandfmt_isuint( VipsBandFormat fmt ); +gboolean vips_bandfmt_isfloat( VipsBandFormat fmt ); +gboolean vips_bandfmt_iscomplex( VipsBandFormat fmt ); -gboolean im_isfile( IMAGE *im ); -gboolean im_ispartial( IMAGE *im ); +gboolean im_isfile( VipsImage *im ); +gboolean im_ispartial( VipsImage *im ); -gboolean im_isMSBfirst( IMAGE *im ); +gboolean im_isMSBfirst( VipsImage *im ); #ifdef __cplusplus } diff --git a/libvips/include/vips/conversion.h b/libvips/include/vips/conversion.h index 0fbcaca1..f6b1f797 100644 --- a/libvips/include/vips/conversion.h +++ b/libvips/include/vips/conversion.h @@ -37,68 +37,70 @@ extern "C" { #endif /*__cplusplus*/ -DOUBLEMASK *im_vips2mask( IMAGE *in, const char *filename ); -int im_mask2vips( DOUBLEMASK *in, IMAGE *out ); +DOUBLEMASK *im_vips2mask( VipsImage *in, const char *filename ); +int im_mask2vips( DOUBLEMASK *in, VipsImage *out ); -int im_copy( IMAGE *in, IMAGE *out ); -int im_copy_set( IMAGE *in, IMAGE *out, - VipsType type, float xres, float yres, int xoffset, int yoffset ); -int im_copy_set_meta( IMAGE *in, IMAGE *out, const char *field, GValue *value ); -int im_copy_morph( IMAGE *in, IMAGE *out, - int bands, VipsBandFmt bandfmt, VipsCoding coding ); -int im_copy_swap( IMAGE *in, IMAGE *out ); -int im_copy_native( IMAGE *in, IMAGE *out, gboolean is_msb_first ); -int im_copy_file( IMAGE *in, IMAGE *out ); +int im_copy( VipsImage *in, VipsImage *out ); +int im_copy_set( VipsImage *in, VipsImage *out, + VipsInterpretation interpretation, + float xres, float yres, int xoffset, int yoffset ); +int im_copy_set_meta( VipsImage *in, VipsImage *out, + const char *field, GValue *value ); +int im_copy_morph( VipsImage *in, VipsImage *out, + int bands, VipsBandFormat format, VipsCoding coding ); +int im_copy_swap( VipsImage *in, VipsImage *out ); +int im_copy_native( VipsImage *in, VipsImage *out, gboolean is_msb_first ); +int im_copy_file( VipsImage *in, VipsImage *out ); -int im_clip2fmt( IMAGE *in, IMAGE *out, VipsBandFmt fmt ); -int im_scale( IMAGE *in, IMAGE *out ); -int im_msb( IMAGE *in, IMAGE *out ); -int im_msb_band( IMAGE *in, IMAGE *out, int band ); +int im_clip2fmt( VipsImage *in, VipsImage *out, VipsBandFormat fmt ); +int im_scale( VipsImage *in, VipsImage *out ); +int im_msb( VipsImage *in, VipsImage *out ); +int im_msb_band( VipsImage *in, VipsImage *out, int band ); -int im_c2amph( IMAGE *in, IMAGE *out ); -int im_c2rect( IMAGE *in, IMAGE *out ); -int im_ri2c( IMAGE *in1, IMAGE *in2, IMAGE *out ); -int im_c2imag( IMAGE *in, IMAGE *out ); -int im_c2real( IMAGE *in, IMAGE *out ); -int im_scaleps( IMAGE *in, IMAGE *out ); +int im_c2amph( VipsImage *in, VipsImage *out ); +int im_c2rect( VipsImage *in, VipsImage *out ); +int im_ri2c( VipsImage *in1, VipsImage *in2, VipsImage *out ); +int im_c2imag( VipsImage *in, VipsImage *out ); +int im_c2real( VipsImage *in, VipsImage *out ); +int im_scaleps( VipsImage *in, VipsImage *out ); -int im_falsecolour( IMAGE *in, IMAGE *out ); -int im_gaussnoise( IMAGE *out, int x, int y, double mean, double sigma ); +int im_falsecolour( VipsImage *in, VipsImage *out ); +int im_gaussnoise( VipsImage *out, int x, int y, double mean, double sigma ); -int im_black( IMAGE *out, int x, int y, int bands ); -int im_text( IMAGE *out, const char *text, const char *font, +int im_black( VipsImage *out, int x, int y, int bands ); +int im_text( VipsImage *out, const char *text, const char *font, int width, int alignment, int dpi ); -int im_extract_band( IMAGE *in, IMAGE *out, int band ); -int im_extract_bands( IMAGE *in, IMAGE *out, int band, int nbands ); -int im_extract_area( IMAGE *in, IMAGE *out, +int im_extract_band( VipsImage *in, VipsImage *out, int band ); +int im_extract_bands( VipsImage *in, VipsImage *out, int band, int nbands ); +int im_extract_area( VipsImage *in, VipsImage *out, int left, int top, int width, int height ); -int im_extract_areabands( IMAGE *in, IMAGE *out, +int im_extract_areabands( VipsImage *in, VipsImage *out, int left, int top, int width, int height, int band, int nbands ); -int im_embed( IMAGE *in, IMAGE *out, +int im_embed( VipsImage *in, VipsImage *out, int type, int x, int y, int width, int height ); -int im_bandjoin( IMAGE *in1, IMAGE *in2, IMAGE *out ); -int im_gbandjoin( IMAGE **in, IMAGE *out, int n ); -int im_insert( IMAGE *main, IMAGE *sub, IMAGE *out, int x, int y ); -int im_insert_noexpand( IMAGE *main, IMAGE *sub, IMAGE *out, int x, int y ); -int im_insertset( IMAGE *main, IMAGE *sub, IMAGE *out, int n, int *x, int *y ); -int im_lrjoin( IMAGE *left, IMAGE *right, IMAGE *out ); -int im_tbjoin( IMAGE *top, IMAGE *bottom, IMAGE *out ); -int im_replicate( IMAGE *in, IMAGE *out, int across, int down ); -int im_grid( IMAGE *in, IMAGE *out, int tile_height, int across, int down ); -int im_wrap( IMAGE *in, IMAGE *out, int x, int y ); +int im_bandjoin( VipsImage *in1, VipsImage *in2, VipsImage *out ); +int im_gbandjoin( VipsImage **in, VipsImage *out, int n ); +int im_insert( VipsImage *main, VipsImage *sub, VipsImage *out, int x, int y ); +int im_insert_noexpand( VipsImage *main, VipsImage *sub, VipsImage *out, int x, int y ); +int im_insertset( VipsImage *main, VipsImage *sub, VipsImage *out, int n, int *x, int *y ); +int im_lrjoin( VipsImage *left, VipsImage *right, VipsImage *out ); +int im_tbjoin( VipsImage *top, VipsImage *bottom, VipsImage *out ); +int im_replicate( VipsImage *in, VipsImage *out, int across, int down ); +int im_grid( VipsImage *in, VipsImage *out, int tile_height, int across, int down ); +int im_wrap( VipsImage *in, VipsImage *out, int x, int y ); -int im_fliphor( IMAGE *in, IMAGE *out ); -int im_flipver( IMAGE *in, IMAGE *out ); -int im_rot90( IMAGE *in, IMAGE *out ); -int im_rot180( IMAGE *in, IMAGE *out ); -int im_rot270( IMAGE *in, IMAGE *out ); +int im_fliphor( VipsImage *in, VipsImage *out ); +int im_flipver( VipsImage *in, VipsImage *out ); +int im_rot90( VipsImage *in, VipsImage *out ); +int im_rot180( VipsImage *in, VipsImage *out ); +int im_rot270( VipsImage *in, VipsImage *out ); -int im_subsample( IMAGE *in, IMAGE *out, int xshrink, int yshrink ); -int im_zoom( IMAGE *in, IMAGE *out, int xfac, int yfac ); +int im_subsample( VipsImage *in, VipsImage *out, int xshrink, int yshrink ); +int im_zoom( VipsImage *in, VipsImage *out, int xfac, int yfac ); -int im_system( IMAGE *im, const char *cmd, char **out ); -IMAGE *im_system_image( IMAGE *im, +int im_system( VipsImage *im, const char *cmd, char **out ); +VipsImage *im_system_image( VipsImage *im, const char *in_format, const char *out_format, const char *cmd_format, char **log ); diff --git a/libvips/include/vips/debug.h b/libvips/include/vips/debug.h index 0f425408..6d1e61da 100644 --- a/libvips/include/vips/debug.h +++ b/libvips/include/vips/debug.h @@ -66,31 +66,27 @@ extern "C" { G_STMT_START { ; } G_STMT_END #endif /*VIPS_DEBUG_GREEN*/ -/* All open image descriptors ... see im_init() and im_close(). - */ -extern GSList *im__open_images; - /* Print one line for each descriptor, complete dump for one descriptor. */ void im__print_one( int n ); void im__print_all( void ); const char *im_Type2char( VipsType type ); -const char *im_BandFmt2char( VipsBandFmt fmt ); +const char *im_BandFormat2char( VipsBandFormat fmt ); const char *im_Coding2char( VipsCoding coding ); const char *im_Compression2char( int n ); -const char *im_dtype2char( im_desc_type n ); +const char *im_dtype2char( VipsImageType n ); const char *im_dhint2char( VipsDemandStyle style ); int im_char2Type( const char *str ); -int im_char2BandFmt( const char *str ); +int im_char2BandFormat( const char *str ); int im_char2Coding( const char *str ); int im_char2Compression( const char *str ); -im_desc_type im_char2dtype( const char *str ); +VipsImageType im_char2dtype( const char *str ); im_demand_type im_char2dhint( const char *str ); -void im_printdesc( IMAGE *image ); -int im_image_sanity( IMAGE *im ); +void im_printdesc( VipsImage *image ); +int im_image_sanity( VipsImage *im ); void im_image_sanity_all( void ); #ifdef __cplusplus diff --git a/libvips/include/vips/image.h b/libvips/include/vips/image.h index 43413f09..19e3d3c9 100644 --- a/libvips/include/vips/image.h +++ b/libvips/include/vips/image.h @@ -44,6 +44,8 @@ extern "C" { #define VIPS_MAGIC_INTEL (0xb6a6f208U) #define VIPS_MAGIC_SPARC (0x08f2a6b6U) +/* Preferred demand type. + */ typedef enum { VIPS_DEMAND_STYLE_SMALLTILE, VIPS_DEMAND_STYLE_FATSTRIP, @@ -51,27 +53,41 @@ typedef enum { VIPS_DEMAND_STYLE_ANY } VipsDemandStyle; +/* Types of image descriptor we may have. The type field is advisory only: it + * does not imply that any fields in IMAGE have valid data. + */ +typedef enum { + VIPS_IMAGE_NONE, /* no type set */ + VIPS_IMAGE_SETBUF, /* malloced memory array */ + VIPS_IMAGE_SETBUF_FOREIGN, /* memory array, don't free on close */ + VIPS_IMAGE_OPENIN, /* input from fd with a window */ + VIPS_IMAGE_MMAPIN, /* memory mapped input file */ + VIPS_IMAGE_MMAPINRW, /* memory mapped read/write file */ + VIPS_IMAGE_OPENOUT, /* output to fd */ + VIPS_IMAGE_PARTIAL /* partial image */ +} VipsImageType; + /* The gaps in the numbering are historical and need maintaining. Allocate new * numbers from the end. */ typedef enum { - VIPS_TYPE_MULTIBAND = 0, - VIPS_TYPE_B_W = 1, - VIPS_TYPE_HISTOGRAM = 10, - VIPS_TYPE_FOURIER = 24, - VIPS_TYPE_XYZ = 12, - VIPS_TYPE_LAB = 13, - VIPS_TYPE_CMYK = 15, - VIPS_TYPE_LABQ = 16, - VIPS_TYPE_RGB = 17, - VIPS_TYPE_UCS = 18, - VIPS_TYPE_LCH = 19, - VIPS_TYPE_LABS = 21, - VIPS_TYPE_sRGB = 22, - VIPS_TYPE_YXY = 23, - VIPS_TYPE_RGB16 = 25, - VIPS_TYPE_GREY16 = 26 -} VipsType; + VIPS_INTERPRETATION_MULTIBAND = 0, + VIPS_INTERPRETATION_B_W = 1, + VIPS_INTERPRETATION_HISTOGRAM = 10, + VIPS_INTERPRETATION_FOURIER = 24, + VIPS_INTERPRETATION_XYZ = 12, + VIPS_INTERPRETATION_LAB = 13, + VIPS_INTERPRETATION_CMYK = 15, + VIPS_INTERPRETATION_LABQ = 16, + VIPS_INTERPRETATION_RGB = 17, + VIPS_INTERPRETATION_UCS = 18, + VIPS_INTERPRETATION_LCH = 19, + VIPS_INTERPRETATION_LABS = 21, + VIPS_INTERPRETATION_sRGB = 22, + VIPS_INTERPRETATION_YXY = 23, + VIPS_INTERPRETATION_RGB16 = 25, + VIPS_INTERPRETATION_GREY16 = 26 +} VipsInterpretation; typedef enum { VIPS_FORMAT_NOTSET = -1, @@ -86,7 +102,7 @@ typedef enum { VIPS_FORMAT_DOUBLE = 8, VIPS_FORMAT_DPCOMPLEX = 9, VIPS_FORMAT_LAST = 10 -} VipsFormat; +} VipsBandFormat; typedef enum { VIPS_CODING_NONE = 0, @@ -138,9 +154,9 @@ typedef struct _VipsImage { int Ysize; /* image height, in pixels */ int Bands; /* number of image bands */ - VipsFormat BandFmt; /* #VipsFormat describing the pixel format */ - VipsCoding Coding; /* #VipsCoding describing the pixel coding */ - VipsType Type; /* #VipsType hinting at pixel interpretation */ + VipsBandFormat BandFmt; /* pixel format */ + VipsCoding Coding; /* pixel coding */ + VipsInterpretation Type;/* pixel interpretation */ float Xres; /* horizontal pixels per millimetre */ float Yres; /* vertical pixels per millimetre */ @@ -241,11 +257,6 @@ typedef struct _VipsImage { */ gboolean hint_set; - /* The pre/post/close callbacks are all fire-once. - */ - gboolean preclose; - gboolean close; - gboolean postclose; } VipsImage; typedef struct _VipsImageClass { @@ -266,19 +277,6 @@ typedef struct _VipsImageClass { */ void (*posteval)( VipsImage *image ); - /* Just before image close, everything is still alive. - */ - void (*preclose)( VipsImage *image ); - - /* Image close, time to free stuff. - */ - void (*close)( VipsImage *image ); - - /* Post-close, everything is dead, except the VipsImage pointer. - * Useful for eg. deleting the file associated with a temp image. - */ - void (*postclose)( VipsImage *image ); - /* An image has been written to. * Used by eg. im_open("x.jpg", "w") to do the final write to jpeg. */ @@ -335,13 +333,13 @@ extern const size_t vips__sizeof_bandfmt[]; int vips_image_get_width( VipsImage *image ); int vips_image_get_height( VipsImage *image ); int vips_image_get_bands( VipsImage *image ); -VipsFormat vips_image_get_format( VipsImage *image ); +VipsBandFormat vips_image_get_format( VipsImage *image ); VipsCoding vips_image_get_coding( VipsImage *image ); -VipsType vips_image_get_type( VipsImage *image ); -VipsType vips_image_get_xres( VipsImage *image ); -VipsType vips_image_get_yres( VipsImage *image ); -VipsType vips_image_get_xoffset( VipsImage *image ); -VipsType vips_image_get_yoffset( VipsImage *image ); +VipsInterpretation vips_image_get_interpretation( VipsImage *image ); +double vips_image_get_xres( VipsImage *image ); +double vips_image_get_yres( VipsImage *image ); +int vips_image_get_xoffset( VipsImage *image ); +int vips_image_get_yoffset( VipsImage *image ); @@ -376,7 +374,8 @@ void vips_invalidate( VipsImage *im ); void vips_initdesc( VipsImage *image, int xsize, int ysize, int bands, int bandbits, - VipsFormat format, VipsCoding coding, VipsType type, + VipsBandFormat format, VipsCoding coding, + VipsInterpretation interpretation, float xres, float yres, int xo, int yo ); @@ -388,7 +387,22 @@ int vips_cp_desc_array( VipsImage *out, VipsImage *in[] ); VipsImage *vips_binfile( const char *name, int xsize, int ysize, int bands, int offset ); VipsImage *vips_image( void *buffer, - int xsize, int ysize, int bands, VipsFormat bandfmt ); + int xsize, int ysize, int bands, VipsBandFormat bandfmt ); + +typedef void *(*im_construct_fn)( void *, void *, void * ); + +/* Also used for im_add_close_callback() etc. + */ +typedef int (*im_callback_fn)( void *a, void *b ); + +void *im_local( VipsImage *im, + im_construct_fn cons, im_callback_fn dest, void *a, void *b, void *c ); +int im_local_array( VipsImage *im, void **out, int n, + im_construct_fn cons, im_callback_fn dest, void *a, void *b, void *c ); +char *im_strdup( VipsImage *im, const char *str ); +VipsImage *im__open_temp( const char *format ); + +int im_bits_of_fmt( VipsBandFormat fmt ); #ifdef __cplusplus } diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index c11d7200..35f1dae5 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -45,15 +45,15 @@ extern "C" { * their GValue implementation, see eg. MetaArea. */ typedef struct _Meta { - IMAGE *im; + VipsImage *im; char *field; /* strdup() of field name */ GValue value; /* copy of value */ } Meta; void im__meta_init_types( void ); -void im__meta_destroy( IMAGE *im ); -int im__meta_cp( IMAGE *, const IMAGE * ); +void im__meta_destroy( VipsImage *im ); +int im__meta_cp( VipsImage *, const VipsImage * ); /* Default tile geometry. */ @@ -75,20 +75,20 @@ extern int im__progress; */ extern char *im__disc_threshold; -typedef int (*im__fftproc_fn)( IMAGE *, IMAGE *, IMAGE * ); +typedef int (*im__fftproc_fn)( VipsImage *, VipsImage *, VipsImage * ); /* iofuncs */ int vips_open_input( VipsImage *image ); int vips_open_input_rw( VipsImage *image ); -int im_mapfile( IMAGE * ); -int im_mapfilerw( IMAGE * ); -int im_remapfilerw( IMAGE *image ); +int im_mapfile( VipsImage * ); +int im_mapfilerw( VipsImage * ); +int im_remapfilerw( VipsImage *image ); -IMAGE *im_open_header( const char * ); +VipsImage *im_open_header( const char * ); -int im_unmapfile( IMAGE * ); +int im_unmapfile( VipsImage * ); void im__read_4byte( int msb_first, unsigned char *to, unsigned char **from ); void im__read_2byte( int msb_first, unsigned char *to, unsigned char **from ); void im__write_4byte( unsigned char **to, unsigned char *from ); @@ -97,21 +97,21 @@ void im__write_2byte( unsigned char **to, unsigned char *from ); int im__ftruncate( int fd, gint64 pos ); int im__seek( int fd, gint64 pos ); int im__get_bytes( const char *filename, unsigned char buf[], int len ); -gint64 im__image_pixel_length( IMAGE *im ); +gint64 im__image_pixel_length( VipsImage *im ); int im__open_image_file( const char * ); void im__format_init( void ); void im__type_init( void ); -int im__read_header_bytes( IMAGE *im, unsigned char *from ); -int im__write_header_bytes( IMAGE *im, unsigned char *to ); -int im__has_extension_block( IMAGE *im ); -void *im__read_extension_block( IMAGE *im, int *size ); -int im__write_extension_block( IMAGE *im, void *buf, int size ); -int im__writehist( IMAGE *image ); -int im__start_eval( IMAGE *im ); -int im__handle_eval( IMAGE *im, int w, int h ); -int im__end_eval( IMAGE *im ); -int im__time_destroy( IMAGE *im ); +int im__read_header_bytes( VipsImage *im, unsigned char *from ); +int im__write_header_bytes( VipsImage *im, unsigned char *to ); +int im__has_extension_block( VipsImage *im ); +void *im__read_extension_block( VipsImage *im, int *size ); +int im__write_extension_block( VipsImage *im, void *buf, int size ); +int im__writehist( VipsImage *image ); +int im__start_eval( VipsImage *im ); +int im__handle_eval( VipsImage *im, int w, int h ); +int im__end_eval( VipsImage *im ); +int im__time_destroy( VipsImage *im ); void im__tiff_register( void ); void im__jpeg_register( void ); @@ -132,11 +132,11 @@ typedef enum { IM__ANY /* any number of bands (eg. TIFF) */ } im__saveable_t; -IMAGE *im__convert_saveable( IMAGE *in, +VipsImage *im__convert_saveable( VipsImage *in, im__saveable_t saveable, int format_table[10] ); -void im__link_break_all( IMAGE *im ); -void *im__link_map( IMAGE *im, VSListMap2Fn fn, void *a, void *b ); +void im__link_break_all( VipsImage *im ); +void *im__link_map( VipsImage *im, VSListMap2Fn fn, void *a, void *b ); GValue *im__gvalue_ref_string_new( const char *text ); void im__gslist_gvalue_free( GSList *list ); @@ -146,34 +146,34 @@ char *im__gslist_gvalue_get( const GSList *list ); void im__buffer_init( void ); -int im__bandup( const char *domain, IMAGE *in, IMAGE *out, int n ); -int im__bandalike_vec( const char *domain, IMAGE **in, IMAGE **out, int n ); +int im__bandup( const char *domain, VipsImage *in, VipsImage *out, int n ); +int im__bandalike_vec( const char *domain, VipsImage **in, VipsImage **out, int n ); int im__bandalike( const char *domain, - IMAGE *in1, IMAGE *in2, IMAGE *out1, IMAGE *out2 ); -int im__formatalike_vec( IMAGE **in, IMAGE **out, int n ); -int im__formatalike( IMAGE *in1, IMAGE *in2, IMAGE *out1, IMAGE *out2 ); + VipsImage *in1, VipsImage *in2, VipsImage *out1, VipsImage *out2 ); +int im__formatalike_vec( VipsImage **in, VipsImage **out, int n ); +int im__formatalike( VipsImage *in1, VipsImage *in2, VipsImage *out1, VipsImage *out2 ); int im__arith_binary( const char *domain, - IMAGE *in1, IMAGE *in2, IMAGE *out, + VipsImage *in1, VipsImage *in2, VipsImage *out, int format_table[10], im_wrapmany_fn fn, void *b ); int im__arith_binary_const( const char *domain, - IMAGE *in, IMAGE *out, - int n, double *c, VipsBandFmt vfmt, + VipsImage *in, VipsImage *out, + int n, double *c, VipsBandFormat vfmt, int format_table[10], im_wrapone_fn fn1, im_wrapone_fn fnn ); -int im__value( IMAGE *im, double *value ); +int im__value( VipsImage *im, double *value ); typedef int (*im__wrapscan_fn)( void *p, int n, void *seq, void *a, void *b ); -int im__wrapscan( IMAGE *in, +int im__wrapscan( VipsImage *in, im_start_fn start, im__wrapscan_fn scan, im_stop_fn stop, void *a, void *b ); int im__colour_difference( const char *domain, - IMAGE *in1, IMAGE *in2, IMAGE *out, + VipsImage *in1, VipsImage *in2, VipsImage *out, im_wrapmany_fn buffer_fn, void *a, void *b ); int im__colour_unary( const char *domain, - IMAGE *in, IMAGE *out, VipsType type, + VipsImage *in, VipsImage *out, VipsInterpretation interpretation, im_wrapone_fn buffer_fn, void *a, void *b ); -IMAGE **im__insert_base( const char *domain, - IMAGE *in1, IMAGE *in2, IMAGE *out ); +VipsImage **im__insert_base( const char *domain, + VipsImage *in1, VipsImage *in2, VipsImage *out ); /* Structure for holding the lookup tables for XYZ<=>rgb conversion. * Also holds the luminance to XYZ matrix and the inverse one. @@ -192,11 +192,11 @@ struct im_col_tab_disp { float ristep, gistep, bistep; }; -struct im_col_tab_disp *im_col_make_tables_RGB( IMAGE *im, +struct im_col_tab_disp *im_col_make_tables_RGB( VipsImage *im, struct im_col_display *d ); struct im_col_tab_disp *im_col_display_get_table( struct im_col_display *d ); -int im__test_kill( IMAGE *im ); +int im__test_kill( VipsImage *im ); void *im__mmap( int fd, int writeable, size_t length, gint64 offset ); int im__munmap( void *start, size_t length ); int im__write( int, const void *, size_t ); @@ -205,28 +205,28 @@ void im__change_suffix( const char *name, char *out, int mx, void im__print_all( void ); void im__print_one( int ); int im__trigger_callbacks( GSList *cblist ); -int im__close( IMAGE * ); -int im__handle_eval( IMAGE *im, int w, int h ); +int im__close( VipsImage * ); +int im__handle_eval( VipsImage *im, int w, int h ); int im__fft_sp( float *rvec, float *ivec, int logrows, int logcols ); -int im__fftproc( IMAGE *dummy, IMAGE *in, IMAGE *out, im__fftproc_fn fn ); -int im__find_lroverlap( IMAGE *ref_in, IMAGE *sec_in, IMAGE *out, +int im__fftproc( VipsImage *dummy, VipsImage *in, VipsImage *out, im__fftproc_fn fn ); +int im__find_lroverlap( VipsImage *ref_in, VipsImage *sec_in, VipsImage *out, int bandno_in, int xref, int yref, int xsec, int ysec, int halfcorrelation, int halfarea, int *dx0, int *dy0, double *scale1, double *angle1, double *dx1, double *dy1 ); -int im__find_tboverlap( IMAGE *ref_in, IMAGE *sec_in, IMAGE *out, +int im__find_tboverlap( VipsImage *ref_in, VipsImage *sec_in, VipsImage *out, int bandno_in, int xref, int yref, int xsec, int ysec, int halfcorrelation, int halfarea, int *dx0, int *dy0, double *scale1, double *angle1, double *dx1, double *dy1 ); -int im__find_best_contrast( IMAGE *image, +int im__find_best_contrast( VipsImage *image, int xpos, int ypos, int xsize, int ysize, int xarray[], int yarray[], int cont[], int nbest, int hcorsize ); -int im__balance( IMAGE *ref, IMAGE *sec, IMAGE *out, - IMAGE **ref_out, IMAGE **sec_out, int dx, int dy, int balancetype ); +int im__balance( VipsImage *ref, VipsImage *sec, VipsImage *out, + VipsImage **ref_out, VipsImage **sec_out, int dx, int dy, int balancetype ); void imb_Lab2LCh( float *, float *, int ); void imb_LCh2Lab( float *, float *, int ); @@ -267,17 +267,17 @@ int im_invmat( double **, int ); int *im_offsets45( int size ); int *im_offsets90( int size ); -int im_conv_f_raw( IMAGE *in, IMAGE *out, DOUBLEMASK *mask ); -int im_convsep_f_raw( IMAGE *in, IMAGE *out, DOUBLEMASK *mask ); +int im_conv_f_raw( VipsImage *in, VipsImage *out, DOUBLEMASK *mask ); +int im_convsep_f_raw( VipsImage *in, VipsImage *out, DOUBLEMASK *mask ); -int im__fmaskcir( IMAGE *out, VipsMaskType flag, va_list ap ); +int im__fmaskcir( VipsImage *out, VipsMaskType flag, va_list ap ); /* inplace */ -PEL *im__vector_to_ink( const char *domain, IMAGE *im, int n, double *vec ); -IMAGE *im__inplace_base( const char *domain, - IMAGE *main, IMAGE *sub, IMAGE *out ); +PEL *im__vector_to_ink( const char *domain, VipsImage *im, int n, double *vec ); +VipsImage *im__inplace_base( const char *domain, + VipsImage *main, VipsImage *sub, VipsImage *out ); /* Register base vips interpolators, called during startup. */ diff --git a/libvips/include/vips/memory.h b/libvips/include/vips/memory.h index 7ea6c44d..0a76850c 100644 --- a/libvips/include/vips/memory.h +++ b/libvips/include/vips/memory.h @@ -29,15 +29,47 @@ */ -#ifndef IM_MEMORY_H -#define IM_MEMORY_H +#ifndef VIPS_MEMORY_H +#define VIPS_MEMORY_H #ifdef __cplusplus extern "C" { #endif /*__cplusplus*/ -#define IM_NEW( IM, T ) ((T *) im_malloc( (IM), sizeof( T ))) -#define IM_ARRAY( IM, N, T ) ((T *) im_malloc( (IM), (N) * sizeof( T ))) +#define VIPS_FREEF( F, S ) \ +G_STMT_START { \ + if( S ) { \ + (void) F( (S) ); \ + (S) = 0; \ + } \ +} G_STMT_END + +/* Can't just use VIPS_FREEF(), we want the extra cast to void on the argument + * to im_free() to make sure we can work for "const char *" variables. + */ +#define VIPS_FREE( S ) \ +G_STMT_START { \ + if( S ) { \ + (void) im_free( (void *) (S) ); \ + (S) = 0; \ + } \ +} G_STMT_END + +#define VIPS_SETSTR( S, V ) \ +G_STMT_START { \ + const char *sst = (V); \ + \ + if( (S) != sst ) { \ + if( !(S) || !sst || strcmp( (S), sst ) != 0 ) { \ + IM_FREE( S ); \ + if( sst ) \ + (S) = im_strdup( NULL, sst ); \ + } \ + } \ +} G_STMT_END + +#define VIPS_NEW( IM, T ) ((T *) im_malloc( (IM), sizeof( T ))) +#define VIPS_ARRAY( IM, N, T ) ((T *) im_malloc( (IM), (N) * sizeof( T ))) void *im_malloc( VipsImage *im, size_t size ); int im_free( void *s ); diff --git a/libvips/include/vips/object.h b/libvips/include/vips/object.h index e5c63d39..9272a2b4 100644 --- a/libvips/include/vips/object.h +++ b/libvips/include/vips/object.h @@ -75,7 +75,7 @@ typedef enum { * disconnect the signal. */ VIPS_ARGUMENT_OUTPUT = 16 -} VipsArgument; +} VipsArgumentFlags; /* Useful flag combinations. User-visible ones are: @@ -125,7 +125,7 @@ typedef struct _VipsArgumentClass { */ VipsObjectClass *object_class; - VipsArgument flags; + VipsArgumentFlags flags; guint offset; /* G_STRUCT_OFFSET of member in object */ } VipsArgumentClass; @@ -188,6 +188,12 @@ struct _VipsObject { */ char *nickname; char *description; + + /* The pre/post/close callbacks are all fire-once. + */ + gboolean preclose; + gboolean close; + gboolean postclose; }; struct _VipsObjectClass { @@ -206,6 +212,19 @@ struct _VipsObjectClass { */ void (*print)( VipsObject *, VipsBuf * ); + /* Just before close, everything is still alive. + */ + void (*preclose)( VipsObject * ); + + /* Close, time to free stuff. + */ + void (*close)( VipsObject * ); + + /* Post-close, everything is dead, except the VipsObject pointer. + * Useful for eg. deleting the file associated with a temp image. + */ + void (*postclose)( VipsObject * ); + /* Class nickname, eg. "VipsInterpolateBicubic" has "bicubic" as a * nickname. Not internationalised. */ @@ -236,7 +255,7 @@ void vips_object_print( VipsObject *object ); GType vips_object_get_type( void ); void vips_object_class_install_argument( VipsObjectClass *, - GParamSpec *pspec, VipsArgument flags, guint offset ); + GParamSpec *pspec, VipsArgumentFlags flags, guint offset ); typedef void *(*VipsObjectSetArguments)( VipsObject *, void *, void * ); VipsObject *vips_object_new( GType type, @@ -247,6 +266,15 @@ void vips_object_to_string( VipsObject *object, VipsBuf *buf ); void *vips_object_map( VSListMap2Fn fn, void *a, void *b ); +typedef void *(*VipsTypeMap)( GType, void * ); +typedef void *(*VipsTypeMap2)( GType, void *, void * ); +typedef void *(*VipsClassMap)( VipsObjectClass *, void * ); +void *vips_type_map( GType base, VipsTypeMap2 fn, void *a, void *b ); +void *vips_type_map_concrete_all( GType base, VipsTypeMap fn, void *a ); +void *vips_class_map_concrete_all( GType base, VipsClassMap fn, void *a ); +VipsObjectClass *vips_class_find( const char *basename, const char *nickname ); +GType vips_type_find( const char *basename, const char *nickname ); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/include/vips/private.h b/libvips/include/vips/private.h index 6ae68295..741189c2 100644 --- a/libvips/include/vips/private.h +++ b/libvips/include/vips/private.h @@ -57,20 +57,6 @@ extern "C" { typedef unsigned char PEL; /* useful datum */ -/* Types of image descriptor we may have. The type field is advisory only: it - * does not imply that any fields in IMAGE have valid data. - */ -typedef enum { - VIPS_IMAGE_NONE, /* no type set */ - VIPS_IMAGE_SETBUF, /* malloced memory array */ - VIPS_IMAGE_SETBUF_FOREIGN, /* memory array, don't free on close */ - VIPS_IMAGE_OPENIN, /* input from fd with a window */ - VIPS_IMAGE_MMAPIN, /* memory mapped input file */ - VIPS_IMAGE_MMAPINRW, /* memory mapped read/write file */ - VIPS_IMAGE_OPENOUT, /* output to fd */ - VIPS_IMAGE_PARTIAL /* partial image */ -} VipsImageType; - /* What we track for each mmap window. Have a list of these on an openin * IMAGE. */ diff --git a/libvips/include/vips/util.h b/libvips/include/vips/util.h index 5727e3eb..7894a72b 100644 --- a/libvips/include/vips/util.h +++ b/libvips/include/vips/util.h @@ -63,38 +63,6 @@ G_STMT_START { \ (B) = t; \ } G_STMT_END -#define IM_FREEF( F, S ) \ -G_STMT_START { \ - if( S ) { \ - (void) F( (S) ); \ - (S) = 0; \ - } \ -} G_STMT_END - -/* Can't just use IM_FREEF(), we want the extra cast to void on the argument - * to im_free() to make sure we can work for "const char *" variables. - */ -#define IM_FREE( S ) \ -G_STMT_START { \ - if( S ) { \ - (void) im_free( (void *) (S) ); \ - (S) = 0; \ - } \ -} G_STMT_END - -#define IM_SETSTR( S, V ) \ -G_STMT_START { \ - const char *sst = (V); \ - \ - if( (S) != sst ) { \ - if( !(S) || !sst || strcmp( (S), sst ) != 0 ) { \ - IM_FREE( S ); \ - if( sst ) \ - (S) = im_strdup( NULL, sst ); \ - } \ - } \ -} G_STMT_END - /* Duff's device. Do OPERation N times in a 16-way unrolled loop. */ #define IM_UNROLL( N, OPER ) \ @@ -187,13 +155,6 @@ G_STMT_START { \ #define VIPS_ENUM_NICK( ENUM, VALUE ) \ (g_enum_get_value( g_type_class_ref( ENUM ), VALUE )->value_nick) -typedef void *(*im_construct_fn)( void *, void *, void * ); - -void *im_local( VipsImage *im, - im_construct_fn cons, im_callback_fn dest, void *a, void *b, void *c ); -int im_local_array( VipsImage *im, void **out, int n, - im_construct_fn cons, im_callback_fn dest, void *a, void *b, void *c ); - /* strtok replacement. */ char *im__break_token( char *str, char *brk ); @@ -218,18 +179,8 @@ void *im_map_equal( void *a, void *b ); void *im_hash_table_map( GHashTable *hash, VSListMap2Fn fn, void *a, void *b ); -typedef void *(*VipsTypeMap)( GType, void * ); -typedef void *(*VipsTypeMap2)( GType, void *, void * ); -typedef void *(*VipsClassMap)( VipsObjectClass *, void * ); -void *vips_type_map( GType base, VipsTypeMap2 fn, void *a, void *b ); -void *vips_type_map_concrete_all( GType base, VipsTypeMap fn, void *a ); -void *vips_class_map_concrete_all( GType base, VipsClassMap fn, void *a ); -VipsObjectClass *vips_class_find( const char *basename, const char *nickname ); -GType vips_type_find( const char *basename, const char *nickname ); - char *im_strncpy( char *dest, const char *src, int n ); char *im_strrstr( const char *haystack, const char *needle ); -char *im_strdup( IMAGE *im, const char *str ); gboolean im_ispostfix( const char *a, const char *b ); gboolean im_isprefix( const char *a, const char *b ); int im_vsnprintf( char *str, size_t size, const char *format, va_list ap ); @@ -280,9 +231,6 @@ int im_isvips( const char *filename ); int im_amiMSBfirst( void ); char *im__temp_name( const char *format ); -IMAGE *im__open_temp( const char *format ); - -int im_bits_of_fmt( VipsBandFmt fmt ); #ifdef __cplusplus } diff --git a/libvips/include/vips/vips.h b/libvips/include/vips/vips.h index e1c777be..25e99bed 100644 --- a/libvips/include/vips/vips.h +++ b/libvips/include/vips/vips.h @@ -95,6 +95,7 @@ extern "C" { #endif /*SWIG*/ #include +#include #include #include @@ -108,7 +109,6 @@ extern "C" { #include #include #include -#include #include #include #include diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 334bc7c9..f4a57771 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -42,29 +42,9 @@ #include #include #include -#include - -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_FILE_H -#include -#endif /*HAVE_SYS_FILE_H*/ -#include #ifdef HAVE_UNISTD_H #include #endif /*HAVE_UNISTD_H*/ -#ifdef HAVE_IO_H -#include -#endif /*HAVE_IO_H*/ -#include -#include - -#ifdef OS_WIN32 -#include -#endif /*OS_WIN32*/ #include #include @@ -321,9 +301,6 @@ enum { /* Our signals. */ enum { - SIG_PRECLOSE, - SIG_CLOSE, - SIG_POSTCLOSE, SIG_PREEVAL, SIG_EVAL, SIG_POSTEVAL, @@ -344,57 +321,6 @@ static guint vips_image_signals[SIG_LAST] = { 0 }; G_DEFINE_TYPE( VipsImage, vips_image, VIPS_TYPE_OBJECT ); -static int -vips_image_preclose( VipsImage *image ) -{ - VipsImageClass *image_class = VIPS_IMAGE_GET_CLASS( image ); - - if( !image->preclose ) { - image->preclose = TRUE; - -#ifdef DEBUG - printf( "vips_image_preclose: " ); - vips_object_print( object ); -#endif /*DEBUG*/ - - g_signal_emit( image, vips_image_signals[SIG_PRECLOSE], 0 ); - } -} - -static int -vips_image_close( VipsImage *image ) -{ - VipsImageClass *image_class = VIPS_IMAGE_GET_CLASS( image ); - - if( !image->close ) { - image->close = TRUE; - -#ifdef DEBUG - printf( "vips_image_close: " ); - vips_object_print( object ); -#endif /*DEBUG*/ - - g_signal_emit( image, vips_image_signals[SIG_CLOSE], 0 ); - } -} - -static int -vips_image_postclose( VipsImage *image ) -{ - VipsImageClass *image_class = VIPS_IMAGE_GET_CLASS( image ); - - if( !image->postclose ) { - image->postclose = TRUE; - -#ifdef DEBUG - printf( "vips_image_postclose: " ); - vips_object_print( object ); -#endif /*DEBUG*/ - - g_signal_emit( image, vips_image_signals[SIG_POSTCLOSE], 0 ); - } -} - static void vips_image_finalize( GObject *gobject ) { @@ -427,7 +353,7 @@ vips_image_finalize( GObject *gobject ) /* MMAP file. */ #ifdef DEBUG_IO - printf( "im__close: unmapping file ..\n" ); + printf( "vips_image_finalize: unmapping file ..\n" ); #endif /*DEBUG_IO*/ im__munmap( image->baseaddr, image->length ); @@ -444,16 +370,16 @@ vips_image_finalize( GObject *gobject ) */ if( image->fd != -1 ) { #ifdef DEBUG_IO - printf( "im__close: closing output file ..\n" ); + printf( "vips_image_finalize: closing output file ..\n" ); #endif /*DEBUG_IO*/ - if( image->dtype == IM_OPENOUT ) + if( image->dtype == VIPS_IMAGE_OPENOUT ) (void) im__writehist( image ); - if( close( im->fd ) == -1 ) - im_error( "im_close", + if( close( image->fd ) == -1 ) + im_error( "vips_image_finalize", _( "unable to close fd for %s" ), image->filename ); - im->fd = -1; + image->fd = -1; } /* Any image data? @@ -461,19 +387,17 @@ vips_image_finalize( GObject *gobject ) if( image->data ) { /* Buffer image. Only free stuff we know we allocated. */ - if( image->dtype == IM_SETBUF ) { + if( image->dtype == VIPS_IMAGE_SETBUF ) { #ifdef DEBUG_IO - printf( "im__close: freeing buffer ..\n" ); + printf( "vips_image_finalize: freeing buffer ..\n" ); #endif /*DEBUG_IO*/ im_free( image->data ); - image->dtype = IM_NONE; + image->dtype = VIPS_IMAGE_NONE; } image->data = NULL; } - vips_image_close( image ); - VIPS_FREE( image->filename ); VIPS_FREE( image->mode ); @@ -484,8 +408,6 @@ vips_image_finalize( GObject *gobject ) im__meta_destroy( image ); im__time_destroy( image ); - vips_image_postclose( image ); - G_OBJECT_CLASS( vips_image_parent_class )->finalize( gobject ); } @@ -501,54 +423,22 @@ vips_image_dispose( GObject *gobject ) } static void -vips_image_destroy( VipsObject *object ) -{ -#ifdef VIPS_DEBUG - VIPS_DEBUG_MSG( "vips_image_destroy: " ); - vips_object_print( VIPS_OBJECT( gobject ) ); -#endif /*VIPS_DEBUG*/ - - vips_image_preclose( image ); - - VIPS_OBJECT_CLASS( vips_image_parent_class )->destroy( object ); -} - -static void -vips_image_info( VipsObject *object, VipsBuf *buf ) -{ - VipsImage *image = VIPS_IMAGE( object ); - - vips_buf_appendf( buf, "image->dtype = %d\n", image->dtype ); - vips_buf_appendf( buf, "image->demand = %s\n", - VIPS_ENUM_STRING( VIPS_TYPE_DEMAND, image->demand ) ); - vips_buf_appendf( buf, "image->magic = 0x%x\n", image->magic ); - vips_buf_appendf( buf, "image->fd = %d\n", image->fd ); - vips_buf_appendf( buf, "image->baseaddr = %p\n", image->baseaddr ); - vips_buf_appendf( buf, "image->length = %#" - G_GSIZE_MODIFIER "x\n", image->length ); - vips_buf_appendf( buf, "image->data = %p\n", image->data ); - vips_buf_appendf( buf, "image->sizeof_header = %d\n", - image->sizeof_header ); - - VIPS_OBJECT_CLASS( parent_class )->info( object, buf ); -} - -static void -vips_image_generate_caption( VipsObject *object, VipsBuf *buf ) +vips_image_print( VipsObject *object, VipsBuf *buf ) { VipsImage *image = VIPS_IMAGE( object ); vips_buf_appendf( buf, ngettext( "%dx%d %s, %d band, %s", - "%dx%d %s, %d bands, %s", image->bands ), + "%dx%d %s, %d bands, %s", + vips_image_get_bands( image ) ), vips_image_get_width( image ), vips_image_get_height( image ), VIPS_ENUM_NICK( VIPS_TYPE_FORMAT, vips_image_get_format( image ) ), vips_image_get_bands( image ), - VIPS_ENUM_NICK( VIPS_TYPE_TYPE, - vips_image_get_type( image ) ) ); + VIPS_ENUM_NICK( VIPS_TYPE_INTERPRETATION, + vips_image_get_interpretation( image ) ) ); } static gboolean @@ -761,7 +651,7 @@ vips_open_lazy( VipsImage *out, * to memory, sadly, so we can't suggest ANY. */ if( format->header( out->filename, out ) || - im_demand_hint( out, IM_THINSTRIP, NULL ) ) + im_demand_hint( out, VIPS_DEMAND_STYLE_THINSTRIP, NULL ) ) return( -1 ); /* Then 'start' creates the real image and 'gen' paints 'out' with @@ -980,7 +870,7 @@ vips_image_build( VipsObject *object ) case 't': image->dtype = VIPS_IMAGE_TYPE_SETBUF; - image->demand = VIPS_DEMAND_ANY; + image->dhint = VIPS_DEMAND_ANY; break; case 'p': @@ -1023,9 +913,7 @@ vips_image_class_init( VipsImageClass *class ) gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; - vobject_class->destroy = vips_image_destroy; - vobject_class->info = vips_image_info; - vobject_class->generate_caption = vips_image_generate_caption; + vobject_class->print = vips_image_print; vobject_class->copy_attributes = vips_image_copy_attributes; vobject_class->build = vips_image_build; @@ -1101,31 +989,10 @@ vips_image_class_init( VipsImageClass *class ) g_object_class_install_property( gobject_class, PROP_DEMAND, pspec ); vips_object_class_install_argument( vobject_class, pspec, VIPS_ARGUMENT_NONE, - G_STRUCT_OFFSET( VipsImage, demand ) ); + G_STRUCT_OFFSET( VipsImage, dhint ) ); /* Create signals. */ - vips_image_signals[SIG_PRECLOSE] = g_signal_new( "preclose", - G_TYPE_FROM_CLASS( class ), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET( VipsImageClass, preclose ), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0 ); - vips_image_signals[SIG_CLOSE] = g_signal_new( "close", - G_TYPE_FROM_CLASS( class ), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET( VipsImageClass, close ), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0 ); - vips_image_signals[SIG_POSTCLOSE] = g_signal_new( "postclose", - G_TYPE_FROM_CLASS( class ), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET( VipsImageClass, postclose ), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0 ); vips_image_signals[SIG_PREEVAL] = g_signal_new( "preeval", G_TYPE_FROM_CLASS( class ), @@ -1167,7 +1034,7 @@ vips_image_init( VipsImage *image ) /* Default to native order. */ - image->magic = im_amiMSBfirst() ? IM_MAGIC_SPARC : IM_MAGIC_INTEL; + image->magic = im_amiMSBfirst() ? VIPS_MAGIC_SPARC : VIPS_MAGIC_INTEL; image->fd = -1; /* since 0 is stdout */ image->sizeof_header = VIPS_SIZEOF_HEADER; diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index 5bfc4395..ab20676f 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -56,12 +56,68 @@ enum { PROP_LAST }; +/* Our signals. + */ +enum { + SIG_PRECLOSE, + SIG_CLOSE, + SIG_POSTCLOSE, + SIG_LAST +}; + /* Table of all objects, handy for debugging. */ static GHashTable *vips_object_all = NULL; +static guint vips_object_signals[SIG_LAST] = { 0 }; + G_DEFINE_ABSTRACT_TYPE( VipsObject, vips_object, G_TYPE_OBJECT ); +static int +vips_object_preclose( VipsObject *object ) +{ + if( !object->preclose ) { + object->preclose = TRUE; + +#ifdef DEBUG + printf( "vips_object_preclose: " ); + vips_object_print( object ); +#endif /*DEBUG*/ + + g_signal_emit( object, vips_object_signals[SIG_PRECLOSE], 0 ); + } +} + +static int +vips_object_close( VipsObject *object ) +{ + if( !object->close ) { + object->close = TRUE; + +#ifdef DEBUG + printf( "vips_object_close: " ); + vips_object_print( object ); +#endif /*DEBUG*/ + + g_signal_emit( object, vips_object_signals[SIG_CLOSE], 0 ); + } +} + +static int +vips_object_postclose( VipsObject *object ) +{ + if( !object->postclose ) { + object->postclose = TRUE; + +#ifdef DEBUG + printf( "vips_object_postclose: " ); + vips_object_print( object ); +#endif /*DEBUG*/ + + g_signal_emit( object, vips_object_signals[SIG_POSTCLOSE], 0 ); + } +} + int vips_object_build( VipsObject *object ) { @@ -335,6 +391,13 @@ vips_object_dispose( GObject *gobject ) vips_object_print( object ); #endif /*DEBUG*/ + /* Our subclasses should have already called this. Run it again, just + * in case. + */ + if( !object->preclose ) + printf( "vips_object_dispose: no vips_object_preclose()\n" ); + vips_object_preclose( object ); + /* Clear all our arguments: they may be holding refs we should drop. */ vips_argument_map( object, vips_object_dispose_argument, NULL, NULL ); @@ -352,10 +415,14 @@ vips_object_finalize( GObject *gobject ) vips_object_print( object ); #endif /*DEBUG*/ + vips_object_close( object ); + g_hash_table_remove( vips_object_all, object ); IM_FREEF( vips_argument_table_destroy, object->argument_table ); G_OBJECT_CLASS( vips_object_parent_class )->finalize( gobject ); + + vips_object_postclose( object ); } static void @@ -762,6 +829,28 @@ vips_object_class_init( VipsObjectClass *object_class ) VIPS_ARGUMENT_SET_ONCE, G_STRUCT_OFFSET( VipsObject, description ) ); + vips_object_signals[SIG_PRECLOSE] = g_signal_new( "preclose", + G_TYPE_FROM_CLASS( class ), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET( VipsObjectClass, preclose ), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0 ); + vips_object_signals[SIG_CLOSE] = g_signal_new( "close", + G_TYPE_FROM_CLASS( class ), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET( VipsObjectClass, close ), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0 ); + vips_object_signals[SIG_POSTCLOSE] = g_signal_new( "postclose", + G_TYPE_FROM_CLASS( class ), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET( VipsObjectClass, postclose ), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0 ); + } static void