try centre sampling option

This commit is contained in:
John Cupitt 2016-09-09 14:51:45 +01:00
parent fc9322f71b
commit 1e9cdef615
2 changed files with 37 additions and 3 deletions

8
TODO
View File

@ -1,3 +1,11 @@
- test possible centre hack
I think we're moving too far ... this is going to shift the mask by 50%, we
just want half a pixel
put the shift into vips_reduce_make_mask() so it gets picked up by the double
path too
- not sure about utf8 error messages on win - not sure about utf8 error messages on win
- strange: - strange:

View File

@ -75,6 +75,10 @@ typedef struct _VipsReduceh {
*/ */
VipsKernel kernel; VipsKernel kernel;
/* Use centre rather than corner sampling convention.
*/
gboolean centre;
/* Number of points in kernel. /* Number of points in kernel.
*/ */
int n_point; int n_point;
@ -461,6 +465,8 @@ vips_reduceh_build( VipsObject *object )
return( -1 ); return( -1 );
} }
for( int x = 0; x < VIPS_TRANSFORM_SCALE + 1; x++ ) { for( int x = 0; x < VIPS_TRANSFORM_SCALE + 1; x++ ) {
float fx;
reduceh->matrixf[x] = reduceh->matrixf[x] =
VIPS_ARRAY( object, reduceh->n_point, double ); VIPS_ARRAY( object, reduceh->n_point, double );
reduceh->matrixi[x] = reduceh->matrixi[x] =
@ -469,9 +475,18 @@ vips_reduceh_build( VipsObject *object )
!reduceh->matrixi[x] ) !reduceh->matrixi[x] )
return( -1 ); return( -1 );
/* Calculate our [0, 1] float displacement. For centre
* convention we must shift by 0.5 and wrap around.
*/
fx = (float) x / VIPS_TRANSFORM_SCALE;
if( reduceh->centre ) {
fx += 0.5;
if( fx > 1.0 )
fx -= 1.0;
}
vips_reduce_make_mask( reduceh->matrixf[x], vips_reduce_make_mask( reduceh->matrixf[x],
reduceh->kernel, reduceh->hshrink, reduceh->kernel, reduceh->hshrink, fx );
(float) x / VIPS_TRANSFORM_SCALE );
for( int i = 0; i < reduceh->n_point; i++ ) for( int i = 0; i < reduceh->n_point; i++ )
reduceh->matrixi[x][i] = reduceh->matrixf[x][i] * reduceh->matrixi[x][i] = reduceh->matrixf[x][i] *
@ -560,6 +575,13 @@ vips_reduceh_class_init( VipsReducehClass *reduceh_class )
G_STRUCT_OFFSET( VipsReduceh, kernel ), G_STRUCT_OFFSET( VipsReduceh, kernel ),
VIPS_TYPE_KERNEL, VIPS_KERNEL_LANCZOS3 ); VIPS_TYPE_KERNEL, VIPS_KERNEL_LANCZOS3 );
VIPS_ARG_BOOL( reduceh_class, "centre", 7,
_( "Centre" ),
_( "Use centre sampling convention" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsReduceh, centre ),
FALSE );
/* Old name. /* Old name.
*/ */
VIPS_ARG_DOUBLE( reduceh_class, "xshrink", 3, VIPS_ARG_DOUBLE( reduceh_class, "xshrink", 3,
@ -587,9 +609,13 @@ vips_reduceh_init( VipsReduceh *reduceh )
* Optional arguments: * Optional arguments:
* *
* * @kernel: #VipsKernel to use to interpolate (default: lanczos3) * * @kernel: #VipsKernel to use to interpolate (default: lanczos3)
* * @centre: %gboolean use centre rather than corner sampling convention
* *
* Reduce @in horizontally by a float factor. The pixels in @out are * Reduce @in horizontally by a float factor. The pixels in @out are
* interpolated with a 1D mask. * interpolated with a 1D mask generated by @kernel.
*
* Set @centre to use centre rather than corner sampling convention. Centre
* convention can be useful to match the behaviour of other systems.
* *
* This is a very low-level operation: see vips_resize() for a more * This is a very low-level operation: see vips_resize() for a more
* convenient way to resize images. * convenient way to resize images.