Merge remote-tracking branch 'origin/master' into colour
This commit is contained in:
commit
982e0ea9eb
|
@ -7,6 +7,14 @@
|
||||||
|
|
||||||
19/4/12 started 7.28.6
|
19/4/12 started 7.28.6
|
||||||
- better resolution unit handling in deprecated im_vips2tiff()
|
- better resolution unit handling in deprecated im_vips2tiff()
|
||||||
|
- use TIFF_CFLAGS output from pkg-config (thanks Jay)
|
||||||
|
- much faster vips_argument_map()
|
||||||
|
- make jpeg pyramids work with tiff4
|
||||||
|
- tiff loader always offers THINSTRIP (thanks Diuming)
|
||||||
|
- add "nocache" operation flag, set for sequential load (thanks Diuming)
|
||||||
|
- fix a crash in the tiff reader for huge values of RowsPerStrip (thanks
|
||||||
|
Nicolas)
|
||||||
|
- remove use of G_DEFINE_BOXED_TYPE() to help compat (thanks Jake)
|
||||||
|
|
||||||
19/4/12 started 7.28.5
|
19/4/12 started 7.28.5
|
||||||
- ifthenelse blend mode was broken
|
- ifthenelse blend mode was broken
|
||||||
|
|
|
@ -664,7 +664,7 @@ fi
|
||||||
# Gather all up for VIPS_CFLAGS, VIPS_INCLUDES, VIPS_LIBS and VIPS_CXX_LIBS
|
# Gather all up for VIPS_CFLAGS, VIPS_INCLUDES, VIPS_LIBS and VIPS_CXX_LIBS
|
||||||
# sort includes to get longer, more specific dirs first
|
# sort includes to get longer, more specific dirs first
|
||||||
# helps, for example, selecting graphicsmagick over imagemagick
|
# helps, for example, selecting graphicsmagick over imagemagick
|
||||||
VIPS_CFLAGS=`for i in $VIPS_CFLAGS $GTHREAD_CFLAGS $REQUIRED_CFLAGS $PANGOFT2_CFLAGS $FFTW_CFLAGS $MAGICK_CFLAGS $PNG_CFLAGS $EXIF_CFLAGS $MATIO_CFLAGS $CFITSIO_CFLAGS $OPENEXR_CFLAGS $OPENSLIDE_CFLAGS $ORC_CFLAGS
|
VIPS_CFLAGS=`for i in $VIPS_CFLAGS $GTHREAD_CFLAGS $REQUIRED_CFLAGS $PANGOFT2_CFLAGS $FFTW_CFLAGS $MAGICK_CFLAGS $PNG_CFLAGS $EXIF_CFLAGS $MATIO_CFLAGS $CFITSIO_CFLAGS $OPENEXR_CFLAGS $OPENSLIDE_CFLAGS $ORC_CFLAGS $TIFF_CFLAGS
|
||||||
do
|
do
|
||||||
echo $i
|
echo $i
|
||||||
done | sort -ru`
|
done | sort -ru`
|
||||||
|
|
|
@ -698,6 +698,10 @@ vips_foreign_load_temp( VipsForeignLoad *load )
|
||||||
printf( "vips_foreign_load_temp: partial sequential temp\n" );
|
printf( "vips_foreign_load_temp: partial sequential temp\n" );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
|
/* You can't reuse sequential operations.
|
||||||
|
*/
|
||||||
|
vips_operation_set_nocache( VIPS_OPERATION( load ), TRUE );
|
||||||
|
|
||||||
return( vips_image_new() );
|
return( vips_image_new() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -927,6 +931,8 @@ vips_foreign_load_init( VipsForeignLoad *load )
|
||||||
load->disc = TRUE;
|
load->disc = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make a sequential cache for a file reader.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
vips_foreign_tilecache( VipsImage *in, VipsImage **out, int strip_height )
|
vips_foreign_tilecache( VipsImage *in, VipsImage **out, int strip_height )
|
||||||
{
|
{
|
||||||
|
@ -2153,19 +2159,10 @@ vips_fitssave( VipsImage *in, const char *filename, ... )
|
||||||
*
|
*
|
||||||
* Optional arguments:
|
* Optional arguments:
|
||||||
*
|
*
|
||||||
* @sequential: sequential read only
|
|
||||||
*
|
|
||||||
* Read a PNG file into a VIPS image. It can read all png images, including 8-
|
* Read a PNG file into a VIPS image. It can read all png images, including 8-
|
||||||
* and 16-bit images, 1 and 3 channel, with and without an alpha channel.
|
* and 16-bit images, 1 and 3 channel, with and without an alpha channel.
|
||||||
*
|
*
|
||||||
* Setting @sequential to %TRUE means you promise to only demand tiles from
|
* Any ICC profile is read and attached to the VIPS image.
|
||||||
* this image top-top-bottom, ie. to read sequentially. This means the png
|
|
||||||
* loader can read directly from the image without having to generate a
|
|
||||||
* random-access intermediate. This can save a lot of time and memory for
|
|
||||||
* large images, but limits the sorts of operation you can perform. It's
|
|
||||||
* useful for things like generating thumbnails.
|
|
||||||
*
|
|
||||||
* There is no support for embedded ICC profiles.
|
|
||||||
*
|
*
|
||||||
* See also: vips_image_new_from_file().
|
* See also: vips_image_new_from_file().
|
||||||
*
|
*
|
||||||
|
@ -2204,7 +2201,9 @@ vips_pngload( const char *filename, VipsImage **out, ... )
|
||||||
* than an interlaced PNG can be up to 7 times slower to write than a
|
* than an interlaced PNG can be up to 7 times slower to write than a
|
||||||
* non-interlaced image.
|
* non-interlaced image.
|
||||||
*
|
*
|
||||||
* There is no support for attaching ICC profiles to PNG images.
|
* If the VIPS header
|
||||||
|
* contains an ICC profile named VIPS_META_ICC_NAME ("icc-profile-data"), the
|
||||||
|
* profile from the VIPS header will be attached.
|
||||||
*
|
*
|
||||||
* The image is automatically converted to RGB, RGBA, Monochrome or Mono +
|
* The image is automatically converted to RGB, RGBA, Monochrome or Mono +
|
||||||
* alpha before saving. Images with more than one byte per band element are
|
* alpha before saving. Images with more than one byte per band element are
|
||||||
|
|
|
@ -128,6 +128,13 @@
|
||||||
* 18/2/12
|
* 18/2/12
|
||||||
* - switch to sequential read
|
* - switch to sequential read
|
||||||
* - remove the lock ... tilecache does this for us
|
* - remove the lock ... tilecache does this for us
|
||||||
|
* 3/6/12
|
||||||
|
* - always offer THINSTRIP ... later stages can ask for something more
|
||||||
|
* relaxed if they wish
|
||||||
|
* 7/6/12
|
||||||
|
* - clip rows_per_strip down to image height to avoid overflows for huge
|
||||||
|
* values (thanks Nicolas)
|
||||||
|
* - better error msg for not PLANARCONFIG_CONTIG images
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -250,29 +257,6 @@ tfexists( TIFF *tif, ttag_t tag )
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test a uint16 field. Field must be defined and equal to the value.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
tfequals( TIFF *tif, ttag_t tag, uint16 val )
|
|
||||||
{
|
|
||||||
uint16 fld;
|
|
||||||
|
|
||||||
if( !TIFFGetFieldDefaulted( tif, tag, &fld ) ) {
|
|
||||||
vips_error( "tiff2vips",
|
|
||||||
_( "required field %d missing" ), tag );
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
if( fld != val ) {
|
|
||||||
vips_error( "tiff2vips", _( "required field %d=%d, not %d" ),
|
|
||||||
tag, fld, val );
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* All ok.
|
|
||||||
*/
|
|
||||||
return( 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get a uint32 field.
|
/* Get a uint32 field.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
|
@ -304,9 +288,26 @@ tfget16( TIFF *tif, ttag_t tag, int *out )
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All ok.
|
|
||||||
*/
|
|
||||||
*out = fld;
|
*out = fld;
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test a uint16 field. Field must be defined and equal to the value.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
tfequals( TIFF *tif, ttag_t tag, uint16 val )
|
||||||
|
{
|
||||||
|
int v;
|
||||||
|
|
||||||
|
if( !tfget16( tif, tag, &v ) )
|
||||||
|
return( 0 );
|
||||||
|
if( v != val ) {
|
||||||
|
vips_error( "tiff2vips",
|
||||||
|
_( "required field %d = %d, not %d" ), tag, v, val );
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
return( 1 );
|
return( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -897,10 +898,16 @@ parse_header( ReadTiff *rtiff, VipsImage *out )
|
||||||
|
|
||||||
/* Ban separate planes, too annoying.
|
/* Ban separate planes, too annoying.
|
||||||
*/
|
*/
|
||||||
if( tfexists( rtiff->tiff, TIFFTAG_PLANARCONFIG ) &&
|
if( tfexists( rtiff->tiff, TIFFTAG_PLANARCONFIG ) ) {
|
||||||
!tfequals( rtiff->tiff,
|
int v;
|
||||||
TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG ) )
|
|
||||||
|
tfget16( rtiff->tiff, TIFFTAG_PLANARCONFIG, &v );
|
||||||
|
if( v != PLANARCONFIG_CONTIG ) {
|
||||||
|
vips_error( "tiff2vips",
|
||||||
|
"%s", _( "not a PLANARCONFIG_CONTIG image" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Always need dimensions.
|
/* Always need dimensions.
|
||||||
*/
|
*/
|
||||||
|
@ -1090,6 +1097,12 @@ parse_header( ReadTiff *rtiff, VipsImage *out )
|
||||||
(VipsCallbackFn) vips_free, data_copy, data_length );
|
(VipsCallbackFn) vips_free, data_copy, data_length );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Offer the most restrictive style. This can be changed downstream if
|
||||||
|
* necessary.
|
||||||
|
*/
|
||||||
|
vips_demand_hint( out,
|
||||||
|
VIPS_DEMAND_STYLE_THINSTRIP, NULL );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1258,15 +1271,18 @@ read_tilewise( ReadTiff *rtiff, VipsImage *out )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
/* Process and save as VIPS.
|
/* Process and save as VIPS.
|
||||||
|
*
|
||||||
|
* Even though this is a tiled reader, we hint thinstrip since with
|
||||||
|
* the cache we are quite happy serving that if anything downstream
|
||||||
|
* would like it.
|
||||||
*/
|
*/
|
||||||
vips_demand_hint( raw,
|
vips_demand_hint( raw,
|
||||||
VIPS_DEMAND_STYLE_SMALLTILE, NULL );
|
VIPS_DEMAND_STYLE_THINSTRIP, NULL );
|
||||||
if( vips_image_generate( raw,
|
if( vips_image_generate( raw,
|
||||||
tiff_seq_start, tiff_fill_region, tiff_seq_stop,
|
tiff_seq_start, tiff_fill_region, tiff_seq_stop,
|
||||||
rtiff, NULL ) )
|
rtiff, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
|
|
||||||
/* Copy to out, adding a cache. Enough tiles for two complete rows.
|
/* Copy to out, adding a cache. Enough tiles for two complete rows.
|
||||||
*/
|
*/
|
||||||
if( vips_tilecache( raw, &t,
|
if( vips_tilecache( raw, &t,
|
||||||
|
@ -1335,8 +1351,8 @@ tiff2vips_stripwise_generate( VipsRegion *or,
|
||||||
/* If necessary, unpack to destination.
|
/* If necessary, unpack to destination.
|
||||||
*/
|
*/
|
||||||
if( !rtiff->memcpy ) {
|
if( !rtiff->memcpy ) {
|
||||||
int height = VIPS_MIN( rtiff->rows_per_strip,
|
int height = VIPS_MIN( VIPS_MIN( rtiff->rows_per_strip,
|
||||||
or->im->Ysize - (r->top + y) );
|
or->im->Ysize - (r->top + y) ), r->height );
|
||||||
int z;
|
int z;
|
||||||
|
|
||||||
for( z = 0; z < height; z++ ) {
|
for( z = 0; z < height; z++ ) {
|
||||||
|
@ -1386,6 +1402,11 @@ read_stripwise( ReadTiff *rtiff, VipsImage *out )
|
||||||
rtiff->strip_size = TIFFStripSize( rtiff->tiff );
|
rtiff->strip_size = TIFFStripSize( rtiff->tiff );
|
||||||
rtiff->number_of_strips = TIFFNumberOfStrips( rtiff->tiff );
|
rtiff->number_of_strips = TIFFNumberOfStrips( rtiff->tiff );
|
||||||
|
|
||||||
|
/* rows_per_strip can be 2**32-1, meaning the whole image. Clip this
|
||||||
|
* down to ysize to avoid confusing vips.
|
||||||
|
*/
|
||||||
|
rtiff->rows_per_strip = VIPS_MIN( rtiff->rows_per_strip, t[0]->Ysize );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "read_stripwise: rows_per_strip = %u\n",
|
printf( "read_stripwise: rows_per_strip = %u\n",
|
||||||
rtiff->rows_per_strip );
|
rtiff->rows_per_strip );
|
||||||
|
|
|
@ -128,6 +128,9 @@
|
||||||
* VipsForeign class
|
* VipsForeign class
|
||||||
* 21/3/12
|
* 21/3/12
|
||||||
* - bump max layer buffer up
|
* - bump max layer buffer up
|
||||||
|
* 2/6/12
|
||||||
|
* - copy jpeg pyramid in gather in RGB mode ... tiff4 doesn't do ycbcr
|
||||||
|
* mode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -906,7 +909,8 @@ shrink_region( VipsRegion *from, VipsRect *area,
|
||||||
/* Write a tile from a layer.
|
/* Write a tile from a layer.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
save_tile( TiffWrite *tw, TIFF *tif, VipsPel *tbuf, VipsRegion *reg, VipsRect *area )
|
save_tile( TiffWrite *tw,
|
||||||
|
TIFF *tif, VipsPel *tbuf, VipsRegion *reg, VipsRect *area )
|
||||||
{
|
{
|
||||||
/* Have to repack pixels.
|
/* Have to repack pixels.
|
||||||
*/
|
*/
|
||||||
|
@ -1342,9 +1346,21 @@ tiff_copy( TiffWrite *tw, TIFF *out, TIFF *in )
|
||||||
/* TIFFTAG_JPEGQUALITY is a pesudo-tag, so we can't copy it.
|
/* TIFFTAG_JPEGQUALITY is a pesudo-tag, so we can't copy it.
|
||||||
* Set explicitly from TiffWrite.
|
* Set explicitly from TiffWrite.
|
||||||
*/
|
*/
|
||||||
if( tw->compression == COMPRESSION_JPEG )
|
if( tw->compression == COMPRESSION_JPEG ) {
|
||||||
TIFFSetField( out, TIFFTAG_JPEGQUALITY, tw->jpqual );
|
TIFFSetField( out, TIFFTAG_JPEGQUALITY, tw->jpqual );
|
||||||
|
|
||||||
|
/* Enable rgb->ycbcr conversion in the jpeg write. See also
|
||||||
|
* the photometric selection below.
|
||||||
|
*/
|
||||||
|
TIFFSetField( out, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB );
|
||||||
|
|
||||||
|
/* And we want ycbcr expanded to rgb on read. Otherwise
|
||||||
|
* TIFFTileSize() will give us the size of a chrominance
|
||||||
|
* subsampled tile.
|
||||||
|
*/
|
||||||
|
TIFFSetField( in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB );
|
||||||
|
}
|
||||||
|
|
||||||
/* We can't copy profiles :( Set again from TiffWrite.
|
/* We can't copy profiles :( Set again from TiffWrite.
|
||||||
*/
|
*/
|
||||||
if( embed_profile( tw, out ) )
|
if( embed_profile( tw, out ) )
|
||||||
|
@ -1359,7 +1375,7 @@ tiff_copy( TiffWrite *tw, TIFF *out, TIFF *in )
|
||||||
* here to save compression/decompression, but sadly it seems
|
* here to save compression/decompression, but sadly it seems
|
||||||
* not to work :-( investigate at some point.
|
* not to work :-( investigate at some point.
|
||||||
*/
|
*/
|
||||||
len = TIFFReadEncodedTile( in, tile, buf, (tsize_t) -1 );
|
len = TIFFReadEncodedTile( in, tile, buf, -1 );
|
||||||
if( len < 0 ||
|
if( len < 0 ||
|
||||||
TIFFWriteEncodedTile( out, tile, buf, len ) < 0 ) {
|
TIFFWriteEncodedTile( out, tile, buf, len ) < 0 ) {
|
||||||
vips_free( buf );
|
vips_free( buf );
|
||||||
|
@ -1527,7 +1543,8 @@ vips__tiff_write( VipsImage *in, const char *filename,
|
||||||
|
|
||||||
/* Gather layers together into final pyramid file.
|
/* Gather layers together into final pyramid file.
|
||||||
*/
|
*/
|
||||||
if( tw->pyramid && gather_pyramid( tw ) ) {
|
if( tw->pyramid &&
|
||||||
|
gather_pyramid( tw ) ) {
|
||||||
free_tiff_write( tw );
|
free_tiff_write( tw );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -328,15 +328,8 @@ int vips_object_get_argument_priority( VipsObject *object, const char *name );
|
||||||
VipsArgumentInstance *ARG_INSTANCE = \
|
VipsArgumentInstance *ARG_INSTANCE = \
|
||||||
vips__argument_get_instance( argument_class, \
|
vips__argument_get_instance( argument_class, \
|
||||||
VIPS_OBJECT( OBJECT ) ); \
|
VIPS_OBJECT( OBJECT ) ); \
|
||||||
\
|
|
||||||
/* We have many props on the arg table ... filter out the \
|
|
||||||
* ones for this class. \
|
|
||||||
*/ \
|
|
||||||
if( g_object_class_find_property( \
|
|
||||||
G_OBJECT_CLASS( object_class ), \
|
|
||||||
g_param_spec_get_name( PSPEC ) ) == PSPEC ) {
|
|
||||||
|
|
||||||
#define VIPS_ARGUMENT_FOR_ALL_END } } }
|
#define VIPS_ARGUMENT_FOR_ALL_END } }
|
||||||
|
|
||||||
/* And some macros to collect args from a va list.
|
/* And some macros to collect args from a va list.
|
||||||
*/
|
*/
|
||||||
|
@ -494,13 +487,22 @@ struct _VipsObjectClass {
|
||||||
*/
|
*/
|
||||||
const char *description;
|
const char *description;
|
||||||
|
|
||||||
/* Table of arguments for this class and any derived classes. Order
|
/* Hash from pspec to VipsArgumentClass.
|
||||||
* is important, so keep a traverse list too. We can't rely on the
|
*
|
||||||
* ordering given by g_object_class_list_properties() since it comes
|
* This records the VipsArgumentClass for every pspec used in
|
||||||
* from a hash :-(
|
* VipsObject and any subclass (ie. everywhere), so it's huge. Don't
|
||||||
|
* loop over this hash! Fine for lookups though.
|
||||||
*/
|
*/
|
||||||
VipsArgumentTable *argument_table;
|
VipsArgumentTable *argument_table;
|
||||||
|
|
||||||
|
/* A sorted (by priority) list of the VipsArgumentClass for this class
|
||||||
|
* and any superclasses. This is small and specific to this class.
|
||||||
|
*
|
||||||
|
* Use the stored GType to work out when to restart the list for a
|
||||||
|
* subclass.
|
||||||
|
*/
|
||||||
GSList *argument_table_traverse;
|
GSList *argument_table_traverse;
|
||||||
|
GType argument_table_traverse_gtype;
|
||||||
};
|
};
|
||||||
|
|
||||||
gboolean vips_value_is_null( GParamSpec *psoec, const GValue *value );
|
gboolean vips_value_is_null( GParamSpec *psoec, const GValue *value );
|
||||||
|
|
|
@ -66,6 +66,12 @@ typedef struct _VipsOperation {
|
||||||
guint hash;
|
guint hash;
|
||||||
gboolean found_hash;
|
gboolean found_hash;
|
||||||
|
|
||||||
|
/* Set this before the end of _build() to stop this operation from
|
||||||
|
* being cached. Some things, like sequential read from a TIFF file,
|
||||||
|
* can't be reused.
|
||||||
|
*/
|
||||||
|
gboolean nocache;
|
||||||
|
|
||||||
} VipsOperation;
|
} VipsOperation;
|
||||||
|
|
||||||
typedef struct _VipsOperationClass {
|
typedef struct _VipsOperationClass {
|
||||||
|
@ -89,6 +95,7 @@ void vips_call_options( GOptionGroup *group, VipsOperation *operation );
|
||||||
int vips_call_argv( VipsOperation *operation, int argc, char **argv );
|
int vips_call_argv( VipsOperation *operation, int argc, char **argv );
|
||||||
|
|
||||||
void vips_cache_drop_all( void );
|
void vips_cache_drop_all( void );
|
||||||
|
void vips_operation_set_nocache( VipsOperation *operation, gboolean nocache );
|
||||||
int vips_cache_operation_buildp( VipsOperation **operation );
|
int vips_cache_operation_buildp( VipsOperation **operation );
|
||||||
VipsOperation *vips_cache_operation_build( VipsOperation *operation );
|
VipsOperation *vips_cache_operation_build( VipsOperation *operation );
|
||||||
void vips_cache_set_max( int max );
|
void vips_cache_set_max( int max );
|
||||||
|
|
|
@ -621,7 +621,7 @@ vips_cache_operation_buildp( VipsOperation **operation )
|
||||||
|
|
||||||
#ifdef VIPS_DEBUG
|
#ifdef VIPS_DEBUG
|
||||||
printf( "vips_cache_operation_build: " );
|
printf( "vips_cache_operation_build: " );
|
||||||
vips_object_print_summary_stdout( VIPS_OBJECT( *operation ) );
|
vips_object_print_dump( VIPS_OBJECT( *operation ) );
|
||||||
#endif /*VIPS_DEBUG*/
|
#endif /*VIPS_DEBUG*/
|
||||||
|
|
||||||
vips_cache_init();
|
vips_cache_init();
|
||||||
|
@ -643,6 +643,10 @@ vips_cache_operation_buildp( VipsOperation **operation )
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if( vips__cache_trace ) {
|
if( vips__cache_trace ) {
|
||||||
|
if( (*operation)->nocache )
|
||||||
|
printf( "vips cache: uncacheable %p\n ",
|
||||||
|
*operation );
|
||||||
|
else
|
||||||
printf( "vips cache: miss %p\n ", *operation );
|
printf( "vips cache: miss %p\n ", *operation );
|
||||||
vips_object_print_summary( VIPS_OBJECT( *operation ) );
|
vips_object_print_summary( VIPS_OBJECT( *operation ) );
|
||||||
}
|
}
|
||||||
|
@ -650,8 +654,11 @@ vips_cache_operation_buildp( VipsOperation **operation )
|
||||||
if( vips_object_build( VIPS_OBJECT( *operation ) ) )
|
if( vips_object_build( VIPS_OBJECT( *operation ) ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
|
if( !(*operation)->nocache ) {
|
||||||
vips_cache_ref( *operation );
|
vips_cache_ref( *operation );
|
||||||
g_hash_table_insert( vips_cache_table, *operation, *operation );
|
g_hash_table_insert( vips_cache_table,
|
||||||
|
*operation, *operation );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
|
|
|
@ -349,6 +349,9 @@ void *
|
||||||
vips_argument_map( VipsObject *object,
|
vips_argument_map( VipsObject *object,
|
||||||
VipsArgumentMapFn fn, void *a, void *b )
|
VipsArgumentMapFn fn, void *a, void *b )
|
||||||
{
|
{
|
||||||
|
VipsObjectClass *object_class = VIPS_OBJECT_GET_CLASS( object );
|
||||||
|
GSList *p;
|
||||||
|
|
||||||
/* Make sure we can't go during the loop. This can happen if eg. we
|
/* Make sure we can't go during the loop. This can happen if eg. we
|
||||||
* flush an arg that refs us.
|
* flush an arg that refs us.
|
||||||
*/
|
*/
|
||||||
|
@ -358,6 +361,8 @@ vips_argument_map( VipsObject *object,
|
||||||
pspec, argument_class, argument_instance ) {
|
pspec, argument_class, argument_instance ) {
|
||||||
void *result;
|
void *result;
|
||||||
|
|
||||||
|
/* argument_instance should not be NULL.
|
||||||
|
*/
|
||||||
g_assert( argument_instance );
|
g_assert( argument_instance );
|
||||||
|
|
||||||
if( (result = fn( object, pspec,
|
if( (result = fn( object, pspec,
|
||||||
|
@ -365,7 +370,7 @@ vips_argument_map( VipsObject *object,
|
||||||
g_object_unref( object );
|
g_object_unref( object );
|
||||||
return( result );
|
return( result );
|
||||||
}
|
}
|
||||||
} VIPS_ARGUMENT_FOR_ALL_END
|
}
|
||||||
|
|
||||||
g_object_unref( object );
|
g_object_unref( object );
|
||||||
|
|
||||||
|
@ -389,19 +394,12 @@ vips_argument_class_map( VipsObjectClass *object_class,
|
||||||
VipsArgument *argument = (VipsArgument *) arg_class;
|
VipsArgument *argument = (VipsArgument *) arg_class;
|
||||||
GParamSpec *pspec = argument->pspec;
|
GParamSpec *pspec = argument->pspec;
|
||||||
|
|
||||||
/* We have many props on the arg table ... filter out the
|
|
||||||
* ones for this class.
|
|
||||||
*/
|
|
||||||
if( g_object_class_find_property(
|
|
||||||
G_OBJECT_CLASS( object_class ),
|
|
||||||
g_param_spec_get_name( pspec ) ) == pspec ) {
|
|
||||||
void *result;
|
void *result;
|
||||||
|
|
||||||
if( (result =
|
if( (result =
|
||||||
fn( object_class, pspec, arg_class, a, b )) )
|
fn( object_class, pspec, arg_class, a, b )) )
|
||||||
return( result );
|
return( result );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
@ -749,15 +747,11 @@ vips_object_dispose( GObject *gobject )
|
||||||
/* Our subclasses should have already called this. Run it again, just
|
/* Our subclasses should have already called this. Run it again, just
|
||||||
* in case.
|
* in case.
|
||||||
*/
|
*/
|
||||||
if( !object->preclose ) {
|
#ifdef DEBUG
|
||||||
#ifdef VIPS_DEBUG
|
if( !object->preclose )
|
||||||
printf( "vips_object_dispose: no vips_object_preclose() " );
|
printf( "vips_object_dispose: pre-close missing!\n" );
|
||||||
vips_object_print_name( VIPS_OBJECT( gobject ) );
|
#endif /*DEBUG*/
|
||||||
printf( "\n" );
|
|
||||||
#endif /*VIPS_DEBUG*/
|
|
||||||
|
|
||||||
vips_object_preclose( object );
|
vips_object_preclose( object );
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear all our arguments: they may be holding resources we should
|
/* Clear all our arguments: they may be holding resources we should
|
||||||
* drop.
|
* drop.
|
||||||
|
@ -1377,7 +1371,8 @@ vips_object_class_install_argument( VipsObjectClass *object_class,
|
||||||
VipsArgumentClass *argument_class = g_new( VipsArgumentClass, 1 );
|
VipsArgumentClass *argument_class = g_new( VipsArgumentClass, 1 );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "vips_object_class_install_argument: %s %s\n",
|
printf( "vips_object_class_install_argument: %p %s %s\n",
|
||||||
|
object_class,
|
||||||
g_type_name( G_TYPE_FROM_CLASS( object_class ) ),
|
g_type_name( G_TYPE_FROM_CLASS( object_class ) ),
|
||||||
g_param_spec_get_name( pspec ) );
|
g_param_spec_get_name( pspec ) );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
@ -1401,10 +1396,46 @@ vips_object_class_install_argument( VipsObjectClass *object_class,
|
||||||
|
|
||||||
vips_argument_table_replace( object_class->argument_table,
|
vips_argument_table_replace( object_class->argument_table,
|
||||||
(VipsArgument *) argument_class );
|
(VipsArgument *) argument_class );
|
||||||
|
|
||||||
|
/* If this is the first argument for a new subclass, we need to clone
|
||||||
|
* the traverse list we inherit.
|
||||||
|
*/
|
||||||
|
if( object_class->argument_table_traverse_gtype !=
|
||||||
|
G_TYPE_FROM_CLASS( object_class ) ) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "vips_object_class_install_argument: "
|
||||||
|
"cloning traverse\n" );
|
||||||
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
|
object_class->argument_table_traverse =
|
||||||
|
g_slist_copy( object_class->argument_table_traverse );
|
||||||
|
object_class->argument_table_traverse_gtype =
|
||||||
|
G_TYPE_FROM_CLASS( object_class );
|
||||||
|
}
|
||||||
|
|
||||||
object_class->argument_table_traverse = g_slist_prepend(
|
object_class->argument_table_traverse = g_slist_prepend(
|
||||||
object_class->argument_table_traverse, argument_class );
|
object_class->argument_table_traverse, argument_class );
|
||||||
object_class->argument_table_traverse = g_slist_sort(
|
object_class->argument_table_traverse = g_slist_sort(
|
||||||
object_class->argument_table_traverse, traverse_sort );
|
object_class->argument_table_traverse, traverse_sort );
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
{
|
||||||
|
GSList *p;
|
||||||
|
|
||||||
|
printf( "%d items on traverse %p\n",
|
||||||
|
g_slist_length( object_class->argument_table_traverse ),
|
||||||
|
&object_class->argument_table_traverse );
|
||||||
|
for( p = object_class->argument_table_traverse; p; p = p->next ) {
|
||||||
|
VipsArgumentClass *argument_class =
|
||||||
|
(VipsArgumentClass *) p->data;
|
||||||
|
|
||||||
|
printf( "\t%p %s\n",
|
||||||
|
argument_class,
|
||||||
|
g_param_spec_get_name(
|
||||||
|
((VipsArgument *) argument_class)->pspec ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /*DEBUG*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set a named arg from a string.
|
/* Set a named arg from a string.
|
||||||
|
|
|
@ -949,3 +949,23 @@ vips_call_argv( VipsOperation *operation, int argc, char **argv )
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_operation_set_nocache:
|
||||||
|
* @operation: operation to set
|
||||||
|
* @nocache: TRUE means don't cache this operation
|
||||||
|
*
|
||||||
|
* Set this before the end of _build() to stop this operation being cached.
|
||||||
|
* Some operations, like sequential read from a TIFF file, for example, cannot
|
||||||
|
* be reused.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vips_operation_set_nocache( VipsOperation *operation, gboolean nocache )
|
||||||
|
{
|
||||||
|
#ifdef VIPS_DEBUG
|
||||||
|
printf( "vips_operation_set_nocache: " );
|
||||||
|
vips_object_print_name( VIPS_OBJECT( operation ) );
|
||||||
|
printf( " %d\n", nocache );
|
||||||
|
#endif /*VIPS_DEBUG*/
|
||||||
|
|
||||||
|
operation->nocache = nocache;
|
||||||
|
}
|
||||||
|
|
|
@ -121,6 +121,19 @@ void vips__g_mutex_lock( GMutex *d ) {}
|
||||||
void vips__g_mutex_unlock( GMutex *d ) {}
|
void vips__g_mutex_unlock( GMutex *d ) {}
|
||||||
#endif /*!HAVE_THREADS*/
|
#endif /*!HAVE_THREADS*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_concurrency_set:
|
||||||
|
* @concurrency: number of threads to run
|
||||||
|
*
|
||||||
|
* Sets the number of worker threads that vips should use when running a
|
||||||
|
* #VipsThreadPool.
|
||||||
|
*
|
||||||
|
* The special value 0 means "default". In this case, the number of threads is
|
||||||
|
* set by the environmnt variable IM_CONCURRENCY, or if that is not set, the
|
||||||
|
* number of threads availble on the hist machine.
|
||||||
|
*
|
||||||
|
* See also: vips_concurrency_get().
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
vips_concurrency_set( int concurrency )
|
vips_concurrency_set( int concurrency )
|
||||||
{
|
{
|
||||||
|
@ -190,8 +203,29 @@ get_num_processors( void )
|
||||||
return( nproc );
|
return( nproc );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set (p)thr_concurrency() from IM_CONCURRENCY environment variable. Return
|
/**
|
||||||
* the number of regions we should pass over the image.
|
* vips_concurrency_get:
|
||||||
|
*
|
||||||
|
* Returns the number of worker threads that vips should use when running a
|
||||||
|
* #VipsThreadPool.
|
||||||
|
*
|
||||||
|
* vips gets this values from these sources in turn:
|
||||||
|
*
|
||||||
|
* If vips_concurrency_set() has been called, this value is used. The special
|
||||||
|
* value 0 means "default". You can also use the command-line argument
|
||||||
|
* "--vips-concurrency" to set this value.
|
||||||
|
*
|
||||||
|
* If vips_concurrency_set() has not been called and no command-line argument
|
||||||
|
* was used, vips uses the value of the environment variable IM_CONCURRENCY,
|
||||||
|
*
|
||||||
|
* If IM_CONCURRENCY has not been set, vips find the number of hardware
|
||||||
|
* threads that the host machine can run in parallel and uses that value.
|
||||||
|
*
|
||||||
|
* The final value is clipped to the range 1 - 1024.
|
||||||
|
*
|
||||||
|
* See also: vips_concurrency_get().
|
||||||
|
*
|
||||||
|
* Returns: number of worker threads to use.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
vips_concurrency_get( void )
|
vips_concurrency_get( void )
|
||||||
|
|
|
@ -101,10 +101,29 @@ vips_thing_get_i( VipsThing *thing )
|
||||||
return( thing->i );
|
return( thing->i );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* glib-2.26+ only
|
||||||
|
|
||||||
G_DEFINE_BOXED_TYPE( VipsThing, vips_thing,
|
G_DEFINE_BOXED_TYPE( VipsThing, vips_thing,
|
||||||
(GBoxedCopyFunc) vips_thing_copy,
|
(GBoxedCopyFunc) vips_thing_copy,
|
||||||
(GBoxedFreeFunc) vips_thing_free );
|
(GBoxedFreeFunc) vips_thing_free );
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
GType
|
||||||
|
vips_thing_get_type( void )
|
||||||
|
{
|
||||||
|
static GType type = 0;
|
||||||
|
|
||||||
|
if( !type ) {
|
||||||
|
type = g_boxed_type_register_static( "VipsThing",
|
||||||
|
(GBoxedCopyFunc) vips_thing_copy,
|
||||||
|
(GBoxedFreeFunc) vips_thing_free );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( type );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION: VipsArea
|
* SECTION: VipsArea
|
||||||
* @short_description: an area of memory
|
* @short_description: an area of memory
|
||||||
|
|
|
@ -58,6 +58,10 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define DEBUG
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif /*HAVE_CONFIG_H*/
|
#endif /*HAVE_CONFIG_H*/
|
||||||
|
@ -244,6 +248,11 @@ shrink_gen( REGION *or, void *vseq, void *a, void *b )
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "shrink_gen: generating %d x %d at %d x %d\n",
|
||||||
|
r->width, r->height, r->left, r->top );
|
||||||
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
for( y = 0; y < r->height; y += ystep )
|
for( y = 0; y < r->height; y += ystep )
|
||||||
for( x = 0; x < r->width; x += xstep ) {
|
for( x = 0; x < r->width; x += xstep ) {
|
||||||
/* Clip the this rect against the demand size.
|
/* Clip the this rect against the demand size.
|
||||||
|
@ -257,6 +266,10 @@ shrink_gen( REGION *or, void *vseq, void *a, void *b )
|
||||||
s.top = (r->top + y) * st->yshrink;
|
s.top = (r->top + y) * st->yshrink;
|
||||||
s.width = 1 + ceil( width * st->xshrink );
|
s.width = 1 + ceil( width * st->xshrink );
|
||||||
s.height = 1 + ceil( height * st->yshrink );
|
s.height = 1 + ceil( height * st->yshrink );
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "shrink_gen: requesting %d x %d at %d x %d\n",
|
||||||
|
s.width, s.height, s.left, s.top );
|
||||||
|
#endif /*DEBUG*/
|
||||||
if( im_prepare( ir, &s ) )
|
if( im_prepare( ir, &s ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue