fix sizing issues with new reduce code

a couple of bugs and some changed conventions
This commit is contained in:
John Cupitt 2016-03-13 17:44:24 +00:00
parent f12fef4aa9
commit fba2ac2f85
5 changed files with 16 additions and 19 deletions

2
TODO
View File

@ -9,6 +9,8 @@
displacement error, I guess? displacement error, I guess?
yes, reduceh output should move one to the right
- need more tests for reduce, test every kernel plus every numeric type - need more tests for reduce, test every kernel plus every numeric type
- try orc version of reducev? and shrinkv? maybe shrinkh? - try orc version of reducev? and shrinkv? maybe shrinkh?

View File

@ -496,7 +496,7 @@ vips_reduceh_build( VipsObject *object )
/* Add new pixels around the input so we can interpolate at the edges. /* Add new pixels around the input so we can interpolate at the edges.
*/ */
if( vips_embed( in, &t[1], if( vips_embed( in, &t[1],
reduceh->n_points / 2, 0, reduceh->n_points / 2 - 1, 0,
in->Xsize + reduceh->n_points - 1, in->Ysize, in->Xsize + reduceh->n_points - 1, in->Ysize,
"extend", VIPS_EXTEND_COPY, "extend", VIPS_EXTEND_COPY,
NULL ) ) NULL ) )
@ -507,14 +507,14 @@ vips_reduceh_build( VipsObject *object )
VIPS_DEMAND_STYLE_THINSTRIP, in, NULL ) ) VIPS_DEMAND_STYLE_THINSTRIP, in, NULL ) )
return( -1 ); return( -1 );
/* Size output. Note: we round the output width down! /* Size output. Note: we round to nearest to hide rounding errors.
* *
* Don't change xres/yres, leave that to the application layer. For * Don't change xres/yres, leave that to the application layer. For
* example, vipsthumbnail knows the true reduce factor (including the * example, vipsthumbnail knows the true reduce factor (including the
* fractional part), we just see the integer part here. * fractional part), we just see the integer part here.
*/ */
resample->out->Xsize = (in->Xsize - reduceh->n_points + 1) / resample->out->Xsize = VIPS_RINT(
reduceh->xshrink; (in->Xsize - reduceh->n_points + 1) / reduceh->xshrink );
if( resample->out->Xsize <= 0 ) { if( resample->out->Xsize <= 0 ) {
vips_error( object_class->nickname, vips_error( object_class->nickname,
"%s", _( "image has shrunk to nothing" ) ); "%s", _( "image has shrunk to nothing" ) );

View File

@ -411,7 +411,7 @@ vips_reducev_build( VipsObject *object )
/* Add new pixels around the input so we can interpolate at the edges. /* Add new pixels around the input so we can interpolate at the edges.
*/ */
if( vips_embed( in, &t[1], if( vips_embed( in, &t[1],
0, reducev->n_points / 2, 0, reducev->n_points / 2 - 1,
in->Xsize, in->Ysize + reducev->n_points - 1, in->Xsize, in->Ysize + reducev->n_points - 1,
"extend", VIPS_EXTEND_COPY, "extend", VIPS_EXTEND_COPY,
NULL ) ) NULL ) )
@ -422,13 +422,14 @@ vips_reducev_build( VipsObject *object )
VIPS_DEMAND_STYLE_SMALLTILE, in, NULL ) ) VIPS_DEMAND_STYLE_SMALLTILE, in, NULL ) )
return( -1 ); return( -1 );
/* Size output. Note: we round the output width down! /* Size output. Note: we round to nearest to hide rounding errors.
* *
* Don't change xres/yres, leave that to the application layer. For * Don't change xres/yres, leave that to the application layer. For
* example, vipsthumbnail knows the true reduce factor (including the * example, vipsthumbnail knows the true reduce factor (including the
* fractional part), we just see the integer part here. * fractional part), we just see the integer part here.
*/ */
resample->out->Ysize = (in->Ysize - reducev->n_points + 1) / reducev->yshrink; resample->out->Ysize = VIPS_RINT(
(in->Ysize - reducev->n_points + 1) / reducev->yshrink );
if( resample->out->Ysize <= 0 ) { if( resample->out->Ysize <= 0 ) {
vips_error( object_class->nickname, vips_error( object_class->nickname,
"%s", _( "image has shrunk to nothing" ) ); "%s", _( "image has shrunk to nothing" ) );

View File

@ -135,13 +135,11 @@ vips_resize_build( VipsObject *object )
/* Do we need a further size adjustment? It's the difference /* Do we need a further size adjustment? It's the difference
* between our target size and the size we have after vips_shrink(). * between our target size and the size we have after vips_shrink().
* *
* Aim for a little above target so we can't round down below it.
*
* This can break the aspect ratio slightly :/ but hopefully no one * This can break the aspect ratio slightly :/ but hopefully no one
* will notice. * will notice.
*/ */
hresidual = ((double) target_width + 0.1) / in->Xsize; hresidual = (double) target_width / in->Xsize;
vresidual = ((double) target_height + 0.1) / in->Ysize; vresidual = (double) target_height / in->Ysize;
/* We want to make sure we read the image sequentially. /* We want to make sure we read the image sequentially.
* However, the convolution we may be doing later will force us * However, the convolution we may be doing later will force us

View File

@ -185,14 +185,13 @@ calculate_shrink( VipsImage *im )
VipsDirection direction; VipsDirection direction;
/* Calculate the horizontal and vertical shrink we'd need to fit the /* Calculate the horizontal and vertical shrink we'd need to fit the
* image to the bounding box, and pick the biggest. Aim for a little * image to the bounding box, and pick the biggest.
* above the target so we can't round down below it.
* *
* In crop mode we aim to fill the bounding box, so we must use the * In crop mode we aim to fill the bounding box, so we must use the
* smaller axis. * smaller axis.
*/ */
double horizontal = (double) width / (thumbnail_width + 0.1); double horizontal = (double) width / thumbnail_width;
double vertical = (double) height / (thumbnail_height + 0.1); double vertical = (double) height / thumbnail_height;
if( crop_image ) { if( crop_image ) {
if( horizontal < vertical ) if( horizontal < vertical )
@ -470,10 +469,7 @@ thumbnail_shrink( VipsObject *process, VipsImage *in )
shrink = calculate_shrink( in ); shrink = calculate_shrink( in );
/* Add a tiny amount to stop rounding below the target. if( vips_resize( in, &t[4], 1.0 / shrink, NULL ) )
*/
if( vips_resize( in, &t[4], 1.0 / shrink + 0.0000000001,
NULL ) )
return( NULL ); return( NULL );
in = t[4]; in = t[4];