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:
parent
8299bea984
commit
12cf71a6a9
@ -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
15
TODO
@ -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
|
||||
|
@ -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 =
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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 =
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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 ) )
|
||||
|
@ -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;
|
||||
|
@ -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 ) )
|
||||
|
@ -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;
|
||||
|
@ -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 ) )
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 );
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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 );
|
||||
|
@ -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 ) )
|
||||
|
@ -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++ )
|
||||
|
@ -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,
|
||||
|
@ -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 ) )
|
||||
|
@ -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 )) ) {
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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 :-(
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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 ) )
|
||||
|
@ -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.
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
|
@ -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*/
|
||||
|
@ -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
|
||||
|
@ -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 ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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!
|
||||
*/
|
||||
|
@ -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 ) )
|
||||
|
@ -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!
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user