better shrinkv for int32 types
use double as the sum type to prevent int overflow
This commit is contained in:
parent
25b6f2fcf1
commit
6ba34e479e
Binary file not shown.
@ -45,6 +45,8 @@
|
|||||||
* - rename yshrink -> vshrink for greater consistency
|
* - rename yshrink -> vshrink for greater consistency
|
||||||
* 7/3/17
|
* 7/3/17
|
||||||
* - add a seq line cache
|
* - add a seq line cache
|
||||||
|
* 6/8/19
|
||||||
|
* - use a double sum buffer for int32 types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -180,9 +182,9 @@ vips_shrinkv_add_line( VipsShrinkv *shrink, VipsShrinkvSequence *seq,
|
|||||||
case VIPS_FORMAT_SHORT:
|
case VIPS_FORMAT_SHORT:
|
||||||
ADD( int, short ); break;
|
ADD( int, short ); break;
|
||||||
case VIPS_FORMAT_UINT:
|
case VIPS_FORMAT_UINT:
|
||||||
ADD( int, unsigned int ); break;
|
ADD( double, unsigned int ); break;
|
||||||
case VIPS_FORMAT_INT:
|
case VIPS_FORMAT_INT:
|
||||||
ADD( int, int ); break;
|
ADD( double, int ); break;
|
||||||
case VIPS_FORMAT_FLOAT:
|
case VIPS_FORMAT_FLOAT:
|
||||||
ADD( double, float ); break;
|
ADD( double, float ); break;
|
||||||
case VIPS_FORMAT_DOUBLE:
|
case VIPS_FORMAT_DOUBLE:
|
||||||
@ -199,13 +201,12 @@ vips_shrinkv_add_line( VipsShrinkv *shrink, VipsShrinkvSequence *seq,
|
|||||||
|
|
||||||
/* Integer average.
|
/* Integer average.
|
||||||
*/
|
*/
|
||||||
#define IAVG( TYPE, BTYPE ) { \
|
#define IAVG( ACC_TYPE, TYPE ) { \
|
||||||
int * restrict sum = (int *) seq->sum; \
|
ACC_TYPE * restrict sum = (ACC_TYPE *) seq->sum; \
|
||||||
TYPE * restrict q = (TYPE *) out; \
|
TYPE * restrict q = (TYPE *) out; \
|
||||||
\
|
\
|
||||||
for( x = 0; x < sz; x++ ) \
|
for( x = 0; x < sz; x++ ) \
|
||||||
q[x] = ((BTYPE) sum[x] + shrink->vshrink / 2) / \
|
q[x] = (sum[x] + shrink->vshrink / 2) / shrink->vshrink; \
|
||||||
shrink->vshrink; \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Float average.
|
/* Float average.
|
||||||
@ -235,17 +236,17 @@ vips_shrinkv_write_line( VipsShrinkv *shrink, VipsShrinkvSequence *seq,
|
|||||||
VipsPel *out = VIPS_REGION_ADDR( or, left, top );
|
VipsPel *out = VIPS_REGION_ADDR( or, left, top );
|
||||||
switch( resample->in->BandFmt ) {
|
switch( resample->in->BandFmt ) {
|
||||||
case VIPS_FORMAT_UCHAR:
|
case VIPS_FORMAT_UCHAR:
|
||||||
IAVG( unsigned char, int ); break;
|
IAVG( int, unsigned char ); break;
|
||||||
case VIPS_FORMAT_CHAR:
|
case VIPS_FORMAT_CHAR:
|
||||||
IAVG( char, int ); break;
|
IAVG( int, char ); break;
|
||||||
case VIPS_FORMAT_USHORT:
|
case VIPS_FORMAT_USHORT:
|
||||||
IAVG( unsigned short, int ); break;
|
IAVG( int, unsigned short ); break;
|
||||||
case VIPS_FORMAT_SHORT:
|
case VIPS_FORMAT_SHORT:
|
||||||
IAVG( short, int ); break;
|
IAVG( int, short ); break;
|
||||||
case VIPS_FORMAT_UINT:
|
case VIPS_FORMAT_UINT:
|
||||||
IAVG( unsigned int, guint64 ); break;
|
IAVG( double, unsigned int ); break;
|
||||||
case VIPS_FORMAT_INT:
|
case VIPS_FORMAT_INT:
|
||||||
IAVG( int, gint64 ); break;
|
IAVG( double, int ); break;
|
||||||
case VIPS_FORMAT_FLOAT:
|
case VIPS_FORMAT_FLOAT:
|
||||||
FAVG( float ); break;
|
FAVG( float ); break;
|
||||||
case VIPS_FORMAT_DOUBLE:
|
case VIPS_FORMAT_DOUBLE:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user