From 4d18300560b18b1e100880f48e1c5f86f45f4d9a Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 26 Jan 2016 12:26:21 +0000 Subject: [PATCH] add VIPS_FABS/MAX/MIN/CLIP macros which use the gcc __builtin_fabs() etc. functions when they can --- ChangeLog | 2 + README.md | 6 +-- TODO | 2 + libvips/arithmetic/abs.c | 6 +-- libvips/arithmetic/deviate.c | 2 +- libvips/arithmetic/divide.c | 2 +- libvips/arithmetic/linear.c | 6 +-- libvips/arithmetic/measure.c | 3 +- libvips/arithmetic/stats.c | 4 +- libvips/arithmetic/unaryconst.c | 2 +- libvips/colour/HSV2sRGB.c | 67 ++++++++++++++++++--------------- libvips/colour/LCh2UCS.c | 2 +- libvips/colour/Lab2LabQ.c | 15 ++++---- libvips/colour/LabS2LabQ.c | 5 ++- libvips/colour/XYZ2Lab.c | 6 +-- libvips/colour/dE00.c | 6 +-- libvips/colour/sRGB2HSV.c | 66 ++++++++++++++++++-------------- libvips/colour/scRGB2BW.c | 2 +- libvips/colour/scRGB2sRGB.c | 2 +- libvips/create/buildlut.c | 2 +- libvips/create/logmat.c | 2 +- libvips/foreign/ppm.c | 2 +- libvips/foreign/vips2jpeg.c | 4 +- libvips/foreign/vips2tiff.c | 4 +- libvips/include/vips/util.h | 42 ++++++++++++--------- 25 files changed, 147 insertions(+), 115 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4f119364..d44b4cdf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,8 @@ - add VIPS_FLOOR()/VIPS_CEIL(), much faster [Lovell Fuller] - use g_assert_not_reached(); - better vips-from-C docs +- add VIPS_FMIN() / VIPS_FMAX() / VIPS_FABS() / VIPS_FCLIP() ... use builtins + when available 1/1/16 started 8.2.1 - add a compat stub [Benjamin Gilbert] diff --git a/README.md b/README.md index 2dd3da05..9e2aa96d 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ Clang dynamic analysis: $ FLAGS="$FLAGS -fno-omit-frame-pointer -fno-optimize-sibling-calls" $ CC=clang CXX=clang++ LD=clang \ CFLAGS="$FLAGS" CXXFLAGS="$FLAGS" LDFLAGS=-fsanitize=address \ - ./configure --prefix=/home/john/vips --disable-introspection + ./configure --prefix=/home/john/vips $ FLAGS="-O1 -g -fsanitize=thread" $ FLAGS="$FLAGS -fPIC -pie" @@ -120,14 +120,14 @@ Clang dynamic analysis: $ CC=clang CXX=clang++ LD=clang \ CFLAGS="$FLAGS" CXXFLAGS="$FLAGS" \ LDFLAGS="-fsanitize=thread -fPIC -pie" \ - ./configure --prefix=/home/john/vips --disable-introspection + ./configure --prefix=/home/john/vips Build with the GCC auto-vectorizer and diagnostics (or just -O3): $ FLAGS="-O2 -msse4.2 -ffast-math" $ FLAGS="$FLAGS -ftree-vectorize -fdump-tree-vect-details" $ CFLAGS="$FLAGS" CXXFLAGS="$FLAGS" \ - ./configure --prefix=/home/john/vips --disable-introspection + ./configure --prefix=/home/john/vips Static analysis with: diff --git a/TODO b/TODO index 1b15b9a5..dc3d76a2 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,5 @@ +- look for FCLIP / FABS use ... VIPS_ABS() on float type + - write a shrinker that does two 1D shrinks, vertical and horizontal, with bicubic interpolation diff --git a/libvips/arithmetic/abs.c b/libvips/arithmetic/abs.c index 0d414dd3..8574688c 100644 --- a/libvips/arithmetic/abs.c +++ b/libvips/arithmetic/abs.c @@ -112,7 +112,7 @@ vips_abs_build( VipsObject *object ) int x; \ \ for( x = 0; x < sz; x++ ) \ - q[x] = fabs( p[x] ); \ + q[x] = VIPS_FABS( p[x] ); \ } /* Complex abs operation: calculate modulus. @@ -141,8 +141,8 @@ vips_abs_build( VipsObject *object ) for( x = 0; x < sz; x++ ) { \ double rp = p[0]; \ double ip = p[1]; \ - double abs_rp = fabs( rp ); \ - double abs_ip = fabs( ip ); \ + double abs_rp = VIPS_FABS( rp ); \ + double abs_ip = VIPS_FABS( ip ); \ \ if( abs_rp > abs_ip ) { \ double temp = ip / rp; \ diff --git a/libvips/arithmetic/deviate.c b/libvips/arithmetic/deviate.c index 1b4b9019..3c62e3d8 100644 --- a/libvips/arithmetic/deviate.c +++ b/libvips/arithmetic/deviate.c @@ -121,7 +121,7 @@ vips_deviate_build( VipsObject *object ) s2 = deviate->sum2; g_object_set( object, - "out", sqrt( fabs( s2 - (s * s / vals) ) / (vals - 1) ), + "out", sqrt( VIPS_FABS( s2 - (s * s / vals) ) / (vals - 1) ), NULL ); return( 0 ); diff --git a/libvips/arithmetic/divide.c b/libvips/arithmetic/divide.c index 60b59e56..000fbcf4 100644 --- a/libvips/arithmetic/divide.c +++ b/libvips/arithmetic/divide.c @@ -131,7 +131,7 @@ G_DEFINE_TYPE( VipsDivide, vips_divide, VIPS_TYPE_BINARY ); q[0] = 0.0; \ q[1] = 0.0; \ } \ - else if( fabs( right[0] ) > fabs( right[1] ) ) { \ + else if( VIPS_FABS( right[0] ) > VIPS_FABS( right[1] ) ) { \ double a = right[1] / right[0]; \ double b = right[0] + right[1] * a; \ \ diff --git a/libvips/arithmetic/linear.c b/libvips/arithmetic/linear.c index d113c97f..9aba5054 100644 --- a/libvips/arithmetic/linear.c +++ b/libvips/arithmetic/linear.c @@ -241,7 +241,7 @@ vips_linear_build( VipsObject *object ) for( x = 0; x < sz; x++ ) { \ float t = a1 * p[x] + b1; \ \ - q[x] = VIPS_CLIP( 0, t, 255 ); \ + q[x] = VIPS_FCLIP( 0, t, 255 ); \ } \ } @@ -255,7 +255,7 @@ vips_linear_build( VipsObject *object ) for( k = 0; k < nb; k++, i++ ) { \ double t = a[k] * p[i] + b[k]; \ \ - q[i] = VIPS_CLIP( 0, t, 255 ); \ + q[i] = VIPS_FCLIP( 0, t, 255 ); \ } \ } @@ -278,7 +278,7 @@ vips_linear_build( VipsObject *object ) for( k = 0; k < nb; k++, i++ ) { \ double t = a[k] * p[0] + b[k]; \ \ - q[i] = VIPS_CLIP( 0, t, 255 ); \ + q[i] = VIPS_FCLIP( 0, t, 255 ); \ p += 2; \ } \ } diff --git a/libvips/arithmetic/measure.c b/libvips/arithmetic/measure.c index 9497799c..67d6feb6 100644 --- a/libvips/arithmetic/measure.c +++ b/libvips/arithmetic/measure.c @@ -163,7 +163,8 @@ vips_measure_build( VipsObject *object ) * averages near zero (can get these if use * measure on IM_TYPE_LAB images). */ - if( dev * 5 > fabs( avg ) && fabs( avg ) > 3 ) + if( dev * 5 > VIPS_FABS( avg ) && + VIPS_FABS( avg ) > 3 ) vips_warn( class->nickname, _( "patch %d x %d, band %d: " "avg = %g, sdev = %g" ), diff --git a/libvips/arithmetic/stats.c b/libvips/arithmetic/stats.c index 345275ca..2e170a06 100644 --- a/libvips/arithmetic/stats.c +++ b/libvips/arithmetic/stats.c @@ -159,12 +159,12 @@ vips_stats_build( VipsObject *object ) double *row = VIPS_MATRIX( stats->out, 0, y ); row[COL_AVG] = row[COL_SUM] / pels; - row[COL_SD] = sqrt( fabs( row[COL_SUM2] - + row[COL_SD] = sqrt( VIPS_FABS( row[COL_SUM2] - (row[COL_SUM] * row[COL_SUM] / pels) ) / (pels - 1) ); } row0[COL_AVG] = row0[COL_SUM] / vals; - row0[COL_SD] = sqrt( fabs( row0[COL_SUM2] - + row0[COL_SD] = sqrt( VIPS_FABS( row0[COL_SUM2] - (row0[COL_SUM] * row0[COL_SUM] / vals) ) / (vals - 1) ); return( 0 ); diff --git a/libvips/arithmetic/unaryconst.c b/libvips/arithmetic/unaryconst.c index 679987e1..e95dc78e 100644 --- a/libvips/arithmetic/unaryconst.c +++ b/libvips/arithmetic/unaryconst.c @@ -57,7 +57,7 @@ G_DEFINE_ABSTRACT_TYPE( VipsUnaryConst, vips_unary_const, VIPS_TYPE_UNARY ); for( i = 0; i < m; i++ ) { \ double v = p[VIPS_MIN( n - 1, i )]; \ \ - tq[i] = (TYPE) VIPS_CLIP( N, v, X ); \ + tq[i] = (TYPE) VIPS_FCLIP( N, v, X ); \ } \ } diff --git a/libvips/colour/HSV2sRGB.c b/libvips/colour/HSV2sRGB.c index 519e9a60..e9835234 100644 --- a/libvips/colour/HSV2sRGB.c +++ b/libvips/colour/HSV2sRGB.c @@ -52,43 +52,50 @@ typedef VipsColourCodeClass VipsHSV2sRGBClass; G_DEFINE_TYPE( VipsHSV2sRGB, vips_HSV2sRGB, VIPS_TYPE_COLOUR_CODE ); -static void vips_HSV2sRGB_line(VipsColour *colour, VipsPel *out, VipsPel **in, - int width) { +static void +vips_HSV2sRGB_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width ) +{ unsigned char *p = (unsigned char *) in[0]; unsigned char *q = (unsigned char *) out; + int i; - float c, x, m; - for (i = 0; i < width; i++) { + for( i = 0; i < width; i++ ) { + float c, x, m; - c = p[2] * p[1] / 255.0f; - x = c * (1 - fabs(fmod(p[0] / SIXTH_OF_CHAR, 2) - 1)); + c = p[2] * p[1] / 255.0; + x = c * (1 - VIPS_FABS( fmod( p[0] / SIXTH_OF_CHAR, 2 ) - 1 )); m = p[2] - c; - if (p[0] < SIXTH_OF_CHAR) { - q[0]= (c+m); - q[1]= (x+m); - q[2]= (0+m); - } else if (p[0] < 2*SIXTH_OF_CHAR) { - q[0]= (x+m); - q[1]= (c+m); - q[2]= (0+m); - } else if (p[0] < 3*SIXTH_OF_CHAR) { - q[0]= (0+m); - q[1]= (c+m); - q[2]= (x+m); - } else if (p[0] < 4*SIXTH_OF_CHAR) { - q[0]= (0+m); - q[1]= (x+m); - q[2]= (c+m); - } else if (p[0] < 5*SIXTH_OF_CHAR) { - q[0]= (x+m); - q[1]= (0+m); - q[2]= (c+m); - } else { - q[0]= (c+m); - q[1]= (0+m); - q[2]= (x+m); + if( p[0] < SIXTH_OF_CHAR ) { + q[0] = c + m; + q[1] = x + m; + q[2] = 0 + m; + } + else if( p[0] < 2 * SIXTH_OF_CHAR ) { + q[0] = x + m; + q[1] = c + m; + q[2] = 0 + m; + } + else if( p[0] < 3 * SIXTH_OF_CHAR ) { + q[0] = 0 + m; + q[1] = c + m; + q[2] = x + m; + } + else if( p[0] < 4 * SIXTH_OF_CHAR ) { + q[0] = 0 + m; + q[1] = x + m; + q[2] = c + m; + } + else if( p[0] < 5 * SIXTH_OF_CHAR ) { + q[0] = x + m; + q[1] = 0 + m; + q[2] = c + m; + } + else { + q[0] = c + m; + q[1] = 0 + m; + q[2] = x + m; } p += 3; diff --git a/libvips/colour/LCh2UCS.c b/libvips/colour/LCh2UCS.c index da09512b..ffd11511 100644 --- a/libvips/colour/LCh2UCS.c +++ b/libvips/colour/LCh2UCS.c @@ -165,7 +165,7 @@ vips_col_Ch2hcmc( float C, float h ) } P = cos( VIPS_RAD( k7 * h + k8 ) ); - D = k4 + k5 * P * pow( fabs( P ), k6 ); + D = k4 + k5 * P * pow( VIPS_FABS( P ), k6 ); g = C * C * C * C; f = sqrt( g / (g + 1900.0) ); hcmc = h + D * f; diff --git a/libvips/colour/Lab2LabQ.c b/libvips/colour/Lab2LabQ.c index d522c737..01d250c4 100644 --- a/libvips/colour/Lab2LabQ.c +++ b/libvips/colour/Lab2LabQ.c @@ -88,12 +88,13 @@ vips_Lab2LabQ_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width ) float * restrict p = (float *) in[0]; VipsPel * restrict q = out; - float fval; - int lsbs; - int intv; int i; - for( i = 0; i < width; i++) { + for( i = 0; i < width; i++ ) { + float fval; + int lsbs; + int intv; + /* Scale L up to 10 bits. Add 0.5 rather than call VIPS_RINT * for speed. This will not round negatives correctly! But * this does not matter, since L is >0. L*=100.0 -> 1023. @@ -101,19 +102,19 @@ vips_Lab2LabQ_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width ) intv = 10.23 * p[0] + 0.5; /* scale L up to 10 bits */ intv = VIPS_CLIP( 0, intv, 1023 ); 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 */ fval = 8.0 * p[1]; /* do a */ intv = VIPS_RINT( fval ); intv = VIPS_CLIP( -1024, intv, 1023 ); lsbs |= (intv & 0x7) << 3; /* 00000111 -> 00111000 */ - q[1] = (intv >> 3); /* drop bot 3 bits & store */ + q[1] = intv >> 3; /* drop bot 3 bits & store */ fval = 8.0 * p[2]; /* do b */ intv = VIPS_RINT( fval ); intv = VIPS_CLIP( -1024, intv, 1023 ); lsbs |= (intv & 0x7); - q[2] = (intv >> 3); + q[2] = intv >> 3; q[3] = lsbs; /* store lsb band */ diff --git a/libvips/colour/LabS2LabQ.c b/libvips/colour/LabS2LabQ.c index f15090e5..368514a0 100644 --- a/libvips/colour/LabS2LabQ.c +++ b/libvips/colour/LabS2LabQ.c @@ -69,10 +69,11 @@ vips_LabS2LabQ_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width ) unsigned char *q = (unsigned char *) out; int i; - int l, a, b; - unsigned char ext; for( i = 0; i < width; i++ ) { + int l, a, b; + unsigned char ext; + /* Get LAB, rounding to 10, 11, 11. */ l = p[0] + 16; diff --git a/libvips/colour/XYZ2Lab.c b/libvips/colour/XYZ2Lab.c index 9b86ce66..97d9af1d 100644 --- a/libvips/colour/XYZ2Lab.c +++ b/libvips/colour/XYZ2Lab.c @@ -133,15 +133,15 @@ vips_XYZ2Lab_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width ) nZ = QUANT_ELEMENTS * p[2] / XYZ2Lab->Z0; p += 3; - i = VIPS_CLIP( 0, (int) nX, QUANT_ELEMENTS - 2 ); + i = VIPS_FCLIP( 0, nX, QUANT_ELEMENTS - 2 ); f = nX - i; cbx = cbrt_table[i] + f * (cbrt_table[i + 1] - cbrt_table[i]); - i = VIPS_CLIP( 0, (int) nY, QUANT_ELEMENTS - 2 ); + i = VIPS_FCLIP( 0, nY, QUANT_ELEMENTS - 2 ); f = nY - i; cby = cbrt_table[i] + f * (cbrt_table[i + 1] - cbrt_table[i]); - i = VIPS_CLIP( 0, (int) nZ, QUANT_ELEMENTS - 2 ); + i = VIPS_FCLIP( 0, nZ, QUANT_ELEMENTS - 2 ); f = nZ - i; cbz = cbrt_table[i] + f * (cbrt_table[i + 1] - cbrt_table[i]); diff --git a/libvips/colour/dE00.c b/libvips/colour/dE00.c index 3dfb304f..6c2d203d 100644 --- a/libvips/colour/dE00.c +++ b/libvips/colour/dE00.c @@ -132,9 +132,9 @@ vips_col_dE00( float L1, float a1, float b1, */ double Ldb = (L1d + L2d) / 2; double Cdb = (C1d + C2d) / 2; - double hdb = fabs( h1d - h2d ) < 180 ? + double hdb = VIPS_FABS( h1d - h2d ) < 180 ? (h1d + h2d) / 2 : - fabs( h1d + h2d - 360 ) / 2; + VIPS_FABS( h1d + h2d - 360 ) / 2; /* dtheta, RC */ @@ -161,7 +161,7 @@ vips_col_dE00( float L1, float a1, float b1, /* hue difference ... careful! */ - double dhd = fabs( h1d - h2d ) < 180 ? + double dhd = VIPS_FABS( h1d - h2d ) < 180 ? h1d - h2d : 360 - (h1d - h2d); diff --git a/libvips/colour/sRGB2HSV.c b/libvips/colour/sRGB2HSV.c index e74634e8..5dca321c 100644 --- a/libvips/colour/sRGB2HSV.c +++ b/libvips/colour/sRGB2HSV.c @@ -52,61 +52,71 @@ vips_sRGB2HSV_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width ) { unsigned char *p = (unsigned char *) in[0]; unsigned char *q = (unsigned char *) out; + int i; - unsigned char c_max,c_min,delta; - - float wrap_around_hue, secondary_diff; - - for( i = 0; i < width; i++ ) { + unsigned char c_max; + unsigned char c_min; + float secondary_diff; + float wrap_around_hue; - if (p[1] < p[2]) { - if (p[2] < p[0]) { - // Center red (at top) + if( p[1] < p[2] ) { + if( p[2] < p[0] ) { + /* Center red (at top). + */ c_max = p[0]; c_min = p[1]; secondary_diff = p[1] - p[2]; - wrap_around_hue = 255.0f; - } else { - // Center blue + wrap_around_hue = 255.0; + } + else { + /* Center blue. + */ c_max = p[2]; - c_min = VIPS_MIN(p[1], p[0]); + c_min = VIPS_MIN( p[1], p[0] ); secondary_diff = p[0] - p[1]; - wrap_around_hue = 170.0f; + wrap_around_hue = 170.0; } - } else { - if (p[1] < p[0]) { - // Center red (at bottom) + } + else { + if( p[1] < p[0] ) { + /* Center red (at bottom) + */ c_max = p[0]; c_min = p[2]; secondary_diff = p[1] - p[2]; - wrap_around_hue = 0.0f; - } else { - // Center green + wrap_around_hue = 0.0; + } + else { + /* Center green + */ c_max = p[1]; - c_min = VIPS_MIN(p[2], p[0]); + c_min = VIPS_MIN( p[2], p[0] ); secondary_diff = p[2] - p[0]; - wrap_around_hue = 85.0f; + wrap_around_hue = 85.0; } } - if (c_max == 0) { + if( c_max == 0 ) { q[0] = 0; q[1] = 0; q[2] = 0; - } else { + } + else { + unsigned char delta; + q[2] = c_max; delta = c_max - c_min; - if (delta == 0) { + if( delta == 0 ) q[0] = 0; - } else { - q[0] = (42.5f*(secondary_diff / (float) delta) + wrap_around_hue); - } + else + q[0] = 42.5 * (secondary_diff / (float) delta) + + wrap_around_hue; - q[1] = (( delta*255.0f / (float) c_max)); + q[1] = delta * 255.0 / (float) c_max; } p += 3; diff --git a/libvips/colour/scRGB2BW.c b/libvips/colour/scRGB2BW.c index f961f1a2..3d5803a7 100644 --- a/libvips/colour/scRGB2BW.c +++ b/libvips/colour/scRGB2BW.c @@ -113,7 +113,7 @@ vips_scRGB2BW_line_16( unsigned short * restrict q, float * restrict p, q += 1; for( j = 0; j < extra_bands; j++ ) - q[j] = VIPS_CLIP( 0, p[j] * 256.0, USHRT_MAX ); + q[j] = VIPS_FCLIP( 0, p[j] * 256.0, USHRT_MAX ); p += extra_bands; q += extra_bands; } diff --git a/libvips/colour/scRGB2sRGB.c b/libvips/colour/scRGB2sRGB.c index 1102d117..6e3f2a78 100644 --- a/libvips/colour/scRGB2sRGB.c +++ b/libvips/colour/scRGB2sRGB.c @@ -142,7 +142,7 @@ vips_scRGB2sRGB_line_16( unsigned short * restrict q, float * restrict p, q += 3; for( j = 0; j < extra_bands; j++ ) - q[j] = VIPS_CLIP( 0, p[j] * 256.0, USHRT_MAX ); + q[j] = VIPS_FCLIP( 0, p[j] * 256.0, USHRT_MAX ); p += extra_bands; q += extra_bands; } diff --git a/libvips/create/buildlut.c b/libvips/create/buildlut.c index 42881e06..48bfa0f7 100644 --- a/libvips/create/buildlut.c +++ b/libvips/create/buildlut.c @@ -129,7 +129,7 @@ vips_buildlut_build_init( VipsBuildlut *lut ) /* Allow for being a bit off. */ - if( fabs( v - VIPS_RINT( v ) ) > 0.001 ) { + if( VIPS_FABS( v - VIPS_RINT( v ) ) > 0.001 ) { vips_error( class->nickname, _( "x value row %d not an int" ), y ); return( -1 ); diff --git a/libvips/create/logmat.c b/libvips/create/logmat.c index 5b3a480b..64520504 100644 --- a/libvips/create/logmat.c +++ b/libvips/create/logmat.c @@ -138,7 +138,7 @@ vips_logmat_build( VipsObject *object ) * is less than the min. */ if( val - last >= 0 && - fabs( val ) < logmat->min_ampl ) + VIPS_FABS( val ) < logmat->min_ampl ) break; last = val; diff --git a/libvips/foreign/ppm.c b/libvips/foreign/ppm.c index 8b70cb16..bc5334ca 100644 --- a/libvips/foreign/ppm.c +++ b/libvips/foreign/ppm.c @@ -204,7 +204,7 @@ read_header( FILE *fp, VipsImage *out, int *bits, int *ascii, int *msb_first ) */ *msb_first = scale > 0; vips_image_set_double( out, - "pfm-scale", fabs( scale ) ); + "pfm-scale", VIPS_FABS( scale ) ); } else { int max_value; diff --git a/libvips/foreign/vips2jpeg.c b/libvips/foreign/vips2jpeg.c index dc153732..71b71ae2 100644 --- a/libvips/foreign/vips2jpeg.c +++ b/libvips/foreign/vips2jpeg.c @@ -398,7 +398,7 @@ vips_exif_set_double( ExifData *ed, rv = exif_get_rational( entry->data + offset, bo ); old_value = (double) rv.numerator / rv.denominator; - if( fabs( old_value - value ) > 0.0001 ) { + if( VIPS_FABS( old_value - value ) > 0.0001 ) { vips_exif_double_to_rational( value, &rv ); VIPS_DEBUG_MSG( "vips_exif_set_double: %u / %u\n", @@ -413,7 +413,7 @@ vips_exif_set_double( ExifData *ed, srv = exif_get_srational( entry->data + offset, bo ); old_value = (double) srv.numerator / srv.denominator; - if( fabs( old_value - value ) > 0.0001 ) { + if( VIPS_FABS( old_value - value ) > 0.0001 ) { vips_exif_double_to_srational( value, &srv ); VIPS_DEBUG_MSG( "vips_exif_set_double: %d / %d\n", diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index cb6c3bbd..32c14998 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -573,9 +573,9 @@ write_tiff_header( Write *write, Layer *layer ) */ TIFFSetField( tif, TIFFTAG_RESOLUTIONUNIT, write->resunit ); TIFFSetField( tif, TIFFTAG_XRESOLUTION, - VIPS_CLIP( 0.01, write->xres, 1000000 ) ); + VIPS_FCLIP( 0.01, write->xres, 1000000 ) ); TIFFSetField( tif, TIFFTAG_YRESOLUTION, - VIPS_CLIP( 0.01, write->yres, 1000000 ) ); + VIPS_FCLIP( 0.01, write->yres, 1000000 ) ); if( write_embed_profile( write, tif ) || write_embed_xmp( write, tif ) || diff --git a/libvips/include/vips/util.h b/libvips/include/vips/util.h index d67b89a0..20288d6e 100644 --- a/libvips/include/vips/util.h +++ b/libvips/include/vips/util.h @@ -58,6 +58,31 @@ extern "C" { #define VIPS_CLIP( A, V, B ) VIPS_MAX( (A), VIPS_MIN( (B), (V) ) ) #define VIPS_NUMBER( R ) ((int) (sizeof(R) / sizeof(R[0]))) +/* The built-in isnan and isinf functions provided by gcc 4+ and clang are + * up to 7x faster than their libc equivalent included from . + */ +#if defined(__clang__) || (__GNUC__ >= 4) +#define VIPS_ISNAN( V ) __builtin_isnan( V ) +#define VIPS_ISINF( V ) __builtin_isinf( V ) +#define VIPS_FLOOR( V ) __builtin_floor( V ) +#define VIPS_CEIL( V ) __builtin_ceil( V ) +#define VIPS_RINT( V ) __builtin_rint( V ) +#define VIPS_FABS( V ) __builtin_fabs( V ) +#define VIPS_FMAX( A, B ) __builtin_fmax( A, B ) +#define VIPS_FMIN( A, B ) __builtin_fmin( A, B ) +#else +#define VIPS_ISNAN( V ) isnan( V ) +#define VIPS_ISINF( V ) isinf( V ) +#define VIPS_FLOOR( V ) floor( V ) +#define VIPS_CEIL( V ) ceil( V ) +#define VIPS_RINT( R ) ((int) ((R) > 0 ? ((R) + 0.5) : ((R) - 0.5))) +#define VIPS_FABS( V ) VIPS_FABS( V ) +#define VIPS_FMAX( A, B ) VIPS_MAX( A, B ) +#define VIPS_FMIN( A, B ) VIPS_MIN( A, B ) +#endif + +#define VIPS_FCLIP( A, V, B ) VIPS_FMAX( (A), VIPS_FMIN( (B), (V) ) ) + #define VIPS_SWAP( TYPE, A, B ) \ G_STMT_START { \ TYPE t = (A); \ @@ -155,23 +180,6 @@ G_STMT_START { \ #define VIPS_CLIP_NONE( V, SEQ ) {} -/* The built-in isnan and isinf functions provided by gcc 4+ and clang are - * up to 7x faster than their libc equivalent included from . - */ -#if defined(__clang__) || (__GNUC__ >= 4) -#define VIPS_ISNAN( V ) __builtin_isnan( V ) -#define VIPS_ISINF( V ) __builtin_isinf( V ) -#define VIPS_FLOOR( V ) __builtin_floor( V ) -#define VIPS_CEIL( V ) __builtin_ceil( V ) -#define VIPS_RINT( V ) __builtin_rint( V ) -#else -#define VIPS_ISNAN( V ) isnan( V ) -#define VIPS_ISINF( V ) isinf( V ) -#define VIPS_FLOOR( V ) floor( V ) -#define VIPS_CEIL( V ) ceil( V ) -#define VIPS_RINT( R ) ((int) ((R) > 0 ? ((R) + 0.5) : ((R) - 0.5))) -#endif - /* Not all platforms have PATH_MAX (eg. Hurd) and we don't need a platform one * anyway, just a static buffer big enough for almost any path. */