Skip to content

Commit 75632a5

Browse files
authored
Merge pull request #1592 from kleisauke/issue-703
Fix the pixel shift within reduce (#703)
2 parents 4469afa + d7a7354 commit 75632a5

File tree

6 files changed

+194
-185
lines changed

6 files changed

+194
-185
lines changed

libvips/resample/bicubic.cpp

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,15 @@ typedef VipsInterpolate VipsInterpolateBicubic;
7979
typedef VipsInterpolateClass VipsInterpolateBicubicClass;
8080

8181
/* Precalculated interpolation matrices. int (used for pel
82-
* sizes up to short), and double (for all others). We go to
83-
* scale + 1 so we can round-to-nearest safely.
82+
* sizes up to short), and double (for all others).
8483
*/
8584

8685
/* We could keep a large set of 2d 4x4 matricies, but this actually
8786
* works out slower since for many resizes the thing will no longer
8887
* fit in L1.
8988
*/
90-
static int vips_bicubic_matrixi[VIPS_TRANSFORM_SCALE + 1][4];
91-
static double vips_bicubic_matrixf[VIPS_TRANSFORM_SCALE + 1][4];
89+
static int vips_bicubic_matrixi[VIPS_TRANSFORM_SCALE][4];
90+
static double vips_bicubic_matrixf[VIPS_TRANSFORM_SCALE][4];
9291

9392
/* We need C linkage for this.
9493
*/
@@ -498,19 +497,13 @@ static void
498497
vips_interpolate_bicubic_interpolate( VipsInterpolate *interpolate,
499498
void *out, VipsRegion *in, double x, double y )
500499
{
501-
/* Find the mask index. We round-to-nearest, so we need to generate
502-
* indexes in 0 to VIPS_TRANSFORM_SCALE, 2^n + 1 values. We multiply
503-
* by 2 more than we need to, add one, mask, then shift down again to
504-
* get the extra range.
500+
/* Find the mask index.
505501
*/
506-
const int sx = x * VIPS_TRANSFORM_SCALE * 2;
507-
const int sy = y * VIPS_TRANSFORM_SCALE * 2;
502+
const int sx = x * VIPS_TRANSFORM_SCALE;
503+
const int sy = y * VIPS_TRANSFORM_SCALE;
508504

509-
const int six = sx & (VIPS_TRANSFORM_SCALE * 2 - 1);
510-
const int siy = sy & (VIPS_TRANSFORM_SCALE * 2 - 1);
511-
512-
const int tx = (six + 1) >> 1;
513-
const int ty = (siy + 1) >> 1;
505+
const int tx = sx & (VIPS_TRANSFORM_SCALE - 1);
506+
const int ty = sy & (VIPS_TRANSFORM_SCALE - 1);
514507

515508
/* We know x/y are always positive, so we can just (int) them.
516509
*/
@@ -643,7 +636,7 @@ vips_interpolate_bicubic_class_init( VipsInterpolateBicubicClass *iclass )
643636

644637
/* Build the tables of pre-computed coefficients.
645638
*/
646-
for( int x = 0; x < VIPS_TRANSFORM_SCALE + 1; x++ ) {
639+
for( int x = 0; x < VIPS_TRANSFORM_SCALE; x++ ) {
647640
calculate_coefficients_catmull( vips_bicubic_matrixf[x],
648641
(float) x / VIPS_TRANSFORM_SCALE );
649642

libvips/resample/reduce.c

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* - rename xshrink -> hshrink for greater consistency
77
* 9/9/16
88
* - add @centre option
9+
* 6/6/20 kleisauke
10+
* - deprecate @centre option, it's now always on
911
*/
1012

1113
/*
@@ -78,14 +80,10 @@
7880
* Optional arguments:
7981
*
8082
* * @kernel: #VipsKernel to use to interpolate (default: lanczos3)
81-
* * @centre: %gboolean use centre rather than corner sampling convention
8283
*
8384
* Reduce @in vertically by a float factor. The pixels in @out are
8485
* interpolated with a 1D mask generated by @kernel.
8586
*
86-
* Set @centre to use centre rather than corner sampling convention. Centre
87-
* convention can be useful to match the behaviour of other systems.
88-
*
8987
* This is a very low-level operation: see vips_resize() for a more
9088
* convenient way to resize images.
9189
*
@@ -107,14 +105,10 @@
107105
* Optional arguments:
108106
*
109107
* * @kernel: #VipsKernel to use to interpolate (default: lanczos3)
110-
* * @centre: %gboolean use centre rather than corner sampling convention
111108
*
112109
* Reduce @in horizontally by a float factor. The pixels in @out are
113110
* interpolated with a 1D mask generated by @kernel.
114111
*
115-
* Set @centre to use centre rather than corner sampling convention. Centre
116-
* convention can be useful to match the behaviour of other systems.
117-
*
118112
* This is a very low-level operation: see vips_resize() for a more
119113
* convenient way to resize images.
120114
*
@@ -136,7 +130,7 @@ typedef struct _VipsReduce {
136130
*/
137131
VipsKernel kernel;
138132

139-
/* Use centre rather than corner sampling convention.
133+
/* Deprecated.
140134
*/
141135
gboolean centre;
142136

@@ -152,18 +146,16 @@ vips_reduce_build( VipsObject *object )
152146
VipsResample *resample = VIPS_RESAMPLE( object );
153147
VipsReduce *reduce = (VipsReduce *) object;
154148
VipsImage **t = (VipsImage **)
155-
vips_object_local_array( object, 3 );
149+
vips_object_local_array( object, 2 );
156150

157151
if( VIPS_OBJECT_CLASS( vips_reduce_parent_class )->build( object ) )
158152
return( -1 );
159153

160154
if( vips_reducev( resample->in, &t[0], reduce->vshrink,
161155
"kernel", reduce->kernel,
162-
"centre", reduce->centre,
163156
NULL ) ||
164157
vips_reduceh( t[0], &t[1], reduce->hshrink,
165158
"kernel", reduce->kernel,
166-
"centre", reduce->centre,
167159
NULL ) ||
168160
vips_image_write( t[1], resample->out ) )
169161
return( -1 );
@@ -210,13 +202,6 @@ vips_reduce_class_init( VipsReduceClass *class )
210202
G_STRUCT_OFFSET( VipsReduce, kernel ),
211203
VIPS_TYPE_KERNEL, VIPS_KERNEL_LANCZOS3 );
212204

213-
VIPS_ARG_BOOL( class, "centre", 7,
214-
_( "Centre" ),
215-
_( "Use centre sampling convention" ),
216-
VIPS_ARGUMENT_OPTIONAL_INPUT,
217-
G_STRUCT_OFFSET( VipsReduce, centre ),
218-
FALSE );
219-
220205
/* The old names .. now use h and v everywhere.
221206
*/
222207
VIPS_ARG_DOUBLE( class, "xshrink", 8,
@@ -233,6 +218,15 @@ vips_reduce_class_init( VipsReduceClass *class )
233218
G_STRUCT_OFFSET( VipsReduce, vshrink ),
234219
1.0, 1000000.0, 1.0 );
235220

221+
/* We used to let people pick centre or corner, but it's automatic now.
222+
*/
223+
VIPS_ARG_BOOL( class, "centre", 7,
224+
_( "Centre" ),
225+
_( "Use centre sampling convention" ),
226+
VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED,
227+
G_STRUCT_OFFSET( VipsReduce, centre ),
228+
FALSE );
229+
236230
}
237231

238232
static void
@@ -252,14 +246,10 @@ vips_reduce_init( VipsReduce *reduce )
252246
* Optional arguments:
253247
*
254248
* * @kernel: #VipsKernel to use to interpolate (default: lanczos3)
255-
* * @centre: %gboolean use centre rather than corner sampling convention
256249
*
257250
* Reduce @in by a pair of factors with a pair of 1D kernels. This
258251
* will not work well for shrink factors greater than three.
259252
*
260-
* Set @centre to use centre rather than corner sampling convention. Centre
261-
* convention can be useful to match the behaviour of other systems.
262-
*
263253
* This is a very low-level operation: see vips_resize() for a more
264254
* convenient way to resize images.
265255
*

0 commit comments

Comments
 (0)