combin copy_fields and demand_hint

We had two API calls, vips_image_copy_fields() and vips_demand_hint().
They are now combined in the single vips_image_pipeline() call.

All operations are now slightly smaller and simpler.
This commit is contained in:
John Cupitt 2013-10-22 09:29:40 +01:00
parent 8299bea984
commit 12cf71a6a9
64 changed files with 256 additions and 299 deletions

View File

@ -3,6 +3,8 @@
- vips_init() now does some ABI compat checking, though this change requires
an ABI break
- add "interlace" option to vips_jpegsave()
- remove vips_image_copy_fields() and vips_demand_hint() and add
vips_image_pipeline() to do both jobs
18/10/13 started 7.36.3
- fix compiler warnings in ubuntu 13.10

15
TODO
View File

@ -1,11 +1,3 @@
- get rid of vips_image_copy_fields(out, in) ... very confusing
just have
vips_image_copy_fieldsv( out, in1, in2, .. NULL )
makes arg order clearer
- do conv and morph quickly as simple wrappers over the vips7 operations
- do much fancier profiling with timing on all locks saved in memory and
@ -24,6 +16,13 @@
combine the two into one call?
hist_find at least does not call demand_hint, same for all writeline output
operators I guess
how about
vips_image_pipelinev( out, hint, in1, ... )
- object construction is threadsafe, but class construction is not
https://github.com/jcupitt/libvips/issues/64

View File

@ -545,11 +545,9 @@ vips_arithmetic_build( VipsObject *object )
*/
arithmetic->ready = size;
if( vips_image_copy_fields_array( arithmetic->out,
arithmetic->ready ) )
if( vips_image_pipeline_array( arithmetic->out,
VIPS_DEMAND_STYLE_THINSTRIP, arithmetic->ready ) )
return( -1 );
vips_demand_hint_array( arithmetic->out,
VIPS_DEMAND_STYLE_THINSTRIP, arithmetic->ready );
arithmetic->out->Bands = arithmetic->ready[0]->Bands;
arithmetic->out->BandFmt =

View File

@ -150,7 +150,8 @@ vips_hist_find_build( VipsObject *object )
/* Make the output image.
*/
if( vips_image_copy_fields( hist_find->out, statistic->ready ) )
if( vips_image_pipelinev( hist_find->out,
VIPS_DEMAND_STYLE_ANY, statistic->ready, NULL ) )
return( -1 );
vips_image_init_fields( hist_find->out,
hist_find->hist->mx + 1, 1, hist_find->hist->bands,

View File

@ -163,7 +163,8 @@ vips_hist_find_indexed_build( VipsObject *object )
VIPS_UNREF( indexed->hist->reg );
if( vips_image_copy_fieldsv( indexed->out,
if( vips_image_pipelinev( indexed->out,
VIPS_DEMAND_STYLE_ANY,
statistic->ready, indexed->index_ready, NULL ) )
return( -1 );
vips_image_init_fields( indexed->out,

View File

@ -154,7 +154,8 @@ vips_hist_find_ndim_build( VipsObject *object )
build( object ) )
return( -1 );
if( vips_image_copy_fields( ndim->out, statistic->ready ) )
if( vips_image_pipelinev( ndim->out,
VIPS_DEMAND_STYLE_ANY, statistic->ready, NULL ) )
return( -1 );
vips_image_init_fields( ndim->out,
ndim->bins,

View File

@ -136,8 +136,10 @@ vips_profile_build( VipsObject *object )
/* Make the output image.
*/
if( vips_image_copy_fields( profile->columns, statistic->ready ) ||
vips_image_copy_fields( profile->rows, statistic->ready ) )
if( vips_image_pipelinev( profile->columns,
VIPS_DEMAND_STYLE_ANY, statistic->ready, NULL ) ||
vips_image_pipelinev( profile->rows,
VIPS_DEMAND_STYLE_ANY, statistic->ready, NULL ) )
return( -1 );
profile->columns->Ysize = 1;
profile->columns->BandFmt = VIPS_FORMAT_INT;

View File

@ -141,8 +141,10 @@ vips_project_build( VipsObject *object )
/* Make the output image.
*/
if( vips_image_copy_fields( project->columns, statistic->ready ) ||
vips_image_copy_fields( project->rows, statistic->ready ) )
if( vips_image_pipelinev( project->columns,
VIPS_DEMAND_STYLE_ANY, statistic->ready, NULL ) ||
vips_image_pipelinev( project->rows,
VIPS_DEMAND_STYLE_ANY, statistic->ready, NULL ) )
return( -1 );
project->columns->Ysize = 1;
project->columns->BandFmt =

View File

@ -320,10 +320,9 @@ vips_colour_build( VipsObject *object )
*/
g_assert( !colour->in[colour->n] );
if( vips_image_copy_fields_array( colour->out, colour->in ) )
if( vips_image_pipeline_array( colour->out,
VIPS_DEMAND_STYLE_THINSTRIP, colour->in ) )
return( -1 );
vips_demand_hint_array( colour->out,
VIPS_DEMAND_STYLE_THINSTRIP, colour->in );
colour->out->Coding = colour->coding;
colour->out->Type = colour->interpretation;
colour->out->BandFmt = colour->format;

View File

@ -147,10 +147,9 @@ vips_bandary_build( VipsObject *object )
return( -1 );
bandary->ready = size;
if( vips_image_copy_fields_array( conversion->out, bandary->ready ) )
if( vips_image_pipeline_array( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, bandary->ready ) )
return( -1 );
vips_demand_hint_array( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, bandary->ready );
conversion->out->Bands = bandary->out_bands;

View File

@ -441,10 +441,9 @@ vips_cast_build( VipsObject *object )
vips_image_pio_input( cast->in ) )
return( -1 );
if( vips_image_copy_fields( conversion->out, cast->in ) )
if( vips_image_pipelinev( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, cast->in, NULL ) )
return( -1 );
vips_demand_hint( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, cast->in, NULL );
conversion->out->BandFmt = cast->format;

View File

@ -250,10 +250,9 @@ vips_copy_build( VipsObject *object )
if( vips_image_pio_input( copy->in ) )
return( -1 );
if( vips_image_copy_fields( conversion->out, copy->in ) )
if( vips_image_pipelinev( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, copy->in, NULL ) )
return( -1 );
vips_demand_hint( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, copy->in, NULL );
/* Use props to adjust header fields.
*/

View File

@ -426,14 +426,12 @@ vips_embed_build( VipsObject *object )
case VIPS_EXTEND_WHITE:
case VIPS_EXTEND_BACKGROUND:
case VIPS_EXTEND_COPY:
if( vips_image_copy_fields( conversion->out, embed->in ) )
return( -1 );
/* embed is used in many places. We don't really care about
* geometry, so use ANY to avoid disturbing all pipelines.
*/
vips_demand_hint( conversion->out,
VIPS_DEMAND_STYLE_ANY, embed->in, NULL );
if( vips_image_pipelinev( conversion->out,
VIPS_DEMAND_STYLE_ANY, embed->in, NULL ) )
return( -1 );
conversion->out->Xsize = embed->width;
conversion->out->Ysize = embed->height;

View File

@ -155,10 +155,9 @@ vips_extract_area_build( VipsObject *object )
vips_check_coding_known( class->nickname, extract->in ) )
return( -1 );
if( vips_image_copy_fields( conversion->out, extract->in ) )
if( vips_image_pipelinev( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, extract->in, NULL ) )
return( -1 );
vips_demand_hint( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, extract->in, NULL );
conversion->out->Xsize = extract->width;
conversion->out->Ysize = extract->height;

View File

@ -316,10 +316,9 @@ vips_flatten_build( VipsObject *object )
vips_image_pio_input( flatten->in ) )
return( -1 );
if( vips_image_copy_fields( conversion->out, flatten->in ) )
if( vips_image_pipelinev( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, flatten->in, NULL ) )
return( -1 );
vips_demand_hint( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, flatten->in, NULL );
conversion->out->Bands -= 1;

View File

@ -198,10 +198,9 @@ vips_flip_build( VipsObject *object )
if( vips_image_pio_input( flip->in ) )
return( -1 );
if( vips_image_copy_fields( conversion->out, flip->in ) )
if( vips_image_pipelinev( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, flip->in, NULL ) )
return( -1 );
vips_demand_hint( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, flip->in, NULL );
if( flip->direction == VIPS_DIRECTION_HORIZONTAL ) {
generate_fn = vips_flip_horizontal_gen;

View File

@ -166,12 +166,11 @@ vips_grid_build( VipsObject *object )
return( -1 );
}
if( vips_image_copy_fields( conversion->out, grid->in ) )
return( -1 );
/* We can render small tiles with pointer copies.
*/
vips_demand_hint( conversion->out,
VIPS_DEMAND_STYLE_SMALLTILE, grid->in, NULL );
if( vips_image_pipelinev( conversion->out,
VIPS_DEMAND_STYLE_SMALLTILE, grid->in, NULL ) )
return( -1 );
conversion->out->Xsize = grid->in->Xsize * grid->across;
conversion->out->Ysize = grid->tile_height * grid->down;

View File

@ -442,10 +442,9 @@ vips_ifthenelse_build( VipsObject *object )
if( vips__formatalike_vec( size, format, 2 ) )
return( -1 );
if( vips_image_copy_fields_array( conversion->out, format ) )
if( vips_image_pipeline_array( conversion->out,
VIPS_DEMAND_STYLE_SMALLTILE, format ) )
return( -1 );
vips_demand_hint_array( conversion->out,
VIPS_DEMAND_STYLE_SMALLTILE, format );
if( vips_image_generate( conversion->out,
vips_start_many, generate_fn, vips_stop_many,

View File

@ -284,10 +284,9 @@ vips_insert_build( VipsObject *object )
insert->main_processed, insert->sub_processed, NULL )) )
return( -1 );
if( vips_image_copy_fields_array( conversion->out, arry ) )
if( vips_image_pipeline_array( conversion->out,
VIPS_DEMAND_STYLE_ANY, arry ) )
return( -1 );
vips_demand_hint_array( conversion->out,
VIPS_DEMAND_STYLE_ANY, arry );
/* Calculate geometry.
*/

View File

@ -201,10 +201,9 @@ vips_msb_build( VipsObject *object )
msb->in->BandFmt == VIPS_FORMAT_UCHAR )
return( vips_image_write( msb->in, conversion->out ) );
if( vips_image_copy_fields( conversion->out, msb->in ) )
if( vips_image_pipelinev( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, msb->in, NULL ) )
return( -1 );
vips_demand_hint( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, msb->in, NULL );
if( msb->band != -1 )
conversion->out->Bands = 1;

View File

@ -164,10 +164,9 @@ vips_recomb_build( VipsObject *object )
return( -1 );
recomb->coeff = t[0];
if( vips_image_copy_fields( conversion->out, recomb->in ) )
if( vips_image_pipelinev( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, recomb->in, NULL ) )
return( -1 );
vips_demand_hint( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, recomb->in, NULL );
conversion->out->Bands = recomb->m->Ysize;
if( vips_bandfmt_isint( recomb->in->BandFmt ) )

View File

@ -162,10 +162,9 @@ vips_replicate_build( VipsObject *object )
if( vips_image_pio_input( replicate->in ) )
return( -1 );
if( vips_image_copy_fields( conversion->out, replicate->in ) )
if( vips_image_pipelinev( conversion->out,
VIPS_DEMAND_STYLE_SMALLTILE, replicate->in, NULL ) )
return( -1 );
vips_demand_hint( conversion->out,
VIPS_DEMAND_STYLE_SMALLTILE, replicate->in, NULL );
conversion->out->Xsize *= replicate->across;
conversion->out->Ysize *= replicate->down;

View File

@ -294,13 +294,16 @@ vips_rot_build( VipsObject *object )
if( vips_image_pio_input( rot->in ) )
return( -1 );
if( vips_image_copy_fields( conversion->out, rot->in ) )
hint = rot->angle == VIPS_ANGLE_180 ?
VIPS_DEMAND_STYLE_THINSTRIP :
VIPS_DEMAND_STYLE_SMALLTILE;
if( vips_image_pipelinev( conversion->out, hint, rot->in, NULL ) )
return( -1 );
switch( rot->angle ) {
case VIPS_ANGLE_90:
generate_fn = vips_rot90_gen;
hint = VIPS_DEMAND_STYLE_SMALLTILE;
conversion->out->Xsize = rot->in->Ysize;
conversion->out->Ysize = rot->in->Xsize;
conversion->out->Xoffset = rot->in->Ysize;
@ -309,14 +312,12 @@ vips_rot_build( VipsObject *object )
case VIPS_ANGLE_180:
generate_fn = vips_rot180_gen;
hint = VIPS_DEMAND_STYLE_THINSTRIP;
conversion->out->Xoffset = rot->in->Xsize;
conversion->out->Yoffset = rot->in->Ysize;
break;
case VIPS_ANGLE_270:
generate_fn = vips_rot270_gen;
hint = VIPS_DEMAND_STYLE_SMALLTILE;
conversion->out->Xsize = rot->in->Ysize;
conversion->out->Ysize = rot->in->Xsize;
conversion->out->Xoffset = 0;
@ -331,8 +332,6 @@ vips_rot_build( VipsObject *object )
return( 0 );
}
vips_demand_hint( conversion->out, hint, rot->in, NULL );
if( vips_image_generate( conversion->out,
vips_start_one, generate_fn, vips_stop_one,
rot->in, rot ) )

View File

@ -113,7 +113,7 @@ vips_rot45_rot45( VipsImage *out, VipsImage *in )
g_assert( in->Xsize == in->Ysize );
g_assert( out->Xsize == out->Ysize );
g_assert( in->Xsize == out->Xsize );
g_assert( in->Xsize % 2 == 0 );
g_assert( in->Xsize % 2 == 1 );
/* Split the square into 8 triangles. Loop over the top-left one,
* reflect into the others.
@ -201,8 +201,10 @@ vips_rot45_build( VipsObject *object )
return( -1 );
t[0] = vips_image_new_buffer();
if( vips_image_copy_fields( t[0], rot45->in ) ||
vips_image_write_prepare( t[0] ) )
if( vips_image_pipelinev( t[0],
VIPS_DEMAND_STYLE_ANY, rot45->in, NULL ) )
return( -1 );
if( vips_image_write_prepare( t[0] ) )
return( -1 );
from = rot45->in;

View File

@ -273,10 +273,9 @@ vips_sequential_build( VipsObject *object )
vips_object_local( object, t );
if( vips_image_copy_fields( conversion->out, t ) )
if( vips_image_pipelinev( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, t, NULL ) )
return( -1 );
vips_demand_hint( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, t, NULL );
if( vips_image_generate( conversion->out,
vips_start_one, vips_sequential_generate, vips_stop_one,
t, sequential ) )

View File

@ -209,10 +209,14 @@ vips_subsample_build( VipsObject *object )
vips_check_coding_known( class->nickname, subsample->in ) )
return( -1 );
/* Set demand hints. We want THINSTRIP, as we will be demanding a
* large area of input for each output line.
*/
if( vips_image_pipelinev( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, subsample->in, NULL ) )
return( -1 );
/* Prepare output. Note: we round the output width down!
*/
if( vips_image_copy_fields( conversion->out, subsample->in ) )
return( -1 );
conversion->out->Xsize = subsample->in->Xsize / subsample->xfac;
conversion->out->Ysize = subsample->in->Ysize / subsample->yfac;
conversion->out->Xres = subsample->in->Xres / subsample->xfac;
@ -224,12 +228,6 @@ vips_subsample_build( VipsObject *object )
return( -1 );
}
/* Set demand hints. We want THINSTRIP, as we will be demanding a
* large area of input for each output line.
*/
vips_demand_hint( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, subsample->in, NULL );
/* Generate! If this is a very large shrink, then it's
* probably faster to do it a pixel at a time.
*/

View File

@ -740,10 +740,9 @@ vips_tile_cache_build( VipsObject *object )
if( vips_image_pio_input( block_cache->in ) )
return( -1 );
if( vips_image_copy_fields( conversion->out, block_cache->in ) )
if( vips_image_pipelinev( conversion->out,
VIPS_DEMAND_STYLE_SMALLTILE, block_cache->in, NULL ) )
return( -1 );
vips_demand_hint( conversion->out,
VIPS_DEMAND_STYLE_SMALLTILE, block_cache->in, NULL );
if( vips_image_generate( conversion->out,
vips_start_one, vips_tile_cache_gen, vips_stop_one,
@ -926,10 +925,9 @@ vips_line_cache_build( VipsObject *object )
if( vips_image_pio_input( block_cache->in ) )
return( -1 );
if( vips_image_copy_fields( conversion->out, block_cache->in ) )
if( vips_image_pipelinev( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, block_cache->in, NULL ) )
return( -1 );
vips_demand_hint( conversion->out,
VIPS_DEMAND_STYLE_THINSTRIP, block_cache->in, NULL );
if( vips_image_generate( conversion->out,
vips_start_one, vips_line_cache_gen, vips_stop_one,

View File

@ -349,13 +349,12 @@ vips_zoom_build( VipsObject *object )
vips_check_coding_known( class->nickname, zoom->in ) )
return( -1 );
if( vips_image_copy_fields( conversion->out, zoom->in ) )
return( -1 );
/* Set demand hints. THINSTRIP will prevent us from using
* vips_zoom_paint_whole() much ... so go for FATSTRIP.
*/
vips_demand_hint( conversion->out,
VIPS_DEMAND_STYLE_FATSTRIP, zoom->in, NULL );
if( vips_image_pipelinev( conversion->out,
VIPS_DEMAND_STYLE_FATSTRIP, zoom->in, NULL ) )
return( -1 );
conversion->out->Xsize = zoom->in->Xsize * zoom->xfac;
conversion->out->Ysize = zoom->in->Ysize * zoom->yfac;

View File

@ -100,7 +100,7 @@ vips_black_build( VipsObject *object )
black->bands == 1 ?
VIPS_INTERPRETATION_B_W : VIPS_INTERPRETATION_MULTIBAND,
1.0, 1.0 );
vips_demand_hint( create->out,
vips_image_pipelinev( create->out,
VIPS_DEMAND_STYLE_ANY, NULL );
if( vips_image_generate( create->out,

View File

@ -116,7 +116,7 @@ vips_gaussmat_build( VipsObject *object )
width, height, 1,
VIPS_FORMAT_DOUBLE, VIPS_CODING_NONE, VIPS_INTERPRETATION_B_W,
1.0, 1.0 );
vips_demand_hint( create->out,
vips_image_pipelinev( create->out,
VIPS_DEMAND_STYLE_ANY, NULL );
if( vips_image_write_prepare( create->out ) )
return( -1 );

View File

@ -131,7 +131,7 @@ vips_gaussnoise_build( VipsObject *object )
gaussnoise->width, gaussnoise->height, 1,
VIPS_FORMAT_FLOAT, VIPS_CODING_NONE,
VIPS_INTERPRETATION_B_W, 1.0, 1.0 );
vips_demand_hint( create->out,
vips_image_pipelinev( create->out,
VIPS_DEMAND_STYLE_ANY, NULL );
if( vips_image_generate( create->out,

View File

@ -116,7 +116,7 @@ vips_identity_build( VipsObject *object )
VIPS_CODING_NONE, VIPS_INTERPRETATION_HISTOGRAM,
1.0, 1.0 );
vips_demand_hint( create->out,
vips_image_pipelinev( create->out,
VIPS_DEMAND_STYLE_ANY, NULL );
if( vips_image_generate( create->out,

View File

@ -138,7 +138,7 @@ vips_logmat_build( VipsObject *object )
width, height, 1,
VIPS_FORMAT_DOUBLE, VIPS_CODING_NONE, VIPS_INTERPRETATION_B_W,
1.0, 1.0 );
vips_demand_hint( create->out,
vips_image_pipelinev( create->out,
VIPS_DEMAND_STYLE_ANY, NULL );
if( vips_image_write_prepare( create->out ) )
return( -1 );

View File

@ -103,7 +103,7 @@ vips_point_build( VipsObject *object )
point->width, point->height, 1,
VIPS_FORMAT_FLOAT, VIPS_CODING_NONE, VIPS_INTERPRETATION_B_W,
1.0, 1.0 );
vips_demand_hint( t[0],
vips_image_pipelinev( t[0],
VIPS_DEMAND_STYLE_ANY, NULL );
if( vips_image_generate( t[0],
NULL, vips_point_gen, NULL, point, NULL ) )

View File

@ -233,7 +233,7 @@ vips_text_build( VipsObject *object )
text->bitmap.width, text->bitmap.rows, 1,
VIPS_FORMAT_UCHAR, VIPS_CODING_NONE, VIPS_INTERPRETATION_B_W,
1.0, 1.0 );
vips_demand_hint( create->out,
vips_image_pipelinev( create->out,
VIPS_DEMAND_STYLE_ANY, NULL );
for( y = 0; y < text->bitmap.rows; y++ )

View File

@ -163,7 +163,7 @@ vips_xyz_build( VipsObject *object )
VIPS_FORMAT_UINT, VIPS_CODING_NONE,
VIPS_INTERPRETATION_MULTIBAND,
1.0, 1.0 );
vips_demand_hint( create->out,
vips_image_pipelinev( create->out,
VIPS_DEMAND_STYLE_ANY, NULL );
if( vips_image_generate( create->out,

View File

@ -221,7 +221,7 @@ vips_image_open_lazy( VipsImage *image,
/* Then 'start' creates the real image and 'gen' paints 'image'
* with pixels from the real image on demand.
*/
vips_demand_hint( image, image->dhint, NULL );
vips_image_pipelinev( image, image->dhint, NULL );
if( vips_image_generate( image,
open_lazy_start, open_lazy_generate, vips_stop_one,
lazy, NULL ) )

View File

@ -486,7 +486,7 @@ im_wrapmany( IMAGE **in, IMAGE *out, im_wrapmany_fn fn, void *a, void *b )
if( vips_image_pio_input( in[i] ) )
return( -1 );
}
vips_demand_hint_array( out, VIPS_DEMAND_STYLE_THINSTRIP, in );
vips_image_pipeline_array( out, VIPS_DEMAND_STYLE_THINSTRIP, in );
/* Generate!
*/
@ -959,7 +959,35 @@ im_demand_hint (IMAGE * im, VipsDemandStyle hint, ...)
return (-1);
}
return (im_demand_hint_array (im, hint, ar));
vips__demand_hint_array (im, hint, ar);
return (0);
}
int
im_cp_descv (IMAGE * im, ...)
{
va_list ap;
int i;
IMAGE *ar[MAX_IMAGES];
va_start (ap, im);
for (i = 0; i < MAX_IMAGES && (ar[i] = va_arg (ap, IMAGE *)); i++)
;
va_end (ap);
if (i == MAX_IMAGES)
{
im_error ("im_cp_descv", "%s", _("too many images"));
return (-1);
}
return (vips__image_copy_fields_array (im, ar));
}
int
im_cp_desc(IMAGE *out, IMAGE *in )
{
return( im_cp_descv( out, in, NULL));
}
int
@ -1925,7 +1953,7 @@ im_gauss_dmask_sep( const char *filename, double sigma, double min_ampl )
DOUBLEMASK *msk;
if( vips_gaussmat( &t, sigma, min_ampl,
"seperable", TRUE,
"separable", TRUE,
NULL ) )
return( NULL );
if( !(msk = im_vips2mask( t, filename )) ) {
@ -1964,7 +1992,7 @@ im_gauss_imask_sep( const char *filename, double sigma, double min_ampl )
if( vips_gaussmat( &t, sigma, min_ampl,
"integer", TRUE,
"seperable", TRUE,
"separable", TRUE,
NULL ) )
return( NULL );
if( !(msk = im_vips2imask( t, filename )) ) {

View File

@ -280,11 +280,11 @@ read_csv( FILE *fp, VipsImage *out,
fsetpos( fp, &pos );
}
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
vips_image_init_fields( out,
columns, lines, 1,
VIPS_FORMAT_DOUBLE,
VIPS_CODING_NONE, VIPS_INTERPRETATION_B_W, 1.0, 1.0 );
vips_demand_hint( out, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
/* Just reading the header? We are done.
*/

View File

@ -263,7 +263,8 @@ pyramid_build( VipsForeignSaveDz *dz, Layer *above,
* easy.
*/
layer->image = vips_image_new();
if( vips_image_copy_fields( layer->image, save->ready ) ) {
if( vips_image_pipelinev( layer->image,
VIPS_DEMAND_STYLE_ANY, save->ready, NULL ) ) {
layer_free( layer );
return( NULL );
}

View File

@ -296,11 +296,11 @@ vips_fits_get_header( VipsFits *fits, VipsImage *out )
else
type = VIPS_INTERPRETATION_MULTIBAND;
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_SMALLTILE, NULL );
vips_image_init_fields( out,
width, height, bands,
format,
VIPS_CODING_NONE, type, 1.0, 1.0 );
vips_demand_hint( out, VIPS_DEMAND_STYLE_SMALLTILE, NULL );
/* Read all keys into meta.
*/

View File

@ -776,7 +776,7 @@ vips_foreign_load_start( VipsImage *out, void *a, void *b )
/* We have to tell vips that out depends on real. We've set
* the demand hint below, but not given an input there.
*/
vips_demand_hint( load->out, load->out->dhint,
vips_image_pipelinev( load->out, load->out->dhint,
load->real, NULL );
}
@ -874,7 +874,7 @@ vips_foreign_load_build( VipsObject *object )
/* ->header() should set the dhint. It'll default to the safe
* SMALLTILE if header() did not set it.
*/
vips_demand_hint( load->out, load->out->dhint, NULL );
vips_image_pipelinev( load->out, load->out->dhint, NULL );
/* Then 'start' creates the real image and 'gen' fetches
* pixels for @out from @real on demand.

View File

@ -764,7 +764,7 @@ read_jpeg_header( ReadJpeg *jpeg, VipsImage *out )
interpretation,
xres, yres );
vips_demand_hint( out, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
/* Interlaced jpegs need lots of memory to read, so our caller needs
* to know.

View File

@ -337,7 +337,7 @@ parse_header( Read *read )
*/
im->Coding = VIPS_CODING_NONE;
vips_demand_hint( im, VIPS_DEMAND_STYLE_SMALLTILE, NULL );
vips_image_pipelinev( im, VIPS_DEMAND_STYLE_SMALLTILE, NULL );
/* Three ways to loop over attributes / properties :-(
*/

View File

@ -212,9 +212,9 @@ read_header( Read *read, VipsImage *out )
VIPS_FORMAT_FLOAT,
VIPS_CODING_NONE, VIPS_INTERPRETATION_sRGB, 1.0, 1.0 );
if( read->tiles )
vips_demand_hint( out, VIPS_DEMAND_STYLE_SMALLTILE, NULL );
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_SMALLTILE, NULL );
else
vips_demand_hint( out, VIPS_DEMAND_STYLE_FATSTRIP, NULL );
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_FATSTRIP, NULL );
}
int

View File

@ -220,7 +220,7 @@ readslide_new( const char *filename, VipsImage *out,
associated, &w, &h );
vips_image_set_string( out, "slide-associated-image",
associated );
vips_demand_hint( out, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
}
else {
char buf[256];
@ -231,7 +231,7 @@ readslide_new( const char *filename, VipsImage *out,
rslide->downsample = openslide_get_level_downsample(
rslide->osr, level );
vips_image_set_int( out, "slide-level", level );
vips_demand_hint( out, VIPS_DEMAND_STYLE_SMALLTILE, NULL );
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_SMALLTILE, NULL );
/* Try to get tile width/height. An undocumented, experimental
* feature.

View File

@ -1236,7 +1236,7 @@ read_tilewise( ReadTiff *rtiff, VipsImage *out )
* the cache we are quite happy serving that if anything downstream
* would like it.
*/
vips_demand_hint( raw, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
vips_image_pipelinev( raw, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
if( vips_image_generate( raw,
tiff_seq_start, tiff_fill_region, tiff_seq_stop,
@ -1413,7 +1413,7 @@ read_stripwise( ReadTiff *rtiff, VipsImage *out )
if( parse_header( rtiff, t[0] ) )
return( -1 );
vips_demand_hint( t[0], VIPS_DEMAND_STYLE_THINSTRIP, NULL );
vips_image_pipelinev( t[0], VIPS_DEMAND_STYLE_THINSTRIP, NULL );
if( !tfget32( rtiff->tiff,
TIFFTAG_ROWSPERSTRIP, &rtiff->rows_per_strip ) )

View File

@ -351,7 +351,7 @@ png2vips_header( Read *read, VipsImage *out )
/* Sequential mode needs thinstrip to work with things like
* vips_shrink().
*/
vips_demand_hint( out, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
/* Fetch the ICC profile. @name is useless, something like "icc" or
* "ICC Profile" etc. Ignore it.

View File

@ -153,7 +153,7 @@ read_header( Read *read, VipsImage *out )
VIPS_INTERPRETATION_sRGB,
1.0, 1.0 );
vips_demand_hint( out, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
return( 0 );
}

View File

@ -256,16 +256,14 @@ vips_hist_local_build( VipsObject *object )
g_object_set( object, "out", vips_image_new(), NULL );
if( vips_image_copy_fields( local->out, in ) )
return( -1 );
local->out->Xsize -= local->width - 1;
local->out->Ysize -= local->height - 1;
/* Set demand hints. FATSTRIP is good for us, as THINSTRIP will cause
* too many recalculations on overlaps.
*/
vips_demand_hint( local->out,
VIPS_DEMAND_STYLE_FATSTRIP, in, NULL );
if( vips_image_pipelinev( local->out,
VIPS_DEMAND_STYLE_FATSTRIP, in, NULL ) )
return( -1 );
local->out->Xsize -= local->width - 1;
local->out->Ysize -= local->height - 1;
if( vips_image_generate( local->out,
vips_hist_local_start,

View File

@ -157,10 +157,9 @@ vips_histogram_build( VipsObject *object )
*/
histogram->ready = size;
if( vips_image_copy_fields_array( histogram->out, histogram->ready ) )
if( vips_image_pipeline_array( histogram->out,
VIPS_DEMAND_STYLE_THINSTRIP, histogram->ready ) )
return( -1 );
vips_demand_hint_array( histogram->out,
VIPS_DEMAND_STYLE_THINSTRIP, histogram->ready );
histogram->out->Xsize = VIPS_IMAGE_N_PELS( histogram->ready[0] );
histogram->out->Ysize = 1;

View File

@ -564,10 +564,9 @@ vips_maplut_build( VipsObject *object )
vips_image_pio_input( in ) )
return( -1 );
if( vips_image_copy_fieldsv( maplut->out, in, lut, NULL ) )
if( vips_image_pipelinev( maplut->out,
VIPS_DEMAND_STYLE_THINSTRIP, in, lut, NULL ) )
return( -1 );
vips_demand_hint( maplut->out, VIPS_DEMAND_STYLE_THINSTRIP,
in, lut, NULL );
maplut->out->BandFmt = lut->BandFmt;
/* Output has same number of bands as LUT, unless LUT has 1 band, in

View File

@ -249,16 +249,14 @@ vips_stdif_build( VipsObject *object )
g_object_set( object, "out", vips_image_new(), NULL );
if( vips_image_copy_fields( stdif->out, in ) )
return( -1 );
stdif->out->Xsize -= stdif->width - 1;
stdif->out->Ysize -= stdif->height - 1;
/* Set demand hints. FATSTRIP is good for us, as THINSTRIP will cause
* too many recalculations on overlaps.
*/
vips_demand_hint( stdif->out,
VIPS_DEMAND_STYLE_FATSTRIP, in, NULL );
if( vips_image_pipelinev( stdif->out,
VIPS_DEMAND_STYLE_FATSTRIP, in, NULL ) )
return( -1 );
stdif->out->Xsize -= stdif->width - 1;
stdif->out->Ysize -= stdif->height - 1;
if( vips_image_generate( stdif->out,
vips_start_one,

View File

@ -73,9 +73,9 @@ int vips_image_generate( VipsImage *im,
void *a, void *b
);
void vips_demand_hint_array( VipsImage *image,
int vips_image_pipeline_array( VipsImage *image,
VipsDemandStyle hint, VipsImage **in );
void vips_demand_hint( VipsImage *image, VipsDemandStyle hint, ... )
int vips_image_pipelinev( VipsImage *image, VipsDemandStyle hint, ... )
__attribute__((sentinel));
#ifdef __cplusplus

View File

@ -118,11 +118,6 @@ void vips_image_init_fields( VipsImage *image,
VipsInterpretation interpretation,
double xres, double yres );
int vips_image_copy_fields_array( VipsImage *out, VipsImage *in[] );
int vips_image_copy_fieldsv( VipsImage *out, VipsImage *in1, ... )
__attribute__((sentinel));
int vips_image_copy_fields( VipsImage *out, VipsImage *in );
void vips_image_set( VipsImage *image, const char *field, GValue *value );
int vips_image_get( const VipsImage *image,
const char *field, GValue *value_copy );

View File

@ -170,6 +170,11 @@ VipsArgumentInstance *vips__argument_get_instance(
VipsArgument *vips__argument_table_lookup( VipsArgumentTable *table,
GParamSpec *pspec);
void vips__demand_hint_array( struct _VipsImage *image,
int hint, struct _VipsImage **in );
int vips__image_copy_fields_array( struct _VipsImage *out,
struct _VipsImage *in[] );
#ifdef __cplusplus
}
#endif /*__cplusplus*/

View File

@ -208,9 +208,12 @@ extern "C" {
#define im_guess_libdir vips_guess_libdir
#define im__global_lock vips__global_lock
#define im_cp_desc vips_image_copy_fields
#define im_cp_descv vips_image_copy_fieldsv
#define im_cp_desc_array vips_image_copy_fields_array
int im_cp_desc(IMAGE *out, IMAGE *in );
int im_cp_descv (IMAGE * im, ...);
#define im_cp_desc_array(I, A) vips__image_copy_fields_array(I, A)
int im_demand_hint (IMAGE * im, VipsDemandStyle hint, ...);
#define im_demand_hint_array( A, B, C ) (vips__demand_hint_array( A, B, C ), 0)
#define im_image vips_image_new_from_memory
#define im_binfile vips_image_new_from_file_raw
#define im__open_temp vips_image_new_temp_file
@ -324,9 +327,6 @@ VipsDemandStyle im_char2dhint( const char *str );
#define im_rect_dup vips_rect_dup
#define im_rect_normalise vips_rect_normalise
int im_demand_hint (IMAGE * im, VipsDemandStyle hint, ...);
#define im_demand_hint_array( A, B, C ) (vips_demand_hint_array( A, B, C ), 0)
#define im_start_one vips_start_one
#define im_stop_one vips_stop_one
#define im_start_many vips_start_many

View File

@ -274,26 +274,12 @@ vips__link_map( VipsImage *image, gboolean upstream,
return( result );
}
/**
* vips_demand_hint_array:
* @image: image to set hint for
* @hint: hint for this image
* @in: array of input images to this operation
*
* Operations can set demand hints, that is, hints to the VIPS IO system about
* the type of region geometry this operation works best with. For example,
* operations which transform coordinates will usually work best with
* %VIPS_DEMAND_STYLE_SMALLTILE, operations which work on local windows of
* pixels will like %VIPS_DEMAND_STYLE_FATSTRIP.
*
* VIPS uses the list of input images to build the tree of operations it needs
* for the cache invalidation system. You have to call this function, or its
* varargs friend vips_demand_hint().
*
* See also: vips_demand_hint(), vips_image_generate().
/* We have to have this as a separate entry point so we can support the old
* vips7 API.
*/
void
vips_demand_hint_array( VipsImage *image, VipsDemandStyle hint, VipsImage **in )
vips__demand_hint_array( VipsImage *image,
VipsDemandStyle hint, VipsImage **in )
{
int i, len, nany;
VipsDemandStyle set_hint;
@ -327,7 +313,7 @@ vips_demand_hint_array( VipsImage *image, VipsDemandStyle hint, VipsImage **in )
image->dhint = set_hint;
#ifdef DEBUG
printf( "vips_demand_hint_array: set dhint for \"%s\" to %s\n",
printf( "vips_image_pipeline_array: set dhint for \"%s\" to %s\n",
image->filename,
vips_enum_nick( VIPS_TYPE_DEMAND_STYLE, image->dhint ) );
printf( "\toperation requested %s\n",
@ -354,17 +340,62 @@ vips_demand_hint_array( VipsImage *image, VipsDemandStyle hint, VipsImage **in )
}
/**
* vips_demand_hint:
* @image: image to set hint for
* @hint: hint for this image
* @Varargs: %NULL-terminated list of input images to this operation
* vips_image_pipeline_array:
* @image: output image
* @hint: demand hint for @image
* @in: %NULL-terminated array of input images
*
* Build an array and call vips_demand_hint_array().
* Add an image to a pipeline. @image depends on all of the images in @in,
* @image prefers to supply pixels according to @hint.
*
* See also: vips_demand_hint(), vips_image_generate().
* Operations can set demand hints, that is, hints to the VIPS IO system about
* the type of region geometry this operation works best with. For example,
* operations which transform coordinates will usually work best with
* %VIPS_DEMAND_STYLE_SMALLTILE, operations which work on local windows of
* pixels will like %VIPS_DEMAND_STYLE_FATSTRIP.
*
* Header fields in @image are set from the fields in @in, with lower-numbered
* images in @in taking priority.
* For example, if @in[0] and @in[1] both have an item
* called "icc-profile", it's the profile attached to @in[0] that will end up
* on @image.
* Image history is completely copied from all @in. @image will have the history
* of all the input images.
* The array of input images can be empty, meaning @image is at the start of a
* pipeline.
*
* VIPS uses the list of input images to build the tree of operations it needs
* for the cache invalidation system.
*
* See also: vips_image_pipelinev(), vips_image_generate().
*
* Returns: 0 on success, -1 on error.
*/
void
vips_demand_hint( VipsImage *image, VipsDemandStyle hint, ... )
int
vips_image_pipeline_array( VipsImage *image,
VipsDemandStyle hint, VipsImage **in )
{
vips__demand_hint_array( image, hint, in );
if( in[0] &&
vips__image_copy_fields_array( image, in ) )
return( -1 );
return( 0 );
}
/**
* vips_image_pipelinev:
* @image: output image of pipeline
* @hint: hint for this image
* @...: %NULL-terminated list of input images
*
* Build an array and call vips_image_pipeline_array().
*
* See also: vips_image_generate().
*/
int
vips_image_pipelinev( VipsImage *image, VipsDemandStyle hint, ... )
{
va_list ap;
int i;
@ -376,14 +407,14 @@ vips_demand_hint( VipsImage *image, VipsDemandStyle hint, ... )
;
va_end( ap );
if( i == MAX_IMAGES ) {
vips_warn( "vips_demand_hint", "%s", _( "too many images" ) );
vips_warn( "vips_image_pipeline", "%s", _( "too many images" ) );
/* Make sure we have a sentinel there.
*/
ar[i - 1] = NULL;
}
vips_demand_hint_array( image, hint, ar );
return( vips_image_pipeline_array( image, hint, ar ) );
}
/**

View File

@ -604,13 +604,13 @@ vips_image_get_data( VipsImage *image )
* @yres: vertical resolution, pixels per millimetre
*
* A convenience function to set the header fields after creating an image.
* Normally you copy the fields from one of your input images with
* vips_image_copy_fields() and then make
* Normally you copy the fields from your input images with
* vips_image_pipelinev() and then make
* any adjustments you need, but if you are creating an image from scratch,
* for example im_black() or im_jpeg2vips(), you do need to set all the
* fields yourself.
*
* See also: vips_image_copy_fields().
* See also: vips_image_pipelinev().
*/
void
vips_image_init_fields( VipsImage *image,
@ -655,7 +655,7 @@ meta_cp_field( VipsMeta *meta, VipsImage *dst )
return( NULL );
}
/* Copy meta on to dst. Called from vips_cp_desc().
/* Copy meta on to dst.
*/
static int
meta_cp( VipsImage *dst, const VipsImage *src )
@ -671,31 +671,11 @@ meta_cp( VipsImage *dst, const VipsImage *src )
return( 0 );
}
/**
* vips_image_copy_fields_array:
* @out: image to copy to
* @in: %NULL-terminated array of images to copy from
*
* Copy fields from all the input images to the output image. There must be at
* least one input image.
*
* The first input image is used to set the main fields of @out (@width,
* @coding and so on).
*
* Metadata from all the images is merged on to @out, with lower-numbered items
* overriding higher. So for example, if @in[0] and @in[1] both have an item
* called "icc-profile", it's the profile attached to @in[0] that will end up
* on @out.
*
* Image history is completely copied from all @in. @out will have the history
* of all the input images.
*
* See also: vips_image_copy_fieldsv(), vips_image_copy_fields().
*
* Returns: 0 on success, -1 on error.
/* We have to have this as a separate entry point so we can support the old
* vips7 API.
*/
int
vips_image_copy_fields_array( VipsImage *out, VipsImage *in[] )
vips__image_copy_fields_array( VipsImage *out, VipsImage *in[] )
{
int i;
int ni;
@ -740,63 +720,6 @@ vips_image_copy_fields_array( VipsImage *out, VipsImage *in[] )
return( 0 );
}
/* Max number of images we can handle.
*/
#define MAX_IMAGES (1000)
/**
* vips_image_copy_fieldsv:
* @out: image to copy to
* @in1: first image to copy from
* @Varargs: %NULL-terminated list of images to copy from
*
* Copy fields from all the input images to the output image. A convenience
* function over vips_image_copy_fields_array().
*
* See also: vips_image_copy_fields_array(), vips_image_copy_fields().
*
* Returns: 0 on success, -1 on error.
*/
int
vips_image_copy_fieldsv( VipsImage *out, VipsImage *in1, ... )
{
va_list ap;
int i;
VipsImage *in[MAX_IMAGES];
in[0] = in1;
va_start( ap, in1 );
for( i = 1; i < MAX_IMAGES &&
(in[i] = va_arg( ap, VipsImage * )); i++ )
;
va_end( ap );
if( i == MAX_IMAGES ) {
vips_error( "vips_image_copy_fieldsv",
"%s", _( "too many images" ) );
return( -1 );
}
return( vips_image_copy_fields_array( out, in ) );
}
/**
* vips_image_copy_fields:
* @out: image to copy to
* @in: image to copy from
*
* Copy fields from @in to @out. A convenience
* function over vips_image_copy_fields_array().
*
* See also: vips_image_copy_fields_array(), vips_image_copy_fieldsv().
*
* Returns: 0 on success, -1 on error.
*/
int
vips_image_copy_fields( VipsImage *out, VipsImage *in )
{
return( vips_image_copy_fieldsv( out, in, NULL ) );
}
/**
* vips_image_set:
* @image: image to set the metadata on

View File

@ -105,7 +105,7 @@
* @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
* See vips_image_pipelinev(). 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
@ -134,7 +134,7 @@
* 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().
* See also: vips_image_pipelinev().
*/
/**
@ -1939,10 +1939,9 @@ int
vips_image_write( VipsImage *image, VipsImage *out )
{
if( vips_image_pio_input( image ) ||
vips_image_copy_fields( out, image ) )
vips_image_pipelinev( out,
VIPS_DEMAND_STYLE_THINSTRIP, image, NULL ) )
return( -1 );
vips_demand_hint( out,
VIPS_DEMAND_STYLE_THINSTRIP, image, NULL );
/* We generate from @image partially, so we need to keep it about as
* long as @out is about.

View File

@ -1067,14 +1067,14 @@ vips_sink_screen( VipsImage *in, VipsImage *out, VipsImage *mask,
}
if( vips_image_pio_input( in ) ||
vips_image_copy_fields( out, in ) )
vips_image_pipelinev( out,
VIPS_DEMAND_STYLE_SMALLTILE, in, NULL ) )
return( -1 );
vips_demand_hint( out, VIPS_DEMAND_STYLE_SMALLTILE, in, NULL );
if( mask ) {
if( vips_image_copy_fields( mask, in ) )
if( vips_image_pipelinev( mask,
VIPS_DEMAND_STYLE_SMALLTILE, in, NULL ) )
return( -1 );
vips_demand_hint( mask, VIPS_DEMAND_STYLE_SMALLTILE, in, NULL );
mask->Bands = 1;
mask->BandFmt = VIPS_FORMAT_UCHAR;

View File

@ -381,6 +381,7 @@ vips_affine_build( VipsObject *object )
VipsImage *in;
gboolean repack;
VipsDemandStyle hint;
int window_size;
int window_offset;
double edge;
@ -479,21 +480,19 @@ vips_affine_build( VipsObject *object )
return( -1 );
in = t[1];
if( vips_image_copy_fields( resample->out, in ) )
return( -1 );
resample->out->Xsize = affine->trn.oarea.width;
resample->out->Ysize = affine->trn.oarea.height;
/* Normally SMALLTILE ... except if this is a size up/down affine.
*/
if( affine->trn.b == 0.0 &&
affine->trn.c == 0.0 )
vips_demand_hint( resample->out,
VIPS_DEMAND_STYLE_FATSTRIP, in, NULL );
hint = VIPS_DEMAND_STYLE_FATSTRIP;
else
vips_demand_hint( resample->out,
VIPS_DEMAND_STYLE_SMALLTILE, in, NULL );
hint = VIPS_DEMAND_STYLE_SMALLTILE;
if( vips_image_pipelinev( resample->out, hint, in, NULL ) )
return( -1 );
resample->out->Xsize = affine->trn.oarea.width;
resample->out->Ysize = affine->trn.oarea.height;
/* Generate!
*/

View File

@ -251,7 +251,11 @@ vips_quadratic_build( VipsObject *object )
if( VIPS_OBJECT_CLASS( vips_quadratic_parent_class )->build( object ) )
return( -1 );
if( vips_image_copy_fields( resample->out, resample->in ) )
/* We have the whole of the input in memory, so we can generate any
* output.
*/
if( vips_image_pipelinev( resample->out,
VIPS_DEMAND_STYLE_ANY, resample->in, NULL ) )
return( -1 );
in = resample->in;
@ -315,12 +319,6 @@ vips_quadratic_build( VipsObject *object )
if( vips_image_wio_input( in ) )
return( -1 );
/* We have the whole of the input in memory, so we can generate any
* output.
*/
vips_demand_hint( resample->out,
VIPS_DEMAND_STYLE_ANY, resample->in, NULL );
if( vips_image_generate( resample->out,
vips_start_one, vips_quadratic_gen, vips_stop_one,
in, quadratic ) )

View File

@ -336,15 +336,13 @@ vips_shrink_build( VipsObject *object )
shrink->yshrink == 1.0 )
return( vips_image_write( resample->in, resample->out ) );
if( vips_image_copy_fields( resample->out, resample->in ) )
return( -1 );
/* THINSTRIP will work, anything else will break seq mode. If you
* combine shrink with conv you'll need to use a line cache to maintain
* sequentiality.
*/
vips_demand_hint( resample->out,
VIPS_DEMAND_STYLE_THINSTRIP, resample->in, NULL );
if( vips_image_pipelinev( resample->out,
VIPS_DEMAND_STYLE_THINSTRIP, resample->in, NULL ) )
return( -1 );
/* Size output. Note: we round the output width down!
*