add a new unbuffered seq mode
things like vips copy huge.png x.v now run with only a small line cache
This commit is contained in:
parent
e5ba019942
commit
440b800e0e
@ -22,6 +22,7 @@
|
||||
- added vips_image_new_matrixv()
|
||||
- dzsave basename param now called filename, so you can use .dz as a
|
||||
destination (basename is still there but deprecated)
|
||||
- new _UNBUFFERED sequential mode saves memory in some important cases
|
||||
|
||||
3/7/13 started 7.34.2
|
||||
- lower priority for Matlab load to reduce segvs from Mat_Open(), thanks
|
||||
|
45
TODO
45
TODO
@ -1,49 +1,4 @@
|
||||
|
||||
- need a new uncached mode for open via disc
|
||||
|
||||
currently we have a huge linecache for "vips copy x.png x.v", in
|
||||
effect what vips does for open-via-disc, and therefore see >100mb ram
|
||||
use even in open-via-disc mode
|
||||
|
||||
add SEQUENTIAL_UNBUFFERED?
|
||||
|
||||
could we spot from the demand style? they do almost the same thing,
|
||||
though one is static and one dynamic, I guess
|
||||
|
||||
|
||||
vips_object_set_argument_from_string() looks at the operation class and
|
||||
sets ("sequential", TRUE) for image arguments
|
||||
|
||||
the "seq" arg needs to be an enum with various settings
|
||||
|
||||
"access",
|
||||
RANDOM, SEQUENTIAL, SEQUENTIAL_UNBUFFERED
|
||||
|
||||
|
||||
|
||||
|
||||
todo:
|
||||
|
||||
add a new operation flag, try setting it on vips_copy(), pass the flag down
|
||||
to "access"
|
||||
|
||||
in foreign/*.c, evey place that uses vips_sequential() needs to be passed a
|
||||
copy of "access"
|
||||
|
||||
when it calls vips_sequential(), it needs to set an access hint
|
||||
|
||||
vips_sequential() needs to pass this down to vips_linecache()
|
||||
|
||||
vips_linecache_build() needs to use this to adjust the setting of
|
||||
max_tiles
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- finish hist_ismonotonic()
|
||||
|
||||
needs im_conv()
|
||||
|
@ -577,7 +577,7 @@ vips_arithmetic_class_init( VipsArithmeticClass *class )
|
||||
vobject_class->description = _( "arithmetic operations" );
|
||||
vobject_class->build = vips_arithmetic_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "out", 100,
|
||||
_( "Output" ),
|
||||
|
@ -356,7 +356,7 @@ vips_colour_class_init( VipsColourClass *class )
|
||||
vobject_class->description = _( "colour operations" );
|
||||
vobject_class->build = vips_colour_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "out", 100,
|
||||
_( "Output" ),
|
||||
|
@ -328,7 +328,7 @@ vips_colourspace_class_init( VipsColourspaceClass *class )
|
||||
vobject_class->description = _( "convert to a new colourspace" );
|
||||
vobject_class->build = vips_colourspace_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "in", 1,
|
||||
_( "Input" ),
|
||||
|
@ -178,7 +178,7 @@ vips_bandary_class_init( VipsBandaryClass *class )
|
||||
vobject_class->description = _( "operations on image bands" );
|
||||
vobject_class->build = vips_bandary_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -477,7 +477,7 @@ vips_cast_class_init( VipsCastClass *class )
|
||||
vobject_class->description = _( "cast an image" );
|
||||
vobject_class->build = vips_cast_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "in", 1,
|
||||
_( "Input" ),
|
||||
|
@ -69,6 +69,81 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* VipsAlign:
|
||||
* @VIPS_ALIGN_LOW: align low coordinate edge
|
||||
* @VIPS_ALIGN_CENTRE: align centre
|
||||
* @VIPS_ALIGN_HIGH: align high coordinate edge
|
||||
*
|
||||
* See vips_join() and so on.
|
||||
*
|
||||
* Operations like vips_join() need to be told whether to align images on the
|
||||
* low or high coordinate edge, or centre.
|
||||
*
|
||||
* See also: vips_join().
|
||||
*/
|
||||
|
||||
/**
|
||||
* VipsAngle:
|
||||
* @VIPS_ANGLE_0: no rotate
|
||||
* @VIPS_ANGLE_90: 90 degrees anti-clockwise
|
||||
* @VIPS_ANGLE_180: 180 degree rotate
|
||||
* @VIPS_ANGLE_270: 90 degrees clockwise
|
||||
*
|
||||
* See vips_rot() and so on.
|
||||
*
|
||||
* Fixed rotate angles.
|
||||
*
|
||||
* See also: vips_rot().
|
||||
*/
|
||||
|
||||
/**
|
||||
* VipsExtend:
|
||||
* @VIPS_EXTEND_BLACK: extend with black (all 0) pixels
|
||||
* @VIPS_EXTEND_COPY: copy the image edges
|
||||
* @VIPS_EXTEND_REPEAT: repeat the whole image
|
||||
* @VIPS_EXTEND_MIRROR: mirror the whole image
|
||||
* @VIPS_EXTEND_WHITE: extend with white (all bits set) pixels
|
||||
* @VIPS_EXTEND_BACKGROUND: extend with colour from the @background property
|
||||
*
|
||||
* See vips_embed(), vips_conv(), vips_affine() and so on.
|
||||
*
|
||||
* When the edges of an image are extended, you can specify
|
||||
* how you want the extension done.
|
||||
*
|
||||
* #VIPS_EXTEND_BLACK --- new pixels are black, ie. all bits are zero.
|
||||
*
|
||||
* #VIPS_EXTEND_COPY --- each new pixel takes the value of the nearest edge
|
||||
* pixel
|
||||
*
|
||||
* #VIPS_EXTEND_REPEAT --- the image is tiled to fill the new area
|
||||
*
|
||||
* #VIPS_EXTEND_MIRROR --- the image is reflected and tiled to reduce hash
|
||||
* edges
|
||||
*
|
||||
* #VIPS_EXTEND_WHITE --- new pixels are white, ie. all bits are set
|
||||
*
|
||||
* #VIPS_EXTEND_BACKGROUND --- colour set from the @background property
|
||||
*
|
||||
* We have to specify the exact value of each enum member since we have to
|
||||
* keep these frozen for back compat with vips7.
|
||||
*
|
||||
* See also: vips_embed().
|
||||
*/
|
||||
|
||||
/**
|
||||
* VipsDirection:
|
||||
* @VIPS_DIRECTION_HORIZONTAL: left-right
|
||||
* @VIPS_DIRECTION_VERTICAL: top-bottom
|
||||
*
|
||||
* See vips_flip(), vips_join() and so on.
|
||||
*
|
||||
* Operations like vips_flip() need to be told whether to flip left-right or
|
||||
* top-bottom.
|
||||
*
|
||||
* See also: vips_flip(), vips_join().
|
||||
*/
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE( VipsConversion, vips_conversion, VIPS_TYPE_OPERATION );
|
||||
|
||||
static int
|
||||
|
@ -320,7 +320,7 @@ vips_copy_class_init( VipsCopyClass *class )
|
||||
* cache it. Plus copy is cheap.
|
||||
*/
|
||||
operation_class->flags =
|
||||
VIPS_OPERATION_SEQUENTIAL |
|
||||
VIPS_OPERATION_SEQUENTIAL_UNBUFFERED |
|
||||
VIPS_OPERATION_NOCACHE;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "in", 1,
|
||||
|
@ -545,7 +545,7 @@ vips_embed_class_init( VipsEmbedClass *class )
|
||||
vobject_class->description = _( "embed an image in a larger image" );
|
||||
vobject_class->build = vips_embed_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "in", -1,
|
||||
_( "Input" ),
|
||||
|
@ -194,7 +194,7 @@ vips_extract_area_class_init( VipsExtractAreaClass *class )
|
||||
vobject_class->description = _( "extract an area from an image" );
|
||||
vobject_class->build = vips_extract_area_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "input", 0,
|
||||
_( "Input" ),
|
||||
|
@ -369,7 +369,7 @@ vips_falsecolour_class_init( VipsFalsecolourClass *class )
|
||||
vobject_class->description = _( "false colour an image" );
|
||||
vobject_class->build = vips_falsecolour_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "in", 0,
|
||||
_( "in" ),
|
||||
|
@ -371,7 +371,7 @@ vips_flatten_class_init( VipsFlattenClass *class )
|
||||
vobject_class->description = _( "flatten alpha out of an image" );
|
||||
vobject_class->build = vips_flatten_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "in", 1,
|
||||
_( "Input" ),
|
||||
|
@ -105,7 +105,7 @@ vips_gammacorrect_class_init( VipsGammacorrectClass *class )
|
||||
vobject_class->description = _( "gammacorrect a pair of images" );
|
||||
vobject_class->build = vips_gammacorrect_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "in", -1,
|
||||
_( "in" ),
|
||||
|
@ -471,7 +471,7 @@ vips_ifthenelse_class_init( VipsIfthenelseClass *class )
|
||||
vobject_class->description = _( "ifthenelse an image" );
|
||||
vobject_class->build = vips_ifthenelse_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "cond", -2,
|
||||
_( "Condition" ),
|
||||
|
@ -355,7 +355,7 @@ vips_insert_class_init( VipsInsertClass *class )
|
||||
vobject_class->description = _( "insert an image" );
|
||||
vobject_class->build = vips_insert_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "main", -1,
|
||||
_( "Main" ),
|
||||
|
@ -228,7 +228,7 @@ vips_join_class_init( VipsJoinClass *class )
|
||||
vobject_class->description = _( "join a pair of images" );
|
||||
vobject_class->build = vips_join_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "in1", -1,
|
||||
_( "in1" ),
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* im_msb
|
||||
/* vips_msb()
|
||||
*
|
||||
* Copyright: 2006, The Nottingham Trent University
|
||||
*
|
||||
@ -239,7 +239,7 @@ vips_msb_class_init( VipsMsbClass *class )
|
||||
_( "pick most-significant byte from an image" );
|
||||
vobject_class->build = vips_msb_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "in", 0,
|
||||
_( "Input" ),
|
||||
|
@ -196,7 +196,7 @@ vips_recomb_class_init( VipsRecombClass *class )
|
||||
object_class->description = _( "linear recombination with matrix" );
|
||||
object_class->build = vips_recomb_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "in", 0,
|
||||
_( "Input" ),
|
||||
|
@ -76,6 +76,7 @@ typedef struct _VipsSequential {
|
||||
|
||||
VipsImage *in;
|
||||
int tile_height;
|
||||
VipsAccess access;
|
||||
gboolean trace;
|
||||
|
||||
/* Lock access to y_pos with this, use the cond to wake up stalled
|
||||
@ -266,7 +267,7 @@ vips_sequential_build( VipsObject *object )
|
||||
|
||||
if( vips_linecache( sequential->in, &t,
|
||||
"tile_height", sequential->tile_height,
|
||||
"strategy", VIPS_CACHE_SEQUENTIAL,
|
||||
"access", sequential->access,
|
||||
NULL ) )
|
||||
return( -1 );
|
||||
|
||||
@ -319,12 +320,20 @@ vips_sequential_class_init( VipsSequentialClass *class )
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsSequential, tile_height ),
|
||||
1, 1000000, 1 );
|
||||
|
||||
VIPS_ARG_ENUM( class, "access", 6,
|
||||
_( "Strategy" ),
|
||||
_( "Expected access pattern" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsSequential, access ),
|
||||
VIPS_TYPE_ACCESS, VIPS_ACCESS_SEQUENTIAL );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_sequential_init( VipsSequential *sequential )
|
||||
{
|
||||
sequential->trace = FALSE;
|
||||
sequential->access = VIPS_ACCESS_SEQUENTIAL;
|
||||
sequential->lock = vips_g_mutex_new();
|
||||
sequential->ready = vips_g_cond_new();
|
||||
sequential->tile_height = 1;
|
||||
@ -341,6 +350,7 @@ vips_sequential_init( VipsSequential *sequential )
|
||||
*
|
||||
* @trace: trace requests
|
||||
* @strip_height: height of cache strips
|
||||
* @access: access pattern
|
||||
*
|
||||
* This operation behaves rather like vips_copy() between images
|
||||
* @in and @out, except that it checks that pixels are only requested
|
||||
@ -357,6 +367,9 @@ vips_sequential_init( VipsSequential *sequential )
|
||||
* @strip_height can be used to set the size of the tiles that
|
||||
* vips_sequential() uses. The default value is 1.
|
||||
*
|
||||
* @access can be set to #VIPS_ACCESS_SEQUENTIAL_UNBUFFERED, meaning don't
|
||||
* keep a large cache behind the read point. This can save some memory.
|
||||
*
|
||||
* See also: vips_image_cache().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
|
@ -119,7 +119,7 @@ typedef struct _VipsBlockCache {
|
||||
int tile_width;
|
||||
int tile_height;
|
||||
int max_tiles;
|
||||
VipsCacheStrategy strategy;
|
||||
VipsAccess access;
|
||||
gboolean threaded;
|
||||
gboolean persistent;
|
||||
|
||||
@ -261,15 +261,16 @@ vips_tile_search_recycle( gpointer key, gpointer value, gpointer user_data )
|
||||
/* Only consider unreffed tiles for recycling.
|
||||
*/
|
||||
if( !tile->ref_count ) {
|
||||
switch( cache->strategy ) {
|
||||
case VIPS_CACHE_RANDOM:
|
||||
switch( cache->access ) {
|
||||
case VIPS_ACCESS_RANDOM:
|
||||
if( tile->time < search->oldest ) {
|
||||
search->oldest = tile->time;
|
||||
search->tile = tile;
|
||||
}
|
||||
break;
|
||||
|
||||
case VIPS_CACHE_SEQUENTIAL:
|
||||
case VIPS_ACCESS_SEQUENTIAL:
|
||||
case VIPS_ACCESS_SEQUENTIAL_UNBUFFERED:
|
||||
if( tile->pos.top < search->topmost ) {
|
||||
search->topmost = tile->pos.top;
|
||||
search->tile = tile;
|
||||
@ -410,12 +411,12 @@ vips_block_cache_class_init( VipsBlockCacheClass *class )
|
||||
G_STRUCT_OFFSET( VipsBlockCache, tile_height ),
|
||||
1, 1000000, 128 );
|
||||
|
||||
VIPS_ARG_ENUM( class, "strategy", 6,
|
||||
_( "Strategy" ),
|
||||
VIPS_ARG_ENUM( class, "access", 6,
|
||||
_( "Access" ),
|
||||
_( "Expected access pattern" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsBlockCache, strategy ),
|
||||
VIPS_TYPE_CACHE_STRATEGY, VIPS_CACHE_RANDOM );
|
||||
G_STRUCT_OFFSET( VipsBlockCache, access ),
|
||||
VIPS_TYPE_ACCESS, VIPS_ACCESS_RANDOM );
|
||||
|
||||
VIPS_ARG_BOOL( class, "threaded", 7,
|
||||
_( "Threaded" ),
|
||||
@ -476,7 +477,7 @@ vips_block_cache_init( VipsBlockCache *cache )
|
||||
cache->tile_width = 128;
|
||||
cache->tile_height = 128;
|
||||
cache->max_tiles = 1000;
|
||||
cache->strategy = VIPS_CACHE_RANDOM;
|
||||
cache->access = VIPS_ACCESS_RANDOM;
|
||||
cache->threaded = FALSE;
|
||||
cache->persistent = FALSE;
|
||||
|
||||
@ -799,7 +800,7 @@ vips_tile_cache_init( VipsTileCache *cache )
|
||||
* @tile_width: width of tiles in cache
|
||||
* @tile_height: height of tiles in cache
|
||||
* @max_tiles: maximum number of tiles to cache
|
||||
* @strategy: hint expected access pattern #VipsCacheStrategy
|
||||
* @access: hint expected access pattern #VipsAccess
|
||||
* @threaded: allow many threads
|
||||
* @persistent: don't drop cache at end of computation
|
||||
*
|
||||
@ -812,12 +813,13 @@ vips_tile_cache_init( VipsTileCache *cache )
|
||||
* Each cache tile is made with a single call to
|
||||
* vips_image_prepare().
|
||||
*
|
||||
* When the cache fills, a tile is chosen for reuse. If @strategy is
|
||||
* #VIPS_CACHE_RANDOM, then the least-recently-used tile is reused. If
|
||||
* @strategy is #VIPS_CACHE_SEQUENTIAL, the top-most tile is reused.
|
||||
* When the cache fills, a tile is chosen for reuse. If @access is
|
||||
* #VIPS_ACCESS_RANDOM, then the least-recently-used tile is reused. If
|
||||
* @access is #VIPS_ACCESS_SEQUENTIAL or #VIPS_ACCESS_SEQUENTIAL_UNBUFFERED,
|
||||
* the top-most tile is reused.
|
||||
*
|
||||
* By default, @tile_width and @tile_height are 128 pixels, and the operation
|
||||
* will cache up to 1,000 tiles. @strategy defaults to #VIPS_CACHE_RANDOM.
|
||||
* will cache up to 1,000 tiles. @access defaults to #VIPS_ACCESS_RANDOM.
|
||||
*
|
||||
* Normally, only a single thread at once is allowed to calculate tiles. If
|
||||
* you set @threaded to %TRUE, vips_tilecache() will allow many threads to
|
||||
@ -846,6 +848,8 @@ vips_tilecache( VipsImage *in, VipsImage **out, ... )
|
||||
typedef struct _VipsLineCache {
|
||||
VipsBlockCache parent_instance;
|
||||
|
||||
VipsAccess access;
|
||||
|
||||
} VipsLineCache;
|
||||
|
||||
typedef VipsBlockCacheClass VipsLineCacheClass;
|
||||
@ -863,9 +867,12 @@ vips_line_cache_gen( VipsRegion *or,
|
||||
/* We size up the cache to the largest request.
|
||||
*/
|
||||
if( or->valid.height >
|
||||
block_cache->max_tiles * block_cache->tile_height )
|
||||
block_cache->max_tiles * block_cache->tile_height ) {
|
||||
block_cache->max_tiles =
|
||||
1 + (or->valid.height / block_cache->tile_height);
|
||||
VIPS_DEBUG_MSG( "vips_line_cache_gen: bumped max_tiles to %d\n",
|
||||
block_cache->max_tiles );
|
||||
}
|
||||
|
||||
g_mutex_unlock( block_cache->lock );
|
||||
|
||||
@ -879,10 +886,6 @@ vips_line_cache_build( VipsObject *object )
|
||||
VipsBlockCache *block_cache = (VipsBlockCache *) object;
|
||||
VipsLineCache *cache = (VipsLineCache *) object;
|
||||
|
||||
int tile_width;
|
||||
int tile_height;
|
||||
int nlines;
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_line_cache_build\n" );
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_line_cache_parent_class )->
|
||||
@ -893,18 +896,32 @@ vips_line_cache_build( VipsObject *object )
|
||||
*/
|
||||
block_cache->tile_width = block_cache->in->Xsize;
|
||||
|
||||
/* Enough lines for two complete buffers would be exactly right. Make
|
||||
* it 3 to give us some slop room.
|
||||
*
|
||||
* This can go up with request size, see vips_line_cache_gen().
|
||||
*/
|
||||
vips_get_tile_size( block_cache->in,
|
||||
&tile_width, &tile_height, &nlines );
|
||||
block_cache->max_tiles = 3 * (1 + nlines / block_cache->tile_height);
|
||||
block_cache->access = cache->access;
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_line_cache_build: max_tiles = %d, "
|
||||
"tile_height = %d, nlines = %d\n",
|
||||
block_cache->max_tiles, block_cache->tile_height, nlines );
|
||||
if( cache->access == VIPS_ACCESS_SEQUENTIAL_UNBUFFERED )
|
||||
block_cache->max_tiles = 1;
|
||||
else {
|
||||
/* Enough lines for two complete buffers would be exactly
|
||||
* right. Make it 3 to give us some slop room.
|
||||
*
|
||||
* This can go up with request size, see vips_line_cache_gen().
|
||||
*/
|
||||
int tile_width;
|
||||
int tile_height;
|
||||
int nlines;
|
||||
|
||||
vips_get_tile_size( block_cache->in,
|
||||
&tile_width, &tile_height, &nlines );
|
||||
block_cache->max_tiles = 3 *
|
||||
(1 + nlines / block_cache->tile_height);
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_line_cache_build: nlines = %d\n",
|
||||
nlines );
|
||||
}
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_line_cache_build: "
|
||||
"max_tiles = %d, tile_height = %d\n",
|
||||
block_cache->max_tiles, block_cache->tile_height );
|
||||
|
||||
if( vips_image_pio_input( block_cache->in ) )
|
||||
return( -1 );
|
||||
@ -937,11 +954,19 @@ vips_line_cache_class_init( VipsLineCacheClass *class )
|
||||
vobject_class->description = _( "cache an image as a set of lines" );
|
||||
vobject_class->build = vips_line_cache_build;
|
||||
|
||||
VIPS_ARG_ENUM( class, "access", 6,
|
||||
_( "Access" ),
|
||||
_( "Expected access pattern" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsLineCache, access ),
|
||||
VIPS_TYPE_ACCESS, VIPS_ACCESS_SEQUENTIAL );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
vips_line_cache_init( VipsLineCache *cache )
|
||||
{
|
||||
cache->access = VIPS_ACCESS_SEQUENTIAL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -952,29 +977,31 @@ vips_line_cache_init( VipsLineCache *cache )
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* @strategy: hint expected access pattern #VipsCacheStrategy
|
||||
* @access: hint expected access pattern #VipsAccess
|
||||
* @tile_height: height of tiles in cache
|
||||
* @threaded: allow many threads
|
||||
*
|
||||
* This operation behaves rather like vips_copy() between images
|
||||
* @in and @out, except that it keeps a cache of computed pixels.
|
||||
* This cache is made of a set of scanlines. The number of lines cached is
|
||||
* equal to the maximum prepare request.
|
||||
* @in and @out, except that it keeps a cache of computed scanlines.
|
||||
*
|
||||
* The number of lines cached is enough for a small amount of non-local
|
||||
* access. If you know you will not be making any non-local access, you can
|
||||
* save some memory and set @access to #VIPS_ACCESS_SEQUENTIAL_UNBUFFERED.
|
||||
*
|
||||
* Each cache tile is made with a single call to
|
||||
* vips_image_prepare().
|
||||
*
|
||||
* When the cache fills, a tile is chosen for reuse. If @strategy is
|
||||
* #VIPS_CACHE_RANDOM, then the least-recently-used tile is reused. If
|
||||
* @strategy is #VIPS_CACHE_SEQUENTIAL, the top-most tile is reused.
|
||||
* @strategy defaults to #VIPS_CACHE_RANDOM.
|
||||
* When the cache fills, a tile is chosen for reuse. If @access is
|
||||
* #VIPS_ACCESS_RANDOM, then the least-recently-used tile is reused. If
|
||||
* @access is #VIPS_ACCESS_SEQUENTIAL or #VIPS_ACCESS_SEQUENTIAL_UNBUFFERED,
|
||||
* the top-most tile is reused. @access defaults to #VIPS_ACCESS_RANDOM.
|
||||
*
|
||||
* @tile_height can be used to set the size of the strips that
|
||||
* vips_linecache() uses. The default is 1 (a single scanline).
|
||||
*
|
||||
* Normally, only a single thread at once is allowed to calculate tiles. If
|
||||
* you set @threaded to %TRUE, vips_linecache() will allow many threads to
|
||||
* calculate tiles at once, and share the cache between them.
|
||||
* calculate tiles at once and share the cache between them.
|
||||
*
|
||||
* See also: vips_cache(), vips_tilecache().
|
||||
*
|
||||
|
@ -386,7 +386,7 @@ vips_zoom_class_init( VipsZoomClass *class )
|
||||
vobject_class->description = _( "zoom an image" );
|
||||
vobject_class->build = vips_zoom_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "input", 0,
|
||||
_( "Input" ),
|
||||
|
@ -115,7 +115,7 @@ jpeg2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||
|
||||
#ifdef HAVE_JPEG
|
||||
if( vips__jpeg_read_file( filename, out,
|
||||
header_only, shrink, fail_on_warn ) )
|
||||
header_only, shrink, fail_on_warn, TRUE ) )
|
||||
return( -1 );
|
||||
#else
|
||||
vips_error( "im_jpeg2vips",
|
||||
|
@ -87,7 +87,7 @@ png2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||
return( -1 );
|
||||
}
|
||||
else {
|
||||
if( vips__png_read( filename, out ) )
|
||||
if( vips__png_read( filename, out, TRUE ) )
|
||||
return( -1 );
|
||||
}
|
||||
#else
|
||||
|
@ -98,7 +98,7 @@ tiff2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||
return( -1 );
|
||||
}
|
||||
else {
|
||||
if( vips__tiff_read( filename, out, page ) )
|
||||
if( vips__tiff_read( filename, out, page, TRUE ) )
|
||||
return( -1 );
|
||||
}
|
||||
#else
|
||||
|
@ -3770,7 +3770,7 @@ im_tile_cache( IMAGE *in, IMAGE *out,
|
||||
"tile_width", tile_width,
|
||||
"tile_height", tile_height,
|
||||
"max_tiles", max_tiles,
|
||||
"strategy", VIPS_CACHE_SEQUENTIAL,
|
||||
"access", VIPS_ACCESS_SEQUENTIAL,
|
||||
"threaded", TRUE,
|
||||
NULL ) )
|
||||
return( -1 );
|
||||
|
@ -135,26 +135,6 @@
|
||||
* need to swap bytes. See vips_copy().
|
||||
*/
|
||||
|
||||
/**
|
||||
* VipsForeignAccess:
|
||||
* @VIPS_FOREIGN_ACCESS_RANDOM: can read anywhere
|
||||
* @VIPS_FOREIGN_ACCESS_SEQUENTIAL: top-to-bottom reading only, but with a small buffer
|
||||
* @VIPS_FOREIGN_ACCESS_SEQUENTIAL_UNBUFFERED: top-to-bottom reading only
|
||||
*
|
||||
* Set this flag on a loader to indicate the type of access you need.
|
||||
*
|
||||
* @VIPS_FOREIGN_ACCESS_RANDOM means you require full random access to the
|
||||
* image. This is usually the most expensive type of access to provide.
|
||||
*
|
||||
* @VIPS_FOREIGN_ACCESS_SEQUENTIAL means you only need need top-to-bottom
|
||||
* reading, but you need a smll buffer (a few hundred scanlines) behind the
|
||||
* read point.
|
||||
*
|
||||
* @VIPS_FOREIGN_ACCESS_SEQUENTIAL_UNBUFFERED means you only need
|
||||
* top-to-bottom access. This is usually the cheapest type of access to
|
||||
* provide.
|
||||
*/
|
||||
|
||||
/**
|
||||
* VipsForeignClass:
|
||||
*
|
||||
@ -705,7 +685,7 @@ vips_foreign_load_temp( VipsForeignLoad *load )
|
||||
* directly.
|
||||
*/
|
||||
if( (load->flags & VIPS_FOREIGN_SEQUENTIAL) &&
|
||||
load->access != VIPS_FOREIGN_ACCESS_RANDOM ) {
|
||||
load->access != VIPS_ACCESS_RANDOM ) {
|
||||
#ifdef DEBUG
|
||||
printf( "vips_foreign_load_temp: partial sequential temp\n" );
|
||||
#endif /*DEBUG*/
|
||||
@ -961,7 +941,7 @@ vips_foreign_load_class_init( VipsForeignLoadClass *class )
|
||||
_( "Required access pattern for this file" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoad, access ),
|
||||
VIPS_TYPE_FOREIGN_ACCESS, VIPS_FOREIGN_ACCESS_RANDOM );
|
||||
VIPS_TYPE_ACCESS, VIPS_ACCESS_RANDOM );
|
||||
|
||||
VIPS_ARG_BOOL( class, "sequential", 10,
|
||||
_( "Sequential" ),
|
||||
@ -976,7 +956,7 @@ static void
|
||||
vips_foreign_load_init( VipsForeignLoad *load )
|
||||
{
|
||||
load->disc = TRUE;
|
||||
load->access = VIPS_FOREIGN_ACCESS_RANDOM;
|
||||
load->access = VIPS_ACCESS_RANDOM;
|
||||
}
|
||||
|
||||
/* Abstract base class for image savers.
|
||||
|
@ -60,11 +60,9 @@ int vips__jpeg_write_buffer( VipsImage *in,
|
||||
|
||||
int vips__isjpeg( const char *filename );
|
||||
int vips__jpeg_read_file( const char *name, VipsImage *out,
|
||||
gboolean header_only,
|
||||
int shrink, gboolean fail );
|
||||
gboolean header_only, int shrink, gboolean fail, gboolean readbehind );
|
||||
int vips__jpeg_read_buffer( void *buf, size_t len, VipsImage *out,
|
||||
gboolean header_only,
|
||||
int shrink, int fail );
|
||||
gboolean header_only, int shrink, int fail, gboolean readbehind );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -144,6 +144,10 @@ typedef struct _ReadJpeg {
|
||||
*/
|
||||
gboolean fail;
|
||||
|
||||
/* Use a read behind buffer.
|
||||
*/
|
||||
gboolean readbehind;
|
||||
|
||||
/* Used for file input only.
|
||||
*/
|
||||
char *filename;
|
||||
@ -208,7 +212,7 @@ readjpeg_close( VipsObject *object, ReadJpeg *jpeg )
|
||||
}
|
||||
|
||||
static ReadJpeg *
|
||||
readjpeg_new( VipsImage *out, int shrink, gboolean fail )
|
||||
readjpeg_new( VipsImage *out, int shrink, gboolean fail, gboolean readbehind )
|
||||
{
|
||||
ReadJpeg *jpeg;
|
||||
|
||||
@ -218,6 +222,7 @@ readjpeg_new( VipsImage *out, int shrink, gboolean fail )
|
||||
jpeg->out = out;
|
||||
jpeg->shrink = shrink;
|
||||
jpeg->fail = fail;
|
||||
jpeg->readbehind = readbehind;
|
||||
jpeg->filename = NULL;
|
||||
jpeg->decompressing = FALSE;
|
||||
|
||||
@ -959,6 +964,9 @@ read_jpeg_image( ReadJpeg *jpeg, VipsImage *out )
|
||||
jpeg, NULL ) ||
|
||||
vips_sequential( t[0], &t[1],
|
||||
"tile_height", 8,
|
||||
"access", jpeg->readbehind ?
|
||||
VIPS_ACCESS_SEQUENTIAL :
|
||||
VIPS_ACCESS_SEQUENTIAL_UNBUFFERED,
|
||||
NULL ) ||
|
||||
vips_image_write( t[1], out ) )
|
||||
return( -1 );
|
||||
@ -970,12 +978,12 @@ read_jpeg_image( ReadJpeg *jpeg, VipsImage *out )
|
||||
*/
|
||||
int
|
||||
vips__jpeg_read_file( const char *filename, VipsImage *out,
|
||||
gboolean header_only, int shrink, gboolean fail )
|
||||
gboolean header_only, int shrink, gboolean fail, gboolean readbehind )
|
||||
{
|
||||
ReadJpeg *jpeg;
|
||||
int result;
|
||||
|
||||
if( !(jpeg = readjpeg_new( out, shrink, fail )) )
|
||||
if( !(jpeg = readjpeg_new( out, shrink, fail, readbehind )) )
|
||||
return( -1 );
|
||||
|
||||
/* Here for longjmp() from vips__new_error_exit() during startup.
|
||||
@ -1189,12 +1197,12 @@ readjpeg_buffer (ReadJpeg *jpeg, void *buf, size_t len)
|
||||
|
||||
int
|
||||
vips__jpeg_read_buffer( void *buf, size_t len, VipsImage *out,
|
||||
gboolean header_only, int shrink, int fail )
|
||||
gboolean header_only, int shrink, int fail, gboolean readbehind )
|
||||
{
|
||||
ReadJpeg *jpeg;
|
||||
int result;
|
||||
|
||||
if( !(jpeg = readjpeg_new( out, shrink, fail )) )
|
||||
if( !(jpeg = readjpeg_new( out, shrink, fail, readbehind )) )
|
||||
return( -1 );
|
||||
|
||||
if( setjmp( jpeg->eman.jmp ) ) {
|
||||
|
@ -199,7 +199,7 @@ vips_foreign_load_jpeg_file_header( VipsForeignLoad *load )
|
||||
VipsForeignLoadJpegFile *file = (VipsForeignLoadJpegFile *) load;
|
||||
|
||||
if( vips__jpeg_read_file( file->filename, load->out,
|
||||
TRUE, jpeg->shrink, jpeg->fail ) )
|
||||
TRUE, jpeg->shrink, jpeg->fail, FALSE ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -212,7 +212,8 @@ vips_foreign_load_jpeg_file_load( VipsForeignLoad *load )
|
||||
VipsForeignLoadJpegFile *file = (VipsForeignLoadJpegFile *) load;
|
||||
|
||||
if( vips__jpeg_read_file( file->filename, load->real,
|
||||
FALSE, jpeg->shrink, jpeg->fail ) )
|
||||
FALSE, jpeg->shrink, jpeg->fail,
|
||||
load->access == VIPS_ACCESS_SEQUENTIAL ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -276,7 +277,7 @@ vips_foreign_load_jpeg_buffer_header( VipsForeignLoad *load )
|
||||
VipsForeignLoadJpegBuffer *buffer = (VipsForeignLoadJpegBuffer *) load;
|
||||
|
||||
if( vips__jpeg_read_buffer( buffer->buf->data, buffer->buf->length,
|
||||
load->out, TRUE, jpeg->shrink, jpeg->fail ) )
|
||||
load->out, TRUE, jpeg->shrink, jpeg->fail, FALSE ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -289,7 +290,8 @@ vips_foreign_load_jpeg_buffer_load( VipsForeignLoad *load )
|
||||
VipsForeignLoadJpegBuffer *buffer = (VipsForeignLoadJpegBuffer *) load;
|
||||
|
||||
if( vips__jpeg_read_buffer( buffer->buf->data, buffer->buf->length,
|
||||
load->real, FALSE, jpeg->shrink, jpeg->fail ) )
|
||||
load->real, FALSE, jpeg->shrink, jpeg->fail,
|
||||
load->access == VIPS_ACCESS_SEQUENTIAL ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
|
@ -104,7 +104,8 @@ vips_foreign_load_png_load( VipsForeignLoad *load )
|
||||
{
|
||||
VipsForeignLoadPng *png = (VipsForeignLoadPng *) load;
|
||||
|
||||
if( vips__png_read( png->filename, load->real ) )
|
||||
if( vips__png_read( png->filename, load->real,
|
||||
load->access == VIPS_ACCESS_SEQUENTIAL ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -178,7 +179,7 @@ vips_foreign_load_png_buffer_load( VipsForeignLoad *load )
|
||||
VipsForeignLoadPngBuffer *png = (VipsForeignLoadPngBuffer *) load;
|
||||
|
||||
if( vips__png_read_buffer( png->buf->data, png->buf->length,
|
||||
load->real ) )
|
||||
load->real, load->access == VIPS_ACCESS_SEQUENTIAL ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
|
@ -49,7 +49,8 @@ int vips__tiff_write( VipsImage *in, const char *filename,
|
||||
VipsForeignTiffResunit resunit, double xres, double yres,
|
||||
gboolean bigtiff );
|
||||
|
||||
int vips__tiff_read( const char *filename, VipsImage *out, int page );
|
||||
int vips__tiff_read( const char *filename, VipsImage *out, int page,
|
||||
gboolean readbehind );
|
||||
int vips__tiff_read_header( const char *filename, VipsImage *out, int page );
|
||||
gboolean vips__istifftiled( const char *filename );
|
||||
gboolean vips__istiff( const char *filename );
|
||||
|
@ -206,10 +206,8 @@ typedef struct _ReadTiff {
|
||||
*/
|
||||
char *filename;
|
||||
VipsImage *out;
|
||||
|
||||
/* From filename.
|
||||
*/
|
||||
int page;
|
||||
gboolean readbehind;
|
||||
|
||||
/* The TIFF we read.
|
||||
*/
|
||||
@ -1497,6 +1495,9 @@ read_stripwise( ReadTiff *rtiff, VipsImage *out )
|
||||
rtiff, NULL ) ||
|
||||
vips_sequential( t[0], &t[1],
|
||||
"tile_height", rtiff->rows_per_strip,
|
||||
"access", rtiff->readbehind ?
|
||||
VIPS_ACCESS_SEQUENTIAL :
|
||||
VIPS_ACCESS_SEQUENTIAL_UNBUFFERED,
|
||||
NULL ) ||
|
||||
vips_image_write( t[1], out ) )
|
||||
return( -1 );
|
||||
@ -1511,7 +1512,8 @@ readtiff_destroy( VipsObject *object, ReadTiff *rtiff )
|
||||
}
|
||||
|
||||
static ReadTiff *
|
||||
readtiff_new( const char *filename, VipsImage *out, int page )
|
||||
readtiff_new( const char *filename, VipsImage *out, int page,
|
||||
gboolean readbehind )
|
||||
{
|
||||
ReadTiff *rtiff;
|
||||
|
||||
@ -1521,6 +1523,7 @@ readtiff_new( const char *filename, VipsImage *out, int page )
|
||||
rtiff->filename = vips_strdup( VIPS_OBJECT( out ), filename );
|
||||
rtiff->out = out;
|
||||
rtiff->page = page;
|
||||
rtiff->readbehind = readbehind;
|
||||
rtiff->tiff = NULL;
|
||||
rtiff->sfn = NULL;
|
||||
rtiff->client = NULL;
|
||||
@ -1594,7 +1597,8 @@ istiffpyramid( const char *name )
|
||||
*/
|
||||
|
||||
int
|
||||
vips__tiff_read( const char *filename, VipsImage *out, int page )
|
||||
vips__tiff_read( const char *filename, VipsImage *out, int page,
|
||||
gboolean readbehind )
|
||||
{
|
||||
ReadTiff *rtiff;
|
||||
|
||||
@ -1605,7 +1609,7 @@ vips__tiff_read( const char *filename, VipsImage *out, int page )
|
||||
|
||||
vips__tiff_init();
|
||||
|
||||
if( !(rtiff = readtiff_new( filename, out, page )) )
|
||||
if( !(rtiff = readtiff_new( filename, out, page, readbehind )) )
|
||||
return( -1 );
|
||||
|
||||
if( !(rtiff->tiff = get_directory( rtiff->filename, rtiff->page )) ) {
|
||||
@ -1633,7 +1637,7 @@ vips__tiff_read_header( const char *filename, VipsImage *out, int page )
|
||||
|
||||
vips__tiff_init();
|
||||
|
||||
if( !(rtiff = readtiff_new( filename, out, page )) )
|
||||
if( !(rtiff = readtiff_new( filename, out, page, FALSE )) )
|
||||
return( -1 );
|
||||
|
||||
if( !(rtiff->tiff = get_directory( rtiff->filename, rtiff->page )) ) {
|
||||
|
@ -108,7 +108,8 @@ vips_foreign_load_tiff_load( VipsForeignLoad *load )
|
||||
{
|
||||
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
|
||||
|
||||
if( vips__tiff_read( tiff->filename, load->real, tiff->page ) )
|
||||
if( vips__tiff_read( tiff->filename, load->real, tiff->page,
|
||||
load->access == VIPS_ACCESS_SEQUENTIAL ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
|
@ -126,6 +126,7 @@ user_warning_function( png_structp png_ptr, png_const_charp warning_msg )
|
||||
typedef struct {
|
||||
char *name;
|
||||
VipsImage *out;
|
||||
gboolean readbehind;
|
||||
|
||||
int y_pos;
|
||||
png_structp pPng;
|
||||
@ -141,6 +142,7 @@ typedef struct {
|
||||
char *buffer;
|
||||
size_t length;
|
||||
size_t read_pos;
|
||||
|
||||
} Read;
|
||||
|
||||
static void
|
||||
@ -153,7 +155,7 @@ read_destroy( VipsImage *out, Read *read )
|
||||
}
|
||||
|
||||
static Read *
|
||||
read_new( VipsImage *out )
|
||||
read_new( VipsImage *out, gboolean readbehind )
|
||||
{
|
||||
Read *read;
|
||||
|
||||
@ -161,6 +163,7 @@ read_new( VipsImage *out )
|
||||
return( NULL );
|
||||
|
||||
read->name = NULL;
|
||||
read->readbehind = readbehind;
|
||||
read->out = out;
|
||||
read->y_pos = 0;
|
||||
read->pPng = NULL;
|
||||
@ -191,11 +194,11 @@ read_new( VipsImage *out )
|
||||
}
|
||||
|
||||
static Read *
|
||||
read_new_filename( VipsImage *out, const char *name )
|
||||
read_new_filename( VipsImage *out, const char *name, gboolean readbehind )
|
||||
{
|
||||
Read *read;
|
||||
|
||||
if( !(read = read_new( out )) )
|
||||
if( !(read = read_new( out, readbehind )) )
|
||||
return( NULL );
|
||||
|
||||
read->name = vips_strdup( VIPS_OBJECT( out ), name );
|
||||
@ -393,7 +396,7 @@ vips__png_header( const char *name, VipsImage *out )
|
||||
{
|
||||
Read *read;
|
||||
|
||||
if( !(read = read_new_filename( out, name )) ||
|
||||
if( !(read = read_new_filename( out, name, FALSE )) ||
|
||||
png2vips_header( read, out ) )
|
||||
return( -1 );
|
||||
|
||||
@ -492,7 +495,7 @@ vips__png_isinterlaced( const char *filename )
|
||||
int interlace_type;
|
||||
|
||||
image = vips_image_new();
|
||||
if( !(read = read_new_filename( image, filename )) ) {
|
||||
if( !(read = read_new_filename( image, filename, FALSE )) ) {
|
||||
g_object_unref( image );
|
||||
return( -1 );
|
||||
}
|
||||
@ -527,6 +530,9 @@ png2vips_image( Read *read, VipsImage *out )
|
||||
read, NULL ) ||
|
||||
vips_sequential( t[0], &t[1],
|
||||
"tile_height", 8,
|
||||
"access", read->readbehind ?
|
||||
VIPS_ACCESS_SEQUENTIAL :
|
||||
VIPS_ACCESS_SEQUENTIAL_UNBUFFERED,
|
||||
NULL ) ||
|
||||
vips_image_write( t[1], out ) )
|
||||
return( -1 );
|
||||
@ -536,7 +542,7 @@ png2vips_image( Read *read, VipsImage *out )
|
||||
}
|
||||
|
||||
int
|
||||
vips__png_read( const char *filename, VipsImage *out )
|
||||
vips__png_read( const char *filename, VipsImage *out, gboolean readbehind )
|
||||
{
|
||||
Read *read;
|
||||
|
||||
@ -544,7 +550,7 @@ vips__png_read( const char *filename, VipsImage *out )
|
||||
printf( "vips__png_read: reading \"%s\"\n", filename );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( !(read = read_new_filename( out, filename )) ||
|
||||
if( !(read = read_new_filename( out, filename, readbehind )) ||
|
||||
png2vips_image( read, out ) )
|
||||
return( -1 );
|
||||
|
||||
@ -581,15 +587,16 @@ vips_png_read_buffer( png_structp pPng, png_bytep data, png_size_t length )
|
||||
}
|
||||
|
||||
static Read *
|
||||
read_new_buffer( VipsImage *out, char *buffer, size_t length )
|
||||
read_new_buffer( VipsImage *out, char *buffer, size_t length,
|
||||
gboolean readbehind )
|
||||
{
|
||||
Read *read;
|
||||
|
||||
if( !(read = read_new( out )) )
|
||||
if( !(read = read_new( out, readbehind )) )
|
||||
return( NULL );
|
||||
|
||||
read->buffer = buffer;
|
||||
read->length = length;
|
||||
read->buffer = buffer;
|
||||
|
||||
png_set_read_fn( read->pPng, read, vips_png_read_buffer );
|
||||
|
||||
@ -606,7 +613,7 @@ vips__png_header_buffer( char *buffer, size_t length, VipsImage *out )
|
||||
{
|
||||
Read *read;
|
||||
|
||||
if( !(read = read_new_buffer( out, buffer, length )) ||
|
||||
if( !(read = read_new_buffer( out, buffer, length, FALSE )) ||
|
||||
png2vips_header( read, out ) )
|
||||
return( -1 );
|
||||
|
||||
@ -614,11 +621,12 @@ vips__png_header_buffer( char *buffer, size_t length, VipsImage *out )
|
||||
}
|
||||
|
||||
int
|
||||
vips__png_read_buffer( char *buffer, size_t length, VipsImage *out )
|
||||
vips__png_read_buffer( char *buffer, size_t length, VipsImage *out,
|
||||
gboolean readbehind )
|
||||
{
|
||||
Read *read;
|
||||
|
||||
if( !(read = read_new_buffer( out, buffer, length )) ||
|
||||
if( !(read = read_new_buffer( out, buffer, length, readbehind )) ||
|
||||
png2vips_image( read, out ) )
|
||||
return( -1 );
|
||||
|
||||
|
@ -36,11 +36,12 @@ extern "C" {
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
int vips__png_header( const char *name, VipsImage *out );
|
||||
int vips__png_read( const char *name, VipsImage *out );
|
||||
int vips__png_read( const char *name, VipsImage *out, gboolean readbehind );
|
||||
int vips__png_ispng( const char *filename );
|
||||
gboolean vips__png_isinterlaced( const char *filename );
|
||||
extern const char *vips__png_suffs[];
|
||||
int vips__png_read_buffer( char *buffer, size_t length, VipsImage *out );
|
||||
int vips__png_read_buffer( char *buffer, size_t length, VipsImage *out,
|
||||
gboolean readbehind );
|
||||
int vips__png_header_buffer( char *buffer, size_t length, VipsImage *out );
|
||||
|
||||
int vips__png_write( VipsImage *in, const char *filename,
|
||||
|
@ -606,7 +606,7 @@ vips_maplut_class_init( VipsMaplutClass *class )
|
||||
object_class->description = _( "map an image though a lut" );
|
||||
object_class->build = vips_maplut_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "in", 1,
|
||||
_( "Input" ),
|
||||
|
@ -38,39 +38,6 @@
|
||||
extern "C" {
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
/**
|
||||
* VipsExtend:
|
||||
* @VIPS_EXTEND_BLACK: extend with black (all 0) pixels
|
||||
* @VIPS_EXTEND_COPY: copy the image edges
|
||||
* @VIPS_EXTEND_REPEAT: repeat the whole image
|
||||
* @VIPS_EXTEND_MIRROR: mirror the whole image
|
||||
* @VIPS_EXTEND_WHITE: extend with white (all bits set) pixels
|
||||
* @VIPS_EXTEND_BACKGROUND: extend with colour from the @background property
|
||||
*
|
||||
* See vips_embed(), vips_conv(), vips_affine() and so on.
|
||||
*
|
||||
* When the edges of an image are extended, you can specify
|
||||
* how you want the extension done.
|
||||
*
|
||||
* #VIPS_EXTEND_BLACK --- new pixels are black, ie. all bits are zero.
|
||||
*
|
||||
* #VIPS_EXTEND_COPY --- each new pixel takes the value of the nearest edge
|
||||
* pixel
|
||||
*
|
||||
* #VIPS_EXTEND_REPEAT --- the image is tiled to fill the new area
|
||||
*
|
||||
* #VIPS_EXTEND_MIRROR --- the image is reflected and tiled to reduce hash
|
||||
* edges
|
||||
*
|
||||
* #VIPS_EXTEND_WHITE --- new pixels are white, ie. all bits are set
|
||||
|
||||
* #VIPS_EXTEND_BACKGROUND --- colour set from the @background property
|
||||
*
|
||||
* We have to specify the exact value of each enum member since we have to
|
||||
* keep these frozen for back compat with vips7.
|
||||
*
|
||||
* See also: vips_embed().
|
||||
*/
|
||||
typedef enum {
|
||||
VIPS_EXTEND_BLACK,
|
||||
VIPS_EXTEND_COPY,
|
||||
@ -81,39 +48,12 @@ typedef enum {
|
||||
VIPS_EXTEND_LAST
|
||||
} VipsExtend;
|
||||
|
||||
/**
|
||||
* VipsDirection:
|
||||
* @VIPS_DIRECTION_HORIZONTAL: left-right
|
||||
* @VIPS_DIRECTION_VERTICAL: top-bottom
|
||||
*
|
||||
* See vips_flip(), vips_join() and so on.
|
||||
*
|
||||
* Operations like vips_flip() need to be told whether to flip left-right or
|
||||
* top-bottom.
|
||||
*
|
||||
* See also: vips_flip(), vips_join().
|
||||
*/
|
||||
typedef enum {
|
||||
VIPS_DIRECTION_HORIZONTAL,
|
||||
VIPS_DIRECTION_VERTICAL,
|
||||
VIPS_DIRECTION_LAST
|
||||
} VipsDirection;
|
||||
|
||||
/**
|
||||
* VipsAlign:
|
||||
* @VIPS_ALIGN_LOW: align low coordinate edge
|
||||
* @VIPS_ALIGN_CENTRE: align centre
|
||||
* @VIPS_ALIGN_HIGH: align high coordinate edge
|
||||
*
|
||||
* See vips_join() and so on.
|
||||
*
|
||||
* Operations like vips_join() need to be told whether to align images on the
|
||||
* low or high coordinate edge, or centre.
|
||||
*
|
||||
*
|
||||
*
|
||||
* See also: vips_join().
|
||||
*/
|
||||
typedef enum {
|
||||
VIPS_ALIGN_LOW,
|
||||
VIPS_ALIGN_CENTRE,
|
||||
@ -121,19 +61,6 @@ typedef enum {
|
||||
VIPS_ALIGN_LAST
|
||||
} VipsAlign;
|
||||
|
||||
/**
|
||||
* VipsAngle:
|
||||
* @VIPS_ANGLE_0: no rotate
|
||||
* @VIPS_ANGLE_90: 90 degrees anti-clockwise
|
||||
* @VIPS_ANGLE_180: 180 degree rotate
|
||||
* @VIPS_ANGLE_270: 90 degrees clockwise
|
||||
*
|
||||
* See vips_rot() and so on.
|
||||
*
|
||||
* Fixed rotate angles.
|
||||
*
|
||||
* See also: vips_rot().
|
||||
*/
|
||||
typedef enum {
|
||||
VIPS_ANGLE_0,
|
||||
VIPS_ANGLE_90,
|
||||
@ -142,24 +69,6 @@ typedef enum {
|
||||
VIPS_ANGLE_LAST
|
||||
} VipsAngle;
|
||||
|
||||
/**
|
||||
* VipsCacheStrategy:
|
||||
* @VIPS_CACHE_RANDOM: expect random access
|
||||
* @VIPS_CACHE_SEQUENTIAL: expect sequential access
|
||||
*
|
||||
* See vips_tilecache() and friends.
|
||||
*
|
||||
* Used to hint to caches about the expected access pattern. RANDOM might mean
|
||||
* LRU eviction, SEQUENTIAL might mean top-most eviction.
|
||||
*
|
||||
* See also: vips_tilecache().
|
||||
*/
|
||||
typedef enum {
|
||||
VIPS_CACHE_RANDOM,
|
||||
VIPS_CACHE_SEQUENTIAL,
|
||||
VIPS_CACHE_LAST
|
||||
} VipsCacheStrategy;
|
||||
|
||||
int vips_copy( VipsImage *in, VipsImage **out, ... )
|
||||
__attribute__((sentinel));
|
||||
int vips_tilecache( VipsImage *in, VipsImage **out, ... )
|
||||
|
@ -9,8 +9,6 @@ G_BEGIN_DECLS
|
||||
/* 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_foreign_access_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_FOREIGN_ACCESS (vips_foreign_access_get_type())
|
||||
GType vips_saveable_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_SAVEABLE (vips_saveable_get_type())
|
||||
GType vips_foreign_tiff_compression_get_type (void) G_GNUC_CONST;
|
||||
@ -49,8 +47,6 @@ GType vips_align_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_ALIGN (vips_align_get_type())
|
||||
GType vips_angle_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_ANGLE (vips_angle_get_type())
|
||||
GType vips_cache_strategy_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_CACHE_STRATEGY (vips_cache_strategy_get_type())
|
||||
/* enumerations from "../../../libvips/include/vips/util.h" */
|
||||
GType vips_token_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_TOKEN (vips_token_get_type())
|
||||
@ -65,6 +61,8 @@ GType vips_band_format_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_BAND_FORMAT (vips_band_format_get_type())
|
||||
GType vips_coding_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_CODING (vips_coding_get_type())
|
||||
GType vips_access_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_ACCESS (vips_access_get_type())
|
||||
/* enumerations from "../../../libvips/include/vips/colour.h" */
|
||||
GType vips_intent_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_INTENT (vips_intent_get_type())
|
||||
|
@ -110,12 +110,6 @@ typedef enum /*< flags >*/ {
|
||||
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
|
||||
VIPS_TYPE_FOREIGN_LOAD, VipsForeignLoadClass ))
|
||||
|
||||
typedef enum {
|
||||
VIPS_FOREIGN_ACCESS_RANDOM,
|
||||
VIPS_FOREIGN_ACCESS_SEQUENTIAL,
|
||||
VIPS_FOREIGN_ACCESS_SEQUENTIAL_UNBUFFERED
|
||||
} VipsForeignAccess;
|
||||
|
||||
typedef struct _VipsForeignLoad {
|
||||
VipsForeign parent_object;
|
||||
/*< private >*/
|
||||
@ -124,9 +118,9 @@ typedef struct _VipsForeignLoad {
|
||||
*/
|
||||
gboolean disc;
|
||||
|
||||
/* Type of access the reader requires.
|
||||
/* Type of access upstream wants and the loader must supply.
|
||||
*/
|
||||
VipsForeignAccess access;
|
||||
VipsAccess access;
|
||||
|
||||
/* Flags for this load operation.
|
||||
*/
|
||||
|
@ -47,44 +47,6 @@ extern "C" {
|
||||
#define VIPS_MAGIC_INTEL (0xb6a6f208U)
|
||||
#define VIPS_MAGIC_SPARC (0x08f2a6b6U)
|
||||
|
||||
/**
|
||||
* VipsDemandStyle:
|
||||
* @VIPS_DEMAND_STYLE_SMALLTILE: demand in small (typically 64x64 pixel) tiles
|
||||
* @VIPS_DEMAND_STYLE_FATSTRIP: demand in fat (typically 10 pixel high) strips
|
||||
* @VIPS_DEMAND_STYLE_THINSTRIP: demand in thin (typically 1 pixel high) strips
|
||||
* @VIPS_DEMAND_STYLE_ANY: demand geometry does not matter
|
||||
*
|
||||
* See vips_demand_hint(). Operations can hint to the VIPS image IO system about
|
||||
* the kind of demand geometry they prefer.
|
||||
*
|
||||
* These demand styles are given below in order of increasing
|
||||
* restrictiveness. When demanding output from a pipeline,
|
||||
* vips_image_generate()
|
||||
* will use the most restrictive of the styles requested by the operations
|
||||
* in the pipeline.
|
||||
*
|
||||
* #VIPS_DEMAND_STYLE_THINSTRIP --- This operation would like to output strips
|
||||
* the width of the image and a few pels high. This is option suitable for
|
||||
* point-to-point operations, such as those in the arithmetic package.
|
||||
*
|
||||
* This option is only efficient for cases where each output pel depends
|
||||
* upon the pel in the corresponding position in the input image.
|
||||
*
|
||||
* #VIPS_DEMAND_STYLE_FATSTRIP --- This operation would like to output strips
|
||||
* the width of the image and as high as possible. This option is suitable
|
||||
* for area operations which do not violently transform coordinates, such
|
||||
* as im_conv().
|
||||
*
|
||||
* #VIPS_DEMAND_STYLE_SMALLTILE --- This is the most general demand format.
|
||||
* Output is demanded in small (around 100x100 pel) sections. This style works
|
||||
* reasonably efficiently, even for bizzare operations like 45 degree rotate.
|
||||
*
|
||||
* #VIPS_DEMAND_STYLE_ANY --- This image is not being demand-read from a disc
|
||||
* file (even indirectly) so any demand style is OK. It's used for things like
|
||||
* im_black() where the pixels are calculated.
|
||||
*
|
||||
* See also: vips_demand_hint().
|
||||
*/
|
||||
typedef enum {
|
||||
VIPS_DEMAND_STYLE_ERROR = -1,
|
||||
VIPS_DEMAND_STYLE_SMALLTILE,
|
||||
@ -108,38 +70,6 @@ typedef enum {
|
||||
VIPS_IMAGE_PARTIAL /* partial image */
|
||||
} VipsImageType;
|
||||
|
||||
/**
|
||||
* VipsInterpretation:
|
||||
* @VIPS_INTERPRETATION_MULTIBAND: generic many-band image
|
||||
* @VIPS_INTERPRETATION_B_W: some kind of single-band image
|
||||
* @VIPS_INTERPRETATION_HISTOGRAM: a 1D image, eg. histogram or lookup table
|
||||
* @VIPS_INTERPRETATION_FOURIER: image is in fourier space
|
||||
* @VIPS_INTERPRETATION_XYZ: the first three bands are CIE XYZ
|
||||
* @VIPS_INTERPRETATION_LAB: pixels are in CIE Lab space
|
||||
* @VIPS_INTERPRETATION_CMYK: the first four bands are in CMYK space
|
||||
* @VIPS_INTERPRETATION_LABQ: implies #VIPS_CODING_LABQ
|
||||
* @VIPS_INTERPRETATION_RGB: generic RGB space
|
||||
* @VIPS_INTERPRETATION_CMC: a uniform colourspace based on CMC(1:1)
|
||||
* @VIPS_INTERPRETATION_LCH: pixels are in CIE LCh space
|
||||
* @VIPS_INTERPRETATION_LABS: CIE LAB coded as three signed 16-bit values
|
||||
* @VIPS_INTERPRETATION_sRGB: pixels are sRGB
|
||||
* @VIPS_INTERPRETATION_scRGB: pixels are scRGB
|
||||
* @VIPS_INTERPRETATION_YXY: pixels are CIE Yxy
|
||||
* @VIPS_INTERPRETATION_RGB16: generic 16-bit RGB
|
||||
* @VIPS_INTERPRETATION_GREY16: generic 16-bit mono
|
||||
* @VIPS_INTERPRETATION_MATRIX: a matrix
|
||||
*
|
||||
* How the values in an image should be interpreted. For example, a
|
||||
* three-band float image of type #VIPS_INTERPRETATION_LAB should have its
|
||||
* pixels interpreted as coordinates in CIE Lab space.
|
||||
*
|
||||
* These values are set by operations as hints to user-interfaces built on top
|
||||
* of VIPS to help them show images to the user in a meaningful way.
|
||||
* Operations do not use these values to decide their action.
|
||||
*
|
||||
* The gaps in the numbering are historical and must be maintained. Allocate
|
||||
* new numbers from the end.
|
||||
*/
|
||||
typedef enum {
|
||||
VIPS_INTERPRETATION_ERROR = -1,
|
||||
VIPS_INTERPRETATION_MULTIBAND = 0,
|
||||
@ -162,25 +92,6 @@ typedef enum {
|
||||
VIPS_INTERPRETATION_scRGB = 28
|
||||
} VipsInterpretation;
|
||||
|
||||
/**
|
||||
* VipsBandFormat:
|
||||
* @VIPS_FORMAT_NOTSET: invalid setting
|
||||
* @VIPS_FORMAT_UCHAR: unsigned char format
|
||||
* @VIPS_FORMAT_CHAR: char format
|
||||
* @VIPS_FORMAT_USHORT: unsigned short format
|
||||
* @VIPS_FORMAT_SHORT: short format
|
||||
* @VIPS_FORMAT_UINT: unsigned int format
|
||||
* @VIPS_FORMAT_INT: int format
|
||||
* @VIPS_FORMAT_FLOAT: float format
|
||||
* @VIPS_FORMAT_COMPLEX: complex (two floats) format
|
||||
* @VIPS_FORMAT_DOUBLE: double float format
|
||||
* @VIPS_FORMAT_DPCOMPLEX: double complex (two double) format
|
||||
*
|
||||
* The format used for each band element.
|
||||
*
|
||||
* Each corresponnds to a native C type for the current machine. For example,
|
||||
* #VIPS_FORMAT_USHORT is <type>unsigned short</type>.
|
||||
*/
|
||||
typedef enum {
|
||||
VIPS_FORMAT_NOTSET = -1,
|
||||
VIPS_FORMAT_UCHAR = 0,
|
||||
@ -196,21 +107,6 @@ typedef enum {
|
||||
VIPS_FORMAT_LAST = 10
|
||||
} VipsBandFormat;
|
||||
|
||||
/**
|
||||
* VipsCoding:
|
||||
* @VIPS_CODING_NONE: pixels are not coded
|
||||
* @VIPS_CODING_LABQ: pixels encode 3 float CIELAB values as 4 uchar
|
||||
* @VIPS_CODING_RAD: pixels encode 3 float RGB as 4 uchar (Radiance coding)
|
||||
*
|
||||
* How pixels are coded.
|
||||
*
|
||||
* Normally, pixels are uncoded and can be manipulated as you would expect.
|
||||
* However some file formats code pixels for compression, and sometimes it's
|
||||
* useful to be able to manipulate images in the coded format.
|
||||
*
|
||||
* The gaps in the numbering are historical and must be maintained. Allocate
|
||||
* new numbers from the end.
|
||||
*/
|
||||
typedef enum {
|
||||
VIPS_CODING_ERROR = -1,
|
||||
VIPS_CODING_NONE = 0,
|
||||
@ -219,6 +115,13 @@ typedef enum {
|
||||
VIPS_CODING_LAST = 7
|
||||
} VipsCoding;
|
||||
|
||||
typedef enum {
|
||||
VIPS_ACCESS_RANDOM,
|
||||
VIPS_ACCESS_SEQUENTIAL,
|
||||
VIPS_ACCESS_SEQUENTIAL_UNBUFFERED,
|
||||
VIPS_ACCESS_LAST
|
||||
} VipsAccess;
|
||||
|
||||
/* Struct we keep a record of execution time in. Passed to eval signal so
|
||||
* it can assess progress.
|
||||
*/
|
||||
|
@ -37,25 +37,11 @@ extern "C" {
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
/**
|
||||
* VipsOperationFlags:
|
||||
* @VIPS_OPERATION_NONE: no flags
|
||||
* @VIPS_OPERATION_SEQUENTIAL: can work sequentially
|
||||
* @VIPS_OPERATION_NOCACHE: must not be cached
|
||||
*
|
||||
* Flags we associate with an operation.
|
||||
*
|
||||
* @VIPS_OPERATION_SEQUENTIAL means that the operation works like vips_copy:
|
||||
* it can happily process images top-to-bottom with only small non-local
|
||||
* references.
|
||||
*
|
||||
* @VIPS_OPERATION_NOCACHE means that the operation must not be cached by
|
||||
* vips.
|
||||
*/
|
||||
typedef enum /*< flags >*/ {
|
||||
VIPS_OPERATION_NONE = 0,
|
||||
VIPS_OPERATION_SEQUENTIAL = 1,
|
||||
VIPS_OPERATION_NOCACHE = 2
|
||||
VIPS_OPERATION_SEQUENTIAL_UNBUFFERED = 2,
|
||||
VIPS_OPERATION_NOCACHE = 3
|
||||
} VipsOperationFlags;
|
||||
|
||||
#define VIPS_TYPE_OPERATION (vips_operation_get_type())
|
||||
|
@ -26,24 +26,6 @@ vips_foreign_flags_get_type( void )
|
||||
return( etype );
|
||||
}
|
||||
GType
|
||||
vips_foreign_access_get_type( void )
|
||||
{
|
||||
static GType etype = 0;
|
||||
|
||||
if( etype == 0 ) {
|
||||
static const GEnumValue values[] = {
|
||||
{VIPS_FOREIGN_ACCESS_RANDOM, "VIPS_FOREIGN_ACCESS_RANDOM", "random"},
|
||||
{VIPS_FOREIGN_ACCESS_SEQUENTIAL, "VIPS_FOREIGN_ACCESS_SEQUENTIAL", "sequential"},
|
||||
{VIPS_FOREIGN_ACCESS_SEQUENTIAL_UNBUFFERED, "VIPS_FOREIGN_ACCESS_SEQUENTIAL_UNBUFFERED", "sequential-unbuffered"},
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
|
||||
etype = g_enum_register_static( "VipsForeignAccess", values );
|
||||
}
|
||||
|
||||
return( etype );
|
||||
}
|
||||
GType
|
||||
vips_saveable_get_type( void )
|
||||
{
|
||||
static GType etype = 0;
|
||||
@ -241,24 +223,6 @@ vips_angle_get_type( void )
|
||||
|
||||
return( etype );
|
||||
}
|
||||
GType
|
||||
vips_cache_strategy_get_type( void )
|
||||
{
|
||||
static GType etype = 0;
|
||||
|
||||
if( etype == 0 ) {
|
||||
static const GEnumValue values[] = {
|
||||
{VIPS_CACHE_RANDOM, "VIPS_CACHE_RANDOM", "random"},
|
||||
{VIPS_CACHE_SEQUENTIAL, "VIPS_CACHE_SEQUENTIAL", "sequential"},
|
||||
{VIPS_CACHE_LAST, "VIPS_CACHE_LAST", "last"},
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
|
||||
etype = g_enum_register_static( "VipsCacheStrategy", values );
|
||||
}
|
||||
|
||||
return( etype );
|
||||
}
|
||||
/* enumerations from "../../libvips/include/vips/arithmetic.h" */
|
||||
GType
|
||||
vips_operation_math_get_type( void )
|
||||
@ -567,6 +531,25 @@ vips_coding_get_type( void )
|
||||
|
||||
return( etype );
|
||||
}
|
||||
GType
|
||||
vips_access_get_type( void )
|
||||
{
|
||||
static GType etype = 0;
|
||||
|
||||
if( etype == 0 ) {
|
||||
static const GEnumValue values[] = {
|
||||
{VIPS_ACCESS_RANDOM, "VIPS_ACCESS_RANDOM", "random"},
|
||||
{VIPS_ACCESS_SEQUENTIAL, "VIPS_ACCESS_SEQUENTIAL", "sequential"},
|
||||
{VIPS_ACCESS_SEQUENTIAL_UNBUFFERED, "VIPS_ACCESS_SEQUENTIAL_UNBUFFERED", "sequential-unbuffered"},
|
||||
{VIPS_ACCESS_LAST, "VIPS_ACCESS_LAST", "last"},
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
|
||||
etype = g_enum_register_static( "VipsAccess", values );
|
||||
}
|
||||
|
||||
return( etype );
|
||||
}
|
||||
/* enumerations from "../../libvips/include/vips/operation.h" */
|
||||
GType
|
||||
vips_operation_flags_get_type( void )
|
||||
@ -577,6 +560,7 @@ vips_operation_flags_get_type( void )
|
||||
static const GFlagsValue values[] = {
|
||||
{VIPS_OPERATION_NONE, "VIPS_OPERATION_NONE", "none"},
|
||||
{VIPS_OPERATION_SEQUENTIAL, "VIPS_OPERATION_SEQUENTIAL", "sequential"},
|
||||
{VIPS_OPERATION_SEQUENTIAL_UNBUFFERED, "VIPS_OPERATION_SEQUENTIAL_UNBUFFERED", "sequential-unbuffered"},
|
||||
{VIPS_OPERATION_NOCACHE, "VIPS_OPERATION_NOCACHE", "nocache"},
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
|
@ -80,6 +80,132 @@
|
||||
* The first four bytes of a VIPS file in SPARC byte ordering.
|
||||
*/
|
||||
|
||||
/**
|
||||
* VipsAccess:
|
||||
* @VIPS_ACCESS_RANDOM: can read anywhere
|
||||
* @VIPS_ACCESS_SEQUENTIAL: top-to-bottom reading only, but with a small buffer
|
||||
* @VIPS_ACCESS_SEQUENTIAL_UNBUFFERED: top-to-bottom reading only
|
||||
*
|
||||
* The type of access an operation has to supply. See vips_tilecache()
|
||||
* and #VipsForeign.
|
||||
*
|
||||
* @VIPS_ACCESS_RANDOM means requests can come in any order.
|
||||
*
|
||||
* @VIPS_ACCESS_SEQUENTIAL means requests will be top-to-bottom, but with some
|
||||
* amount of buffering behind the read point for small non-local accesses.
|
||||
*
|
||||
* @VIPS_ACCESS_SEQUENTIAL_UNBUFFERED means requests will be strictly
|
||||
* top-to-bottom with no read-behind. This can save some memory.
|
||||
*/
|
||||
|
||||
/**
|
||||
* VipsDemandStyle:
|
||||
* @VIPS_DEMAND_STYLE_SMALLTILE: demand in small (typically 64x64 pixel) tiles
|
||||
* @VIPS_DEMAND_STYLE_FATSTRIP: demand in fat (typically 10 pixel high) strips
|
||||
* @VIPS_DEMAND_STYLE_THINSTRIP: demand in thin (typically 1 pixel high) strips
|
||||
* @VIPS_DEMAND_STYLE_ANY: demand geometry does not matter
|
||||
*
|
||||
* See vips_demand_hint(). Operations can hint to the VIPS image IO system about
|
||||
* the kind of demand geometry they prefer.
|
||||
*
|
||||
* These demand styles are given below in order of increasing
|
||||
* restrictiveness. When demanding output from a pipeline,
|
||||
* vips_image_generate()
|
||||
* will use the most restrictive of the styles requested by the operations
|
||||
* in the pipeline.
|
||||
*
|
||||
* #VIPS_DEMAND_STYLE_THINSTRIP --- This operation would like to output strips
|
||||
* the width of the image and a few pels high. This is option suitable for
|
||||
* point-to-point operations, such as those in the arithmetic package.
|
||||
*
|
||||
* This option is only efficient for cases where each output pel depends
|
||||
* upon the pel in the corresponding position in the input image.
|
||||
*
|
||||
* #VIPS_DEMAND_STYLE_FATSTRIP --- This operation would like to output strips
|
||||
* the width of the image and as high as possible. This option is suitable
|
||||
* for area operations which do not violently transform coordinates, such
|
||||
* as im_conv().
|
||||
*
|
||||
* #VIPS_DEMAND_STYLE_SMALLTILE --- This is the most general demand format.
|
||||
* Output is demanded in small (around 100x100 pel) sections. This style works
|
||||
* reasonably efficiently, even for bizzare operations like 45 degree rotate.
|
||||
*
|
||||
* #VIPS_DEMAND_STYLE_ANY --- This image is not being demand-read from a disc
|
||||
* file (even indirectly) so any demand style is OK. It's used for things like
|
||||
* im_black() where the pixels are calculated.
|
||||
*
|
||||
* See also: vips_demand_hint().
|
||||
*/
|
||||
|
||||
/**
|
||||
* VipsInterpretation:
|
||||
* @VIPS_INTERPRETATION_MULTIBAND: generic many-band image
|
||||
* @VIPS_INTERPRETATION_B_W: some kind of single-band image
|
||||
* @VIPS_INTERPRETATION_HISTOGRAM: a 1D image, eg. histogram or lookup table
|
||||
* @VIPS_INTERPRETATION_FOURIER: image is in fourier space
|
||||
* @VIPS_INTERPRETATION_XYZ: the first three bands are CIE XYZ
|
||||
* @VIPS_INTERPRETATION_LAB: pixels are in CIE Lab space
|
||||
* @VIPS_INTERPRETATION_CMYK: the first four bands are in CMYK space
|
||||
* @VIPS_INTERPRETATION_LABQ: implies #VIPS_CODING_LABQ
|
||||
* @VIPS_INTERPRETATION_RGB: generic RGB space
|
||||
* @VIPS_INTERPRETATION_CMC: a uniform colourspace based on CMC(1:1)
|
||||
* @VIPS_INTERPRETATION_LCH: pixels are in CIE LCh space
|
||||
* @VIPS_INTERPRETATION_LABS: CIE LAB coded as three signed 16-bit values
|
||||
* @VIPS_INTERPRETATION_sRGB: pixels are sRGB
|
||||
* @VIPS_INTERPRETATION_scRGB: pixels are scRGB
|
||||
* @VIPS_INTERPRETATION_YXY: pixels are CIE Yxy
|
||||
* @VIPS_INTERPRETATION_RGB16: generic 16-bit RGB
|
||||
* @VIPS_INTERPRETATION_GREY16: generic 16-bit mono
|
||||
* @VIPS_INTERPRETATION_MATRIX: a matrix
|
||||
*
|
||||
* How the values in an image should be interpreted. For example, a
|
||||
* three-band float image of type #VIPS_INTERPRETATION_LAB should have its
|
||||
* pixels interpreted as coordinates in CIE Lab space.
|
||||
*
|
||||
* These values are set by operations as hints to user-interfaces built on top
|
||||
* of VIPS to help them show images to the user in a meaningful way.
|
||||
* Operations do not use these values to decide their action.
|
||||
*
|
||||
* The gaps in the numbering are historical and must be maintained. Allocate
|
||||
* new numbers from the end.
|
||||
*/
|
||||
|
||||
/**
|
||||
* VipsBandFormat:
|
||||
* @VIPS_FORMAT_NOTSET: invalid setting
|
||||
* @VIPS_FORMAT_UCHAR: unsigned char format
|
||||
* @VIPS_FORMAT_CHAR: char format
|
||||
* @VIPS_FORMAT_USHORT: unsigned short format
|
||||
* @VIPS_FORMAT_SHORT: short format
|
||||
* @VIPS_FORMAT_UINT: unsigned int format
|
||||
* @VIPS_FORMAT_INT: int format
|
||||
* @VIPS_FORMAT_FLOAT: float format
|
||||
* @VIPS_FORMAT_COMPLEX: complex (two floats) format
|
||||
* @VIPS_FORMAT_DOUBLE: double float format
|
||||
* @VIPS_FORMAT_DPCOMPLEX: double complex (two double) format
|
||||
*
|
||||
* The format used for each band element.
|
||||
*
|
||||
* Each corresponnds to a native C type for the current machine. For example,
|
||||
* #VIPS_FORMAT_USHORT is <type>unsigned short</type>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* VipsCoding:
|
||||
* @VIPS_CODING_NONE: pixels are not coded
|
||||
* @VIPS_CODING_LABQ: pixels encode 3 float CIELAB values as 4 uchar
|
||||
* @VIPS_CODING_RAD: pixels encode 3 float RGB as 4 uchar (Radiance coding)
|
||||
*
|
||||
* How pixels are coded.
|
||||
*
|
||||
* Normally, pixels are uncoded and can be manipulated as you would expect.
|
||||
* However some file formats code pixels for compression, and sometimes it's
|
||||
* useful to be able to manipulate images in the coded format.
|
||||
*
|
||||
* The gaps in the numbering are historical and must be maintained. Allocate
|
||||
* new numbers from the end.
|
||||
*/
|
||||
|
||||
/**
|
||||
* VipsProgress:
|
||||
* @run: Time we have been running
|
||||
|
@ -1519,6 +1519,7 @@ vips_object_set_argument_from_string( VipsObject *object,
|
||||
if( g_type_is_a( otype, VIPS_TYPE_IMAGE ) ) {
|
||||
VipsImage *out;
|
||||
VipsOperationFlags flags;
|
||||
VipsAccess access;
|
||||
|
||||
flags = 0;
|
||||
if( VIPS_IS_OPERATION( object ) )
|
||||
@ -1533,17 +1534,17 @@ vips_object_set_argument_from_string( VipsObject *object,
|
||||
/* Read the filename. vips_foreign_load_options()
|
||||
* handles embedded options.
|
||||
*/
|
||||
if( flags & VIPS_OPERATION_SEQUENTIAL ) {
|
||||
if( vips_foreign_load_options( value, &out,
|
||||
"access", VIPS_FOREIGN_ACCESS_SEQUENTIAL,
|
||||
NULL ) )
|
||||
return( -1 );
|
||||
}
|
||||
else {
|
||||
if( vips_foreign_load_options( value, &out,
|
||||
NULL ) )
|
||||
return( -1 );
|
||||
}
|
||||
if( flags & VIPS_OPERATION_SEQUENTIAL_UNBUFFERED )
|
||||
access = VIPS_ACCESS_SEQUENTIAL_UNBUFFERED;
|
||||
else if( flags & VIPS_OPERATION_SEQUENTIAL )
|
||||
access = VIPS_ACCESS_SEQUENTIAL;
|
||||
else
|
||||
access = VIPS_ACCESS_RANDOM;
|
||||
|
||||
if( vips_foreign_load_options( value, &out,
|
||||
"access", access,
|
||||
NULL ) )
|
||||
return( -1 );
|
||||
|
||||
g_value_init( &gvalue, VIPS_TYPE_IMAGE );
|
||||
g_value_set_object( &gvalue, out );
|
||||
|
@ -65,6 +65,26 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* VipsOperationFlags:
|
||||
* @VIPS_OPERATION_NONE: no flags
|
||||
* @VIPS_OPERATION_SEQUENTIAL: can work sequentially
|
||||
* @VIPS_OPERATION_NOCACHE: must not be cached
|
||||
*
|
||||
* Flags we associate with an operation.
|
||||
*
|
||||
* @VIPS_OPERATION_SEQUENTIAL means that the operation works like vips_conv():
|
||||
* it can happily process images top-to-bottom with only small non-local
|
||||
* references.
|
||||
*
|
||||
* @VIPS_OPERATION_SEQUENTIAL_UNBUFFERED means that the operation works like
|
||||
* vips_copy(): it can happily process images top-to-bottom and makes no
|
||||
* non-local references.
|
||||
*
|
||||
* @VIPS_OPERATION_NOCACHE means that the operation must not be cached by
|
||||
* vips.
|
||||
*/
|
||||
|
||||
/* Abstract base class for operations.
|
||||
*/
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user