use round() rather than rint() where appropriate
rint() rounds to nearest even, rather than nearest ... in some cases, like geometry transforms, we want strict nearest
This commit is contained in:
parent
8503065faa
commit
271d8656e9
|
@ -37,8 +37,9 @@
|
||||||
- support --strip for pngsave
|
- support --strip for pngsave
|
||||||
- add svgz support [Felix Bünemann]
|
- add svgz support [Felix Bünemann]
|
||||||
- rename boostrap.sh -> autogen.sh to help snapcraft
|
- rename boostrap.sh -> autogen.sh to help snapcraft
|
||||||
- resize/reduce/shrink now round output size to nearest rather than rounding
|
- added VIPS_ROUND as well as VIPS_RINT
|
||||||
down, thanks ioquatix
|
- resize/reduce*/shrink*/affine now round output size to nearest rather than
|
||||||
|
rounding down, thanks ioquatix
|
||||||
|
|
||||||
30/7/16 started 8.3.3
|
30/7/16 started 8.3.3
|
||||||
- fix performance regression in 8.3.2, thanks Lovell
|
- fix performance regression in 8.3.2, thanks Lovell
|
||||||
|
|
|
@ -95,11 +95,9 @@ vips_Lab2LabQ_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width )
|
||||||
int lsbs;
|
int lsbs;
|
||||||
int intv;
|
int intv;
|
||||||
|
|
||||||
/* Scale L up to 10 bits. Add 0.5 rather than call VIPS_RINT
|
/* Scale L up to 10 bits.
|
||||||
* for speed. This will not round negatives correctly! But
|
|
||||||
* this does not matter, since L is >0. L*=100.0 -> 1023.
|
|
||||||
*/
|
*/
|
||||||
intv = 10.23 * p[0] + 0.5; /* scale L up to 10 bits */
|
intv = VIPS_ROUND_UINT( 10.23 * p[0] );
|
||||||
intv = VIPS_CLIP( 0, intv, 1023 );
|
intv = VIPS_CLIP( 0, intv, 1023 );
|
||||||
lsbs = (intv & 0x3) << 6; /* 00000011 -> 11000000 */
|
lsbs = (intv & 0x3) << 6; /* 00000011 -> 11000000 */
|
||||||
q[0] = intv >> 2; /* drop bot 2 bits and store */
|
q[0] = intv >> 2; /* drop bot 2 bits and store */
|
||||||
|
|
|
@ -50,14 +50,6 @@
|
||||||
|
|
||||||
#include "pconversion.h"
|
#include "pconversion.h"
|
||||||
|
|
||||||
/* Round N down to P boundary.
|
|
||||||
*/
|
|
||||||
#define ROUND_DOWN( N, P ) ((N) - ((N) % P))
|
|
||||||
|
|
||||||
/* Round N up to P boundary.
|
|
||||||
*/
|
|
||||||
#define ROUND_UP( N, P ) (ROUND_DOWN( (N) + (P) - 1, (P) ))
|
|
||||||
|
|
||||||
typedef struct _VipsArrayjoin {
|
typedef struct _VipsArrayjoin {
|
||||||
VipsConversion parent_instance;
|
VipsConversion parent_instance;
|
||||||
|
|
||||||
|
@ -179,7 +171,7 @@ vips_arrayjoin_build( VipsObject *object )
|
||||||
|
|
||||||
/* How many images down the grid?
|
/* How many images down the grid?
|
||||||
*/
|
*/
|
||||||
join->down = ROUND_UP( n, join->across ) / join->across;
|
join->down = VIPS_ROUND_UP( n, join->across ) / join->across;
|
||||||
|
|
||||||
/* The output size.
|
/* The output size.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -98,14 +98,6 @@ typedef VipsConversionClass VipsZoomClass;
|
||||||
|
|
||||||
G_DEFINE_TYPE( VipsZoom, vips_zoom, VIPS_TYPE_CONVERSION );
|
G_DEFINE_TYPE( VipsZoom, vips_zoom, VIPS_TYPE_CONVERSION );
|
||||||
|
|
||||||
/* Round N down to P boundary.
|
|
||||||
*/
|
|
||||||
#define ROUND_DOWN( N, P ) ((N) - ((N) % P))
|
|
||||||
|
|
||||||
/* Round N up to P boundary.
|
|
||||||
*/
|
|
||||||
#define ROUND_UP( N, P ) (ROUND_DOWN( (N) + (P) - 1, (P) ))
|
|
||||||
|
|
||||||
/* Paint the part of the region containing only whole pels.
|
/* Paint the part of the region containing only whole pels.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
|
@ -265,10 +257,10 @@ vips_zoom_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
|
||||||
/* Area of input we need. We have to round out, as we may have
|
/* Area of input we need. We have to round out, as we may have
|
||||||
* part-pixels all around the edges.
|
* part-pixels all around the edges.
|
||||||
*/
|
*/
|
||||||
left = ROUND_DOWN( r->left, zoom->xfac );
|
left = VIPS_ROUND_DOWN( r->left, zoom->xfac );
|
||||||
right = ROUND_UP( ri, zoom->xfac );
|
right = VIPS_ROUND_UP( ri, zoom->xfac );
|
||||||
top = ROUND_DOWN( r->top, zoom->yfac );
|
top = VIPS_ROUND_DOWN( r->top, zoom->yfac );
|
||||||
bottom = ROUND_UP( bo, zoom->yfac );
|
bottom = VIPS_ROUND_UP( bo, zoom->yfac );
|
||||||
width = right - left;
|
width = right - left;
|
||||||
height = bottom - top;
|
height = bottom - top;
|
||||||
s.left = left / zoom->xfac;
|
s.left = left / zoom->xfac;
|
||||||
|
@ -280,10 +272,10 @@ vips_zoom_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
|
||||||
|
|
||||||
/* Find the part of the output (if any) which uses only whole pels.
|
/* Find the part of the output (if any) which uses only whole pels.
|
||||||
*/
|
*/
|
||||||
left = ROUND_UP( r->left, zoom->xfac );
|
left = VIPS_ROUND_UP( r->left, zoom->xfac );
|
||||||
right = ROUND_DOWN( ri, zoom->xfac );
|
right = VIPS_ROUND_DOWN( ri, zoom->xfac );
|
||||||
top = ROUND_UP( r->top, zoom->yfac );
|
top = VIPS_ROUND_UP( r->top, zoom->yfac );
|
||||||
bottom = ROUND_DOWN( bo, zoom->yfac );
|
bottom = VIPS_ROUND_DOWN( bo, zoom->yfac );
|
||||||
width = right - left;
|
width = right - left;
|
||||||
height = bottom - top;
|
height = bottom - top;
|
||||||
|
|
||||||
|
|
|
@ -71,14 +71,6 @@ typedef struct _VipsPerlinClass {
|
||||||
|
|
||||||
G_DEFINE_TYPE( VipsPerlin, vips_perlin, VIPS_TYPE_CREATE );
|
G_DEFINE_TYPE( VipsPerlin, vips_perlin, VIPS_TYPE_CREATE );
|
||||||
|
|
||||||
/* Round N down to P boundary.
|
|
||||||
*/
|
|
||||||
#define ROUND_DOWN( N, P ) ((N) - ((N) % P))
|
|
||||||
|
|
||||||
/* Round N up to P boundary.
|
|
||||||
*/
|
|
||||||
#define ROUND_UP( N, P ) (ROUND_DOWN( (N) + (P) - 1, (P) ))
|
|
||||||
|
|
||||||
/* cos and sin from an angle in 0 - 255.
|
/* cos and sin from an angle in 0 - 255.
|
||||||
*/
|
*/
|
||||||
float vips_perlin_cos[256];
|
float vips_perlin_cos[256];
|
||||||
|
@ -261,9 +253,11 @@ vips_perlin_build( VipsObject *object )
|
||||||
|
|
||||||
/* Be careful if width is a multiple of cell_size.
|
/* Be careful if width is a multiple of cell_size.
|
||||||
*/
|
*/
|
||||||
perlin->cells_across = ROUND_UP( perlin->width, perlin->cell_size ) /
|
perlin->cells_across =
|
||||||
|
VIPS_ROUND_UP( perlin->width, perlin->cell_size ) /
|
||||||
perlin->cell_size;
|
perlin->cell_size;
|
||||||
perlin->cells_down = ROUND_UP( perlin->height, perlin->cell_size ) /
|
perlin->cells_down =
|
||||||
|
VIPS_ROUND_UP( perlin->height, perlin->cell_size ) /
|
||||||
perlin->cell_size;
|
perlin->cell_size;
|
||||||
|
|
||||||
perlin->seed = g_random_double() * 0xffffffffu;
|
perlin->seed = g_random_double() * 0xffffffffu;
|
||||||
|
|
|
@ -75,14 +75,6 @@ G_DEFINE_TYPE( VipsWorley, vips_worley, VIPS_TYPE_CREATE );
|
||||||
|
|
||||||
#define MAX_FEATURES (10)
|
#define MAX_FEATURES (10)
|
||||||
|
|
||||||
/* Round N down to P boundary.
|
|
||||||
*/
|
|
||||||
#define ROUND_DOWN( N, P ) ((N) - ((N) % P))
|
|
||||||
|
|
||||||
/* Round N up to P boundary.
|
|
||||||
*/
|
|
||||||
#define ROUND_UP( N, P ) (ROUND_DOWN( (N) + (P) - 1, (P) ))
|
|
||||||
|
|
||||||
typedef struct _Cell {
|
typedef struct _Cell {
|
||||||
/* Cell position, in number of cells. Scale by cell_size to get
|
/* Cell position, in number of cells. Scale by cell_size to get
|
||||||
* absolute image cods.
|
* absolute image cods.
|
||||||
|
@ -294,9 +286,11 @@ vips_worley_build( VipsObject *object )
|
||||||
|
|
||||||
/* Be careful if width is a multiple of cell_size.
|
/* Be careful if width is a multiple of cell_size.
|
||||||
*/
|
*/
|
||||||
worley->cells_across = ROUND_UP( worley->width, worley->cell_size ) /
|
worley->cells_across =
|
||||||
|
VIPS_ROUND_UP( worley->width, worley->cell_size ) /
|
||||||
worley->cell_size;
|
worley->cell_size;
|
||||||
worley->cells_down = ROUND_UP( worley->height, worley->cell_size ) /
|
worley->cells_down =
|
||||||
|
VIPS_ROUND_UP( worley->height, worley->cell_size ) /
|
||||||
worley->cell_size;
|
worley->cell_size;
|
||||||
|
|
||||||
worley->seed = g_random_double() * 0xffffffffu;
|
worley->seed = g_random_double() * 0xffffffffu;
|
||||||
|
|
|
@ -285,14 +285,6 @@ vips__make_xml_metadata( const char *domain, VipsImage *image )
|
||||||
|
|
||||||
#include <gsf/gsf.h>
|
#include <gsf/gsf.h>
|
||||||
|
|
||||||
/* Round N down to P boundary.
|
|
||||||
*/
|
|
||||||
#define ROUND_DOWN( N, P ) ((N) - ((N) % P))
|
|
||||||
|
|
||||||
/* Round N up to P boundary.
|
|
||||||
*/
|
|
||||||
#define ROUND_UP( N, P ) (ROUND_DOWN( (N) + (P) - 1, (P) ))
|
|
||||||
|
|
||||||
/* Simple wrapper around libgsf.
|
/* Simple wrapper around libgsf.
|
||||||
*
|
*
|
||||||
* We need to be able to do scattered writes to structured files. So while
|
* We need to be able to do scattered writes to structured files. So while
|
||||||
|
@ -672,8 +664,10 @@ pyramid_build( VipsForeignSaveDz *dz, Layer *above,
|
||||||
layer->width = width;
|
layer->width = width;
|
||||||
layer->height = height;
|
layer->height = height;
|
||||||
|
|
||||||
layer->tiles_across = ROUND_UP( width, dz->tile_size ) / dz->tile_size;
|
layer->tiles_across = VIPS_ROUND_UP( width, dz->tile_size ) /
|
||||||
layer->tiles_down = ROUND_UP( height, dz->tile_size ) / dz->tile_size;
|
dz->tile_size;
|
||||||
|
layer->tiles_down = VIPS_ROUND_UP( height, dz->tile_size ) /
|
||||||
|
dz->tile_size;
|
||||||
|
|
||||||
layer->real_pixels = *real_pixels;
|
layer->real_pixels = *real_pixels;
|
||||||
|
|
||||||
|
|
|
@ -322,14 +322,6 @@ tiff_openin( const char *name )
|
||||||
return( tif );
|
return( tif );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Round N down to P boundary.
|
|
||||||
*/
|
|
||||||
#define ROUND_DOWN(N,P) ((N) - ((N) % P))
|
|
||||||
|
|
||||||
/* Round N up to P boundary.
|
|
||||||
*/
|
|
||||||
#define ROUND_UP(N,P) (ROUND_DOWN( (N) + (P) - 1, (P) ))
|
|
||||||
|
|
||||||
static Layer *
|
static Layer *
|
||||||
pyramid_new( Write *write, Layer *above, int width, int height )
|
pyramid_new( Write *write, Layer *above, int width, int height )
|
||||||
{
|
{
|
||||||
|
@ -975,7 +967,7 @@ write_new( VipsImage *im, const char *filename,
|
||||||
if( im->Coding == VIPS_CODING_LABQ )
|
if( im->Coding == VIPS_CODING_LABQ )
|
||||||
write->tls = write->tilew * 3;
|
write->tls = write->tilew * 3;
|
||||||
else if( write->onebit )
|
else if( write->onebit )
|
||||||
write->tls = ROUND_UP( write->tilew, 8 ) / 8;
|
write->tls = VIPS_ROUND_UP( write->tilew, 8 ) / 8;
|
||||||
else
|
else
|
||||||
write->tls = VIPS_IMAGE_SIZEOF_PEL( im ) * write->tilew;
|
write->tls = VIPS_IMAGE_SIZEOF_PEL( im ) * write->tilew;
|
||||||
|
|
||||||
|
|
|
@ -53,11 +53,14 @@ extern "C" {
|
||||||
|
|
||||||
#define VIPS_MAX( A, B ) ((A) > (B) ? (A) : (B))
|
#define VIPS_MAX( A, B ) ((A) > (B) ? (A) : (B))
|
||||||
#define VIPS_MIN( A, B ) ((A) < (B) ? (A) : (B))
|
#define VIPS_MIN( A, B ) ((A) < (B) ? (A) : (B))
|
||||||
#define VIPS_ABS( X ) (((X) >= 0) ? (X) : -(X))
|
|
||||||
|
|
||||||
#define VIPS_CLIP( A, V, B ) VIPS_MAX( (A), VIPS_MIN( (B), (V) ) )
|
#define VIPS_CLIP( A, V, B ) VIPS_MAX( (A), VIPS_MIN( (B), (V) ) )
|
||||||
|
#define VIPS_FCLIP( A, V, B ) VIPS_FMAX( (A), VIPS_FMIN( (B), (V) ) )
|
||||||
|
|
||||||
#define VIPS_NUMBER( R ) ((int) (sizeof(R) / sizeof(R[0])))
|
#define VIPS_NUMBER( R ) ((int) (sizeof(R) / sizeof(R[0])))
|
||||||
|
|
||||||
|
#define VIPS_ABS( X ) (((X) >= 0) ? (X) : -(X))
|
||||||
|
|
||||||
/* The built-in isnan and isinf functions provided by gcc 4+ and clang are
|
/* The built-in isnan and isinf functions provided by gcc 4+ and clang are
|
||||||
* up to 7x faster than their libc equivalent included from <math.h>.
|
* up to 7x faster than their libc equivalent included from <math.h>.
|
||||||
*/
|
*/
|
||||||
|
@ -67,6 +70,7 @@ extern "C" {
|
||||||
#define VIPS_FLOOR( V ) __builtin_floor( V )
|
#define VIPS_FLOOR( V ) __builtin_floor( V )
|
||||||
#define VIPS_CEIL( V ) __builtin_ceil( V )
|
#define VIPS_CEIL( V ) __builtin_ceil( V )
|
||||||
#define VIPS_RINT( V ) __builtin_rint( V )
|
#define VIPS_RINT( V ) __builtin_rint( V )
|
||||||
|
#define VIPS_ROUND( V ) __builtin_round( V )
|
||||||
#define VIPS_FABS( V ) __builtin_fabs( V )
|
#define VIPS_FABS( V ) __builtin_fabs( V )
|
||||||
#define VIPS_FMAX( A, B ) __builtin_fmax( A, B )
|
#define VIPS_FMAX( A, B ) __builtin_fmax( A, B )
|
||||||
#define VIPS_FMIN( A, B ) __builtin_fmin( A, B )
|
#define VIPS_FMIN( A, B ) __builtin_fmin( A, B )
|
||||||
|
@ -75,13 +79,25 @@ extern "C" {
|
||||||
#define VIPS_ISINF( V ) isinf( V )
|
#define VIPS_ISINF( V ) isinf( V )
|
||||||
#define VIPS_FLOOR( V ) floor( V )
|
#define VIPS_FLOOR( V ) floor( V )
|
||||||
#define VIPS_CEIL( V ) ceil( V )
|
#define VIPS_CEIL( V ) ceil( V )
|
||||||
#define VIPS_RINT( R ) ((int) ((R) > 0 ? ((R) + 0.5) : ((R) - 0.5)))
|
#define VIPS_RINT( R ) rint( V )
|
||||||
|
#define VIPS_ROUND( V ) round( V )
|
||||||
#define VIPS_FABS( V ) VIPS_ABS( V )
|
#define VIPS_FABS( V ) VIPS_ABS( V )
|
||||||
#define VIPS_FMAX( A, B ) VIPS_MAX( A, B )
|
#define VIPS_FMAX( A, B ) VIPS_MAX( A, B )
|
||||||
#define VIPS_FMIN( A, B ) VIPS_MIN( A, B )
|
#define VIPS_FMIN( A, B ) VIPS_MIN( A, B )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define VIPS_FCLIP( A, V, B ) VIPS_FMAX( (A), VIPS_FMIN( (B), (V) ) )
|
/* VIPS_RINT() does "bankers rounding", it rounds to the nerarest even integer.
|
||||||
|
* For things like image geometry, we want strict nearest int.
|
||||||
|
*
|
||||||
|
* If you know it's unsigned, _UINT is a little faster.
|
||||||
|
*/
|
||||||
|
#define VIPS_ROUND_INT( R ) ((int) ((R) > 0 ? ((R) + 0.5) : ((R) - 0.5)))
|
||||||
|
#define VIPS_ROUND_UINT( R ) ((int) ((R) + 0.5))
|
||||||
|
|
||||||
|
/* Round N down and up to the nearest multiple of P.
|
||||||
|
*/
|
||||||
|
#define VIPS_ROUND_DOWN( N, P ) ((N) - ((N) % (P)))
|
||||||
|
#define VIPS_ROUND_UP( N, P ) (VIPS_ROUND_DOWN( N, P ) + (P))
|
||||||
|
|
||||||
#define VIPS_SWAP( TYPE, A, B ) \
|
#define VIPS_SWAP( TYPE, A, B ) \
|
||||||
G_STMT_START { \
|
G_STMT_START { \
|
||||||
|
|
|
@ -922,14 +922,6 @@ vips_threadpool_run( VipsImage *im,
|
||||||
return( result );
|
return( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Round N down to P boundary.
|
|
||||||
*/
|
|
||||||
#define ROUND_DOWN(N,P) ((N) - ((N) % P))
|
|
||||||
|
|
||||||
/* Round N up to P boundary.
|
|
||||||
*/
|
|
||||||
#define ROUND_UP(N,P) (ROUND_DOWN( (N) + (P) - 1, (P) ))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vips_get_tile_size:
|
* vips_get_tile_size:
|
||||||
* @im: image to guess for
|
* @im: image to guess for
|
||||||
|
@ -986,7 +978,7 @@ vips_get_tile_size( VipsImage *im,
|
||||||
(1 + nthr / VIPS_MAX( 1, im->Xsize / vips__tile_width )) * 2;
|
(1 + nthr / VIPS_MAX( 1, im->Xsize / vips__tile_width )) * 2;
|
||||||
*n_lines = VIPS_MAX( *n_lines, vips__fatstrip_height * nthr * 2 );
|
*n_lines = VIPS_MAX( *n_lines, vips__fatstrip_height * nthr * 2 );
|
||||||
*n_lines = VIPS_MAX( *n_lines, vips__thinstrip_height * nthr * 2 );
|
*n_lines = VIPS_MAX( *n_lines, vips__thinstrip_height * nthr * 2 );
|
||||||
*n_lines = ROUND_UP( *n_lines, *tile_height );
|
*n_lines = VIPS_ROUND_UP( *n_lines, *tile_height );
|
||||||
|
|
||||||
/* We make this assumption in several places.
|
/* We make this assumption in several places.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -498,13 +498,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 to nearest to hide rounding errors.
|
/* Size output. We need to always round to nearest, so round(), not
|
||||||
|
* rint().
|
||||||
*
|
*
|
||||||
* 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 = VIPS_RINT(
|
resample->out->Xsize = VIPS_ROUND_UINT(
|
||||||
(in->Xsize - reduceh->n_point + 1) / reduceh->hshrink );
|
(in->Xsize - reduceh->n_point + 1) / reduceh->hshrink );
|
||||||
if( resample->out->Xsize <= 0 ) {
|
if( resample->out->Xsize <= 0 ) {
|
||||||
vips_error( object_class->nickname,
|
vips_error( object_class->nickname,
|
||||||
|
|
|
@ -775,13 +775,14 @@ vips_reducev_raw( VipsReducev *reducev, VipsImage *in )
|
||||||
VIPS_DEMAND_STYLE_FATSTRIP, in, NULL ) )
|
VIPS_DEMAND_STYLE_FATSTRIP, in, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
/* Size output. Note: we round to nearest to hide rounding errors.
|
/* Size output. We need to always round to nearest, so round(), not
|
||||||
|
* rint().
|
||||||
*
|
*
|
||||||
* 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 = VIPS_RINT(
|
resample->out->Ysize = VIPS_ROUND_UINT(
|
||||||
(in->Ysize - reducev->n_point + 1) / reducev->vshrink );
|
(in->Ysize - reducev->n_point + 1) / reducev->vshrink );
|
||||||
if( resample->out->Ysize <= 0 ) {
|
if( resample->out->Ysize <= 0 ) {
|
||||||
vips_error( object_class->nickname,
|
vips_error( object_class->nickname,
|
||||||
|
|
|
@ -275,13 +275,14 @@ vips_shrinkh_build( VipsObject *object )
|
||||||
VIPS_DEMAND_STYLE_THINSTRIP, in, NULL ) )
|
VIPS_DEMAND_STYLE_THINSTRIP, in, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
/* Size output. We need to rint() from the size of the original image.
|
/* Size output. We need to always round to nearest, so round(), not
|
||||||
|
* rint().
|
||||||
*
|
*
|
||||||
* 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 shrink factor (including the
|
* example, vipsthumbnail knows the true shrink factor (including the
|
||||||
* fractional part), we just see the integer part here.
|
* fractional part), we just see the integer part here.
|
||||||
*/
|
*/
|
||||||
resample->out->Xsize = VIPS_RINT(
|
resample->out->Xsize = VIPS_ROUND_UINT(
|
||||||
resample->in->Xsize / shrink->hshrink );
|
resample->in->Xsize / shrink->hshrink );
|
||||||
if( resample->out->Xsize <= 0 ) {
|
if( resample->out->Xsize <= 0 ) {
|
||||||
vips_error( class->nickname,
|
vips_error( class->nickname,
|
||||||
|
|
|
@ -379,13 +379,14 @@ vips_shrinkv_build( VipsObject *object )
|
||||||
VIPS_DEMAND_STYLE_THINSTRIP, in, NULL ) )
|
VIPS_DEMAND_STYLE_THINSTRIP, in, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
/* Size output. We need to rint() from the size of the original image.
|
/* Size output. We need to always round to nearest, so round(), not
|
||||||
|
* rint().
|
||||||
*
|
*
|
||||||
* 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 shrink factor (including the
|
* example, vipsthumbnail knows the true shrink factor (including the
|
||||||
* fractional part), we just see the integer part here.
|
* fractional part), we just see the integer part here.
|
||||||
*/
|
*/
|
||||||
resample->out->Ysize = VIPS_RINT(
|
resample->out->Ysize = VIPS_ROUND_UINT(
|
||||||
resample->in->Ysize / shrink->vshrink );
|
resample->in->Ysize / shrink->vshrink );
|
||||||
if( resample->out->Ysize <= 0 ) {
|
if( resample->out->Ysize <= 0 ) {
|
||||||
vips_error( class->nickname,
|
vips_error( class->nickname,
|
||||||
|
|
|
@ -215,10 +215,10 @@ transform_rect( const VipsTransformation *trn, transform_fn transform,
|
||||||
top = VIPS_MIN( y1, VIPS_MIN( y2, VIPS_MIN( y3, y4 ) ) );
|
top = VIPS_MIN( y1, VIPS_MIN( y2, VIPS_MIN( y3, y4 ) ) );
|
||||||
bottom = VIPS_MAX( y1, VIPS_MAX( y2, VIPS_MAX( y3, y4 ) ) );
|
bottom = VIPS_MAX( y1, VIPS_MAX( y2, VIPS_MAX( y3, y4 ) ) );
|
||||||
|
|
||||||
out->left = VIPS_RINT( left );
|
out->left = VIPS_ROUND_INT( left );
|
||||||
out->top = VIPS_RINT( top );
|
out->top = VIPS_ROUND_INT( top );
|
||||||
out->width = VIPS_RINT( right - left );
|
out->width = VIPS_ROUND_INT( right - left );
|
||||||
out->height = VIPS_RINT( bottom - top );
|
out->height = VIPS_ROUND_INT( bottom - top );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Given an area in the input image, calculate the bounding box for those
|
/* Given an area in the input image, calculate the bounding box for those
|
||||||
|
|
Loading…
Reference in New Issue