add "nearest" region shrink

This commit is contained in:
John Cupitt 2020-01-30 16:53:18 +00:00
parent 979422886b
commit 4aeedd9711
4 changed files with 26 additions and 7 deletions

View File

@ -62,6 +62,7 @@ extern "C" {
* @VIPS_REGION_SHRINK_MODE: use the mode
* @VIPS_REGION_SHRINK_MAX: use the maximum
* @VIPS_REGION_SHRINK_MIN: use the minimum
* @VIPS_REGION_SHRINK_NEAREST: use the top-left pixel
*
* How to calculate the output pixels when shrinking a 2x2 region.
*/
@ -71,6 +72,7 @@ typedef enum {
VIPS_REGION_SHRINK_MODE,
VIPS_REGION_SHRINK_MAX,
VIPS_REGION_SHRINK_MIN,
VIPS_REGION_SHRINK_NEAREST,
VIPS_REGION_SHRINK_LAST
} VipsRegionShrink;

View File

@ -905,6 +905,7 @@ vips_region_shrink_get_type( void )
{VIPS_REGION_SHRINK_MODE, "VIPS_REGION_SHRINK_MODE", "mode"},
{VIPS_REGION_SHRINK_MAX, "VIPS_REGION_SHRINK_MAX", "max"},
{VIPS_REGION_SHRINK_MIN, "VIPS_REGION_SHRINK_MIN", "min"},
{VIPS_REGION_SHRINK_NEAREST, "VIPS_REGION_SHRINK_NEAREST", "nearest"},
{VIPS_REGION_SHRINK_LAST, "VIPS_REGION_SHRINK_LAST", "last"},
{0, NULL, NULL}
};

View File

@ -1283,8 +1283,6 @@ vips_region_shrink_uncoded_mean( VipsRegion *from,
tq[z] = v[index]; \
} \
\
/* Move on two pels in input. \
*/ \
p += ps << 1; \
q += ps; \
} \
@ -1303,8 +1301,6 @@ vips_region_shrink_uncoded_mean( VipsRegion *from,
); \
} \
\
/* Move on two pels in input. \
*/ \
p += ps << 1; \
q += ps; \
} \
@ -1323,8 +1319,20 @@ vips_region_shrink_uncoded_mean( VipsRegion *from,
); \
} \
\
/* Move on two pels in input. \
*/ \
p += ps << 1; \
q += ps; \
} \
}
#define SHRINK_TYPE_NEAREST( TYPE ) { \
for( x = 0; x < target->width; x++ ) { \
TYPE *tp = (TYPE *) p; \
TYPE *tp1 = (TYPE *) (p + ls); \
TYPE *tq = (TYPE *) q; \
\
for( z = 0; z < nb; z++ ) \
tq[z] = tp[z]; \
\
p += ps << 1; \
q += ps; \
} \
@ -1377,6 +1385,7 @@ VIPS_REGION_SHRINK( MAX );
VIPS_REGION_SHRINK( MIN );
VIPS_REGION_SHRINK( MODE );
VIPS_REGION_SHRINK( MEDIAN );
VIPS_REGION_SHRINK( NEAREST );
/* Generate area @target in @to using pixels in @from. Non-complex.
*/
@ -1405,6 +1414,10 @@ vips_region_shrink_uncoded( VipsRegion *from,
vips_region_shrink_uncoded_MIN( from, to, target );
break;
case VIPS_REGION_SHRINK_NEAREST:
vips_region_shrink_uncoded_NEAREST( from, to, target );
break;
default:
g_assert_not_reached();
}

View File

@ -419,11 +419,14 @@ class TestForeign:
assert a.height == b.height
assert a.avg() == b.avg()
# region-shrink added in 8.7
x = pyvips.Image.new_from_file(TIF_FILE)
buf = x.tiffsave_buffer(tile=True, pyramid=True, region_shrink="mean")
buf = x.tiffsave_buffer(tile=True, pyramid=True, region_shrink="mode")
buf = x.tiffsave_buffer(tile=True, pyramid=True, region_shrink="median")
buf = x.tiffsave_buffer(tile=True, pyramid=True, region_shrink="max")
buf = x.tiffsave_buffer(tile=True, pyramid=True, region_shrink="min")
buf = x.tiffsave_buffer(tile=True, pyramid=True,
region_shrink="nearest")
@skip_if_no("magickload")
def test_magickload(self):