Home | History | Annotate | Download | only in tests
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 #include "Test.h"
      9 #include "SkFloatBits.h"
     10 #include "SkFloatingPoint.h"
     11 #include "SkMathPriv.h"
     12 #include "SkPoint.h"
     13 #include "SkRandom.h"
     14 #include "SkColorPriv.h"
     15 
     16 static float sk_fsel(float pred, float result_ge, float result_lt) {
     17     return pred >= 0 ? result_ge : result_lt;
     18 }
     19 
     20 static float fast_floor(float x) {
     21 //    float big = sk_fsel(x, 0x1.0p+23, -0x1.0p+23);
     22     float big = sk_fsel(x, (float)(1 << 23), -(float)(1 << 23));
     23     return (float)(x + big) - big;
     24 }
     25 
     26 static float std_floor(float x) {
     27     return sk_float_floor(x);
     28 }
     29 
     30 static void test_floor_value(skiatest::Reporter* reporter, float value) {
     31     float fast = fast_floor(value);
     32     float std = std_floor(value);
     33     REPORTER_ASSERT(reporter, std == fast);
     34 //    SkDebugf("value[%1.9f] std[%g] fast[%g] equal[%d]\n",
     35 //             value, std, fast, std == fast);
     36 }
     37 
     38 static void test_floor(skiatest::Reporter* reporter) {
     39     static const float gVals[] = {
     40         0, 1, 1.1f, 1.01f, 1.001f, 1.0001f, 1.00001f, 1.000001f, 1.0000001f
     41     };
     42 
     43     for (size_t i = 0; i < SK_ARRAY_COUNT(gVals); ++i) {
     44         test_floor_value(reporter, gVals[i]);
     45 //        test_floor_value(reporter, -gVals[i]);
     46     }
     47 }
     48 
     49 ///////////////////////////////////////////////////////////////////////////////
     50 
     51 static float float_blend(int src, int dst, float unit) {
     52     return dst + (src - dst) * unit;
     53 }
     54 
     55 static int blend31(int src, int dst, int a31) {
     56     return dst + ((src - dst) * a31 * 2114 >> 16);
     57     //    return dst + ((src - dst) * a31 * 33 >> 10);
     58 }
     59 
     60 static int blend31_slow(int src, int dst, int a31) {
     61     int prod = src * a31 + (31 - a31) * dst + 16;
     62     prod = (prod + (prod >> 5)) >> 5;
     63     return prod;
     64 }
     65 
     66 static int blend31_round(int src, int dst, int a31) {
     67     int prod = (src - dst) * a31 + 16;
     68     prod = (prod + (prod >> 5)) >> 5;
     69     return dst + prod;
     70 }
     71 
     72 static int blend31_old(int src, int dst, int a31) {
     73     a31 += a31 >> 4;
     74     return dst + ((src - dst) * a31 >> 5);
     75 }
     76 
     77 // suppress unused code warning
     78 static int (*blend_functions[])(int, int, int) = {
     79     blend31,
     80     blend31_slow,
     81     blend31_round,
     82     blend31_old
     83 };
     84 
     85 static void test_blend31() {
     86     int failed = 0;
     87     int death = 0;
     88     if (false) { // avoid bit rot, suppress warning
     89         failed = (*blend_functions[0])(0,0,0);
     90     }
     91     for (int src = 0; src <= 255; src++) {
     92         for (int dst = 0; dst <= 255; dst++) {
     93             for (int a = 0; a <= 31; a++) {
     94 //                int r0 = blend31(src, dst, a);
     95 //                int r0 = blend31_round(src, dst, a);
     96 //                int r0 = blend31_old(src, dst, a);
     97                 int r0 = blend31_slow(src, dst, a);
     98 
     99                 float f = float_blend(src, dst, a / 31.f);
    100                 int r1 = (int)f;
    101                 int r2 = SkScalarRoundToInt(SkFloatToScalar(f));
    102 
    103                 if (r0 != r1 && r0 != r2) {
    104                     printf("src:%d dst:%d a:%d result:%d float:%g\n",
    105                                  src, dst, a, r0, f);
    106                     failed += 1;
    107                 }
    108                 if (r0 > 255) {
    109                     death += 1;
    110                     printf("death src:%d dst:%d a:%d result:%d float:%g\n",
    111                            src, dst, a, r0, f);
    112                 }
    113             }
    114         }
    115     }
    116     SkDebugf("---- failed %d death %d\n", failed, death);
    117 }
    118 
    119 static void test_blend(skiatest::Reporter* reporter) {
    120     for (int src = 0; src <= 255; src++) {
    121         for (int dst = 0; dst <= 255; dst++) {
    122             for (int a = 0; a <= 255; a++) {
    123                 int r0 = SkAlphaBlend255(src, dst, a);
    124                 float f1 = float_blend(src, dst, a / 255.f);
    125                 int r1 = SkScalarRoundToInt(SkFloatToScalar(f1));
    126 
    127                 if (r0 != r1) {
    128                     float diff = sk_float_abs(f1 - r1);
    129                     diff = sk_float_abs(diff - 0.5f);
    130                     if (diff > (1 / 255.f)) {
    131 #ifdef SK_DEBUG
    132                         SkDebugf("src:%d dst:%d a:%d result:%d float:%g\n",
    133                                  src, dst, a, r0, f1);
    134 #endif
    135                         REPORTER_ASSERT(reporter, false);
    136                     }
    137                 }
    138             }
    139         }
    140     }
    141 }
    142 
    143 #if defined(SkLONGLONG)
    144 static int symmetric_fixmul(int a, int b) {
    145     int sa = SkExtractSign(a);
    146     int sb = SkExtractSign(b);
    147 
    148     a = SkApplySign(a, sa);
    149     b = SkApplySign(b, sb);
    150 
    151 #if 1
    152     int c = (int)(((SkLONGLONG)a * b) >> 16);
    153 
    154     return SkApplySign(c, sa ^ sb);
    155 #else
    156     SkLONGLONG ab = (SkLONGLONG)a * b;
    157     if (sa ^ sb) {
    158         ab = -ab;
    159     }
    160     return ab >> 16;
    161 #endif
    162 }
    163 #endif
    164 
    165 static void check_length(skiatest::Reporter* reporter,
    166                          const SkPoint& p, SkScalar targetLen) {
    167     float x = SkScalarToFloat(p.fX);
    168     float y = SkScalarToFloat(p.fY);
    169     float len = sk_float_sqrt(x*x + y*y);
    170 
    171     len /= SkScalarToFloat(targetLen);
    172 
    173     REPORTER_ASSERT(reporter, len > 0.999f && len < 1.001f);
    174 }
    175 
    176 static float nextFloat(SkRandom& rand) {
    177     SkFloatIntUnion data;
    178     data.fSignBitInt = rand.nextU();
    179     return data.fFloat;
    180 }
    181 
    182 /*  returns true if a == b as resulting from (int)x. Since it is undefined
    183  what to do if the float exceeds 2^32-1, we check for that explicitly.
    184  */
    185 static bool equal_float_native_skia(float x, uint32_t ni, uint32_t si) {
    186     if (!(x == x)) {    // NAN
    187         return ((int32_t)si) == SK_MaxS32 || ((int32_t)si) == SK_MinS32;
    188     }
    189     // for out of range, C is undefined, but skia always should return NaN32
    190     if (x > SK_MaxS32) {
    191         return ((int32_t)si) == SK_MaxS32;
    192     }
    193     if (x < -SK_MaxS32) {
    194         return ((int32_t)si) == SK_MinS32;
    195     }
    196     return si == ni;
    197 }
    198 
    199 static void assert_float_equal(skiatest::Reporter* reporter, const char op[],
    200                                float x, uint32_t ni, uint32_t si) {
    201     if (!equal_float_native_skia(x, ni, si)) {
    202         SkString desc;
    203         uint32_t xi = SkFloat2Bits(x);
    204         desc.printf("%s float %g bits %x native %x skia %x\n", op, x, xi, ni, si);
    205         reporter->reportFailed(desc);
    206     }
    207 }
    208 
    209 static void test_float_cast(skiatest::Reporter* reporter, float x) {
    210     int ix = (int)x;
    211     int iix = SkFloatToIntCast(x);
    212     assert_float_equal(reporter, "cast", x, ix, iix);
    213 }
    214 
    215 static void test_float_floor(skiatest::Reporter* reporter, float x) {
    216     int ix = (int)floor(x);
    217     int iix = SkFloatToIntFloor(x);
    218     assert_float_equal(reporter, "floor", x, ix, iix);
    219 }
    220 
    221 static void test_float_round(skiatest::Reporter* reporter, float x) {
    222     double xx = x + 0.5;    // need intermediate double to avoid temp loss
    223     int ix = (int)floor(xx);
    224     int iix = SkFloatToIntRound(x);
    225     assert_float_equal(reporter, "round", x, ix, iix);
    226 }
    227 
    228 static void test_float_ceil(skiatest::Reporter* reporter, float x) {
    229     int ix = (int)ceil(x);
    230     int iix = SkFloatToIntCeil(x);
    231     assert_float_equal(reporter, "ceil", x, ix, iix);
    232 }
    233 
    234 static void test_float_conversions(skiatest::Reporter* reporter, float x) {
    235     test_float_cast(reporter, x);
    236     test_float_floor(reporter, x);
    237     test_float_round(reporter, x);
    238     test_float_ceil(reporter, x);
    239 }
    240 
    241 static void test_int2float(skiatest::Reporter* reporter, int ival) {
    242     float x0 = (float)ival;
    243     float x1 = SkIntToFloatCast(ival);
    244     float x2 = SkIntToFloatCast_NoOverflowCheck(ival);
    245     REPORTER_ASSERT(reporter, x0 == x1);
    246     REPORTER_ASSERT(reporter, x0 == x2);
    247 }
    248 
    249 static void unittest_fastfloat(skiatest::Reporter* reporter) {
    250     SkRandom rand;
    251     size_t i;
    252 
    253     static const float gFloats[] = {
    254         0.f, 1.f, 0.5f, 0.499999f, 0.5000001f, 1.f/3,
    255         0.000000001f, 1000000000.f,     // doesn't overflow
    256         0.0000000001f, 10000000000.f    // does overflow
    257     };
    258     for (i = 0; i < SK_ARRAY_COUNT(gFloats); i++) {
    259         test_float_conversions(reporter, gFloats[i]);
    260         test_float_conversions(reporter, -gFloats[i]);
    261     }
    262 
    263     for (int outer = 0; outer < 100; outer++) {
    264         rand.setSeed(outer);
    265         for (i = 0; i < 100000; i++) {
    266             float x = nextFloat(rand);
    267             test_float_conversions(reporter, x);
    268         }
    269 
    270         test_int2float(reporter, 0);
    271         test_int2float(reporter, 1);
    272         test_int2float(reporter, -1);
    273         for (i = 0; i < 100000; i++) {
    274             // for now only test ints that are 24bits or less, since we don't
    275             // round (down) large ints the same as IEEE...
    276             int ival = rand.nextU() & 0xFFFFFF;
    277             test_int2float(reporter, ival);
    278             test_int2float(reporter, -ival);
    279         }
    280     }
    281 }
    282 
    283 #ifdef SK_SCALAR_IS_FLOAT
    284 static float make_zero() {
    285     return sk_float_sin(0);
    286 }
    287 #endif
    288 
    289 static void unittest_isfinite(skiatest::Reporter* reporter) {
    290 #ifdef SK_SCALAR_IS_FLOAT
    291     float nan = sk_float_asin(2);
    292     float inf = 1.0f / make_zero();
    293     float big = 3.40282e+038f;
    294 
    295     REPORTER_ASSERT(reporter, !SkScalarIsNaN(inf));
    296     REPORTER_ASSERT(reporter, !SkScalarIsNaN(-inf));
    297     REPORTER_ASSERT(reporter, !SkScalarIsFinite(inf));
    298     REPORTER_ASSERT(reporter, !SkScalarIsFinite(-inf));
    299 #else
    300     SkFixed nan = SK_FixedNaN;
    301     SkFixed big = SK_FixedMax;
    302 #endif
    303 
    304     REPORTER_ASSERT(reporter,  SkScalarIsNaN(nan));
    305     REPORTER_ASSERT(reporter, !SkScalarIsNaN(big));
    306     REPORTER_ASSERT(reporter, !SkScalarIsNaN(-big));
    307     REPORTER_ASSERT(reporter, !SkScalarIsNaN(0));
    308 
    309     REPORTER_ASSERT(reporter, !SkScalarIsFinite(nan));
    310     REPORTER_ASSERT(reporter,  SkScalarIsFinite(big));
    311     REPORTER_ASSERT(reporter,  SkScalarIsFinite(-big));
    312     REPORTER_ASSERT(reporter,  SkScalarIsFinite(0));
    313 }
    314 
    315 static void test_muldiv255(skiatest::Reporter* reporter) {
    316     for (int a = 0; a <= 255; a++) {
    317         for (int b = 0; b <= 255; b++) {
    318             int ab = a * b;
    319             float s = ab / 255.0f;
    320             int round = (int)floorf(s + 0.5f);
    321             int trunc = (int)floorf(s);
    322 
    323             int iround = SkMulDiv255Round(a, b);
    324             int itrunc = SkMulDiv255Trunc(a, b);
    325 
    326             REPORTER_ASSERT(reporter, iround == round);
    327             REPORTER_ASSERT(reporter, itrunc == trunc);
    328 
    329             REPORTER_ASSERT(reporter, itrunc <= iround);
    330             REPORTER_ASSERT(reporter, iround <= a);
    331             REPORTER_ASSERT(reporter, iround <= b);
    332         }
    333     }
    334 }
    335 
    336 static void test_muldiv255ceiling(skiatest::Reporter* reporter) {
    337     for (int c = 0; c <= 255; c++) {
    338         for (int a = 0; a <= 255; a++) {
    339             int product = (c * a + 255);
    340             int expected_ceiling = (product + (product >> 8)) >> 8;
    341             int webkit_ceiling = (c * a + 254) / 255;
    342             REPORTER_ASSERT(reporter, expected_ceiling == webkit_ceiling);
    343             int skia_ceiling = SkMulDiv255Ceiling(c, a);
    344             REPORTER_ASSERT(reporter, skia_ceiling == webkit_ceiling);
    345         }
    346     }
    347 }
    348 
    349 static void test_copysign(skiatest::Reporter* reporter) {
    350     static const int32_t gTriples[] = {
    351         // x, y, expected result
    352         0, 0, 0,
    353         0, 1, 0,
    354         0, -1, 0,
    355         1, 0, 1,
    356         1, 1, 1,
    357         1, -1, -1,
    358         -1, 0, 1,
    359         -1, 1, 1,
    360         -1, -1, -1,
    361     };
    362     for (size_t i = 0; i < SK_ARRAY_COUNT(gTriples); i += 3) {
    363         REPORTER_ASSERT(reporter,
    364                         SkCopySign32(gTriples[i], gTriples[i+1]) == gTriples[i+2]);
    365         float x = (float)gTriples[i];
    366         float y = (float)gTriples[i+1];
    367         float expected = (float)gTriples[i+2];
    368         REPORTER_ASSERT(reporter, sk_float_copysign(x, y) == expected);
    369     }
    370 
    371     SkRandom rand;
    372     for (int j = 0; j < 1000; j++) {
    373         int ix = rand.nextS();
    374         REPORTER_ASSERT(reporter, SkCopySign32(ix, ix) == ix);
    375         REPORTER_ASSERT(reporter, SkCopySign32(ix, -ix) == -ix);
    376         REPORTER_ASSERT(reporter, SkCopySign32(-ix, ix) == ix);
    377         REPORTER_ASSERT(reporter, SkCopySign32(-ix, -ix) == -ix);
    378 
    379         SkScalar sx = rand.nextSScalar1();
    380         REPORTER_ASSERT(reporter, SkScalarCopySign(sx, sx) == sx);
    381         REPORTER_ASSERT(reporter, SkScalarCopySign(sx, -sx) == -sx);
    382         REPORTER_ASSERT(reporter, SkScalarCopySign(-sx, sx) == sx);
    383         REPORTER_ASSERT(reporter, SkScalarCopySign(-sx, -sx) == -sx);
    384     }
    385 }
    386 
    387 static void TestMath(skiatest::Reporter* reporter) {
    388     int         i;
    389     int32_t     x;
    390     SkRandom    rand;
    391 
    392     // these should assert
    393 #if 0
    394     SkToS8(128);
    395     SkToS8(-129);
    396     SkToU8(256);
    397     SkToU8(-5);
    398 
    399     SkToS16(32768);
    400     SkToS16(-32769);
    401     SkToU16(65536);
    402     SkToU16(-5);
    403 
    404     if (sizeof(size_t) > 4) {
    405         SkToS32(4*1024*1024);
    406         SkToS32(-4*1024*1024);
    407         SkToU32(5*1024*1024);
    408         SkToU32(-5);
    409     }
    410 #endif
    411 
    412     test_muldiv255(reporter);
    413     test_muldiv255ceiling(reporter);
    414     test_copysign(reporter);
    415 
    416     {
    417         SkScalar x = SK_ScalarNaN;
    418         REPORTER_ASSERT(reporter, SkScalarIsNaN(x));
    419     }
    420 
    421     for (i = 1; i <= 10; i++) {
    422         x = SkCubeRootBits(i*i*i, 11);
    423         REPORTER_ASSERT(reporter, x == i);
    424     }
    425 
    426     x = SkFixedSqrt(SK_Fixed1);
    427     REPORTER_ASSERT(reporter, x == SK_Fixed1);
    428     x = SkFixedSqrt(SK_Fixed1/4);
    429     REPORTER_ASSERT(reporter, x == SK_Fixed1/2);
    430     x = SkFixedSqrt(SK_Fixed1*4);
    431     REPORTER_ASSERT(reporter, x == SK_Fixed1*2);
    432 
    433     x = SkFractSqrt(SK_Fract1);
    434     REPORTER_ASSERT(reporter, x == SK_Fract1);
    435     x = SkFractSqrt(SK_Fract1/4);
    436     REPORTER_ASSERT(reporter, x == SK_Fract1/2);
    437     x = SkFractSqrt(SK_Fract1/16);
    438     REPORTER_ASSERT(reporter, x == SK_Fract1/4);
    439 
    440     for (i = 1; i < 100; i++) {
    441         x = SkFixedSqrt(SK_Fixed1 * i * i);
    442         REPORTER_ASSERT(reporter, x == SK_Fixed1 * i);
    443     }
    444 
    445     for (i = 0; i < 1000; i++) {
    446         int value = rand.nextS16();
    447         int max = rand.nextU16();
    448 
    449         int clamp = SkClampMax(value, max);
    450         int clamp2 = value < 0 ? 0 : (value > max ? max : value);
    451         REPORTER_ASSERT(reporter, clamp == clamp2);
    452     }
    453 
    454     for (i = 0; i < 10000; i++) {
    455         SkPoint p;
    456 
    457         // These random values are being treated as 32-bit-patterns, not as
    458         // ints; calling SkIntToScalar() here produces crashes.
    459         p.setLength((SkScalar) rand.nextS(),
    460                     (SkScalar) rand.nextS(),
    461                     SK_Scalar1);
    462         check_length(reporter, p, SK_Scalar1);
    463         p.setLength((SkScalar) (rand.nextS() >> 13),
    464                     (SkScalar) (rand.nextS() >> 13),
    465                     SK_Scalar1);
    466         check_length(reporter, p, SK_Scalar1);
    467     }
    468 
    469     {
    470         SkFixed result = SkFixedDiv(100, 100);
    471         REPORTER_ASSERT(reporter, result == SK_Fixed1);
    472         result = SkFixedDiv(1, SK_Fixed1);
    473         REPORTER_ASSERT(reporter, result == 1);
    474     }
    475 
    476     unittest_fastfloat(reporter);
    477     unittest_isfinite(reporter);
    478 
    479 #ifdef SkLONGLONG
    480     for (i = 0; i < 10000; i++) {
    481         SkFixed numer = rand.nextS();
    482         SkFixed denom = rand.nextS();
    483         SkFixed result = SkFixedDiv(numer, denom);
    484         SkLONGLONG check = ((SkLONGLONG)numer << 16) / denom;
    485 
    486         (void)SkCLZ(numer);
    487         (void)SkCLZ(denom);
    488 
    489         REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32);
    490         if (check > SK_MaxS32) {
    491             check = SK_MaxS32;
    492         } else if (check < -SK_MaxS32) {
    493             check = SK_MinS32;
    494         }
    495         REPORTER_ASSERT(reporter, result == (int32_t)check);
    496 
    497         result = SkFractDiv(numer, denom);
    498         check = ((SkLONGLONG)numer << 30) / denom;
    499 
    500         REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32);
    501         if (check > SK_MaxS32) {
    502             check = SK_MaxS32;
    503         } else if (check < -SK_MaxS32) {
    504             check = SK_MinS32;
    505         }
    506         REPORTER_ASSERT(reporter, result == (int32_t)check);
    507 
    508         // make them <= 2^24, so we don't overflow in fixmul
    509         numer = numer << 8 >> 8;
    510         denom = denom << 8 >> 8;
    511 
    512         result = SkFixedMul(numer, denom);
    513         SkFixed r2 = symmetric_fixmul(numer, denom);
    514         //        SkASSERT(result == r2);
    515 
    516         result = SkFixedMul(numer, numer);
    517         r2 = SkFixedSquare(numer);
    518         REPORTER_ASSERT(reporter, result == r2);
    519 
    520         if (numer >= 0 && denom >= 0) {
    521             SkFixed mean = SkFixedMean(numer, denom);
    522             float prod = SkFixedToFloat(numer) * SkFixedToFloat(denom);
    523             float fm = sk_float_sqrt(sk_float_abs(prod));
    524             SkFixed mean2 = SkFloatToFixed(fm);
    525             int diff = SkAbs32(mean - mean2);
    526             REPORTER_ASSERT(reporter, diff <= 1);
    527         }
    528 
    529         {
    530             SkFixed mod = SkFixedMod(numer, denom);
    531             float n = SkFixedToFloat(numer);
    532             float d = SkFixedToFloat(denom);
    533             float m = sk_float_mod(n, d);
    534             // ensure the same sign
    535             REPORTER_ASSERT(reporter, mod == 0 || (mod < 0) == (m < 0));
    536             int diff = SkAbs32(mod - SkFloatToFixed(m));
    537             REPORTER_ASSERT(reporter, (diff >> 7) == 0);
    538         }
    539     }
    540 #endif
    541 
    542     for (i = 0; i < 10000; i++) {
    543         SkFract x = rand.nextU() >> 1;
    544         double xx = (double)x / SK_Fract1;
    545         SkFract xr = SkFractSqrt(x);
    546         SkFract check = SkFloatToFract(sqrt(xx));
    547         REPORTER_ASSERT(reporter, xr == check ||
    548                                   xr == check-1 ||
    549                                   xr == check+1);
    550 
    551         xr = SkFixedSqrt(x);
    552         xx = (double)x / SK_Fixed1;
    553         check = SkFloatToFixed(sqrt(xx));
    554         REPORTER_ASSERT(reporter, xr == check || xr == check-1);
    555 
    556         xr = SkSqrt32(x);
    557         xx = (double)x;
    558         check = (int32_t)sqrt(xx);
    559         REPORTER_ASSERT(reporter, xr == check || xr == check-1);
    560     }
    561 
    562 #if !defined(SK_SCALAR_IS_FLOAT)
    563     {
    564         SkFixed s, c;
    565         s = SkFixedSinCos(0, &c);
    566         REPORTER_ASSERT(reporter, s == 0);
    567         REPORTER_ASSERT(reporter, c == SK_Fixed1);
    568     }
    569 
    570     int maxDiff = 0;
    571     for (i = 0; i < 1000; i++) {
    572         SkFixed rads = rand.nextS() >> 10;
    573         double frads = SkFixedToFloat(rads);
    574 
    575         SkFixed s, c;
    576         s = SkScalarSinCos(rads, &c);
    577 
    578         double fs = sin(frads);
    579         double fc = cos(frads);
    580 
    581         SkFixed is = SkFloatToFixed(fs);
    582         SkFixed ic = SkFloatToFixed(fc);
    583 
    584         maxDiff = SkMax32(maxDiff, SkAbs32(is - s));
    585         maxDiff = SkMax32(maxDiff, SkAbs32(ic - c));
    586     }
    587     SkDebugf("SinCos: maximum error = %d\n", maxDiff);
    588 #endif
    589 
    590 #ifdef SK_SCALAR_IS_FLOAT
    591     test_blend(reporter);
    592 #endif
    593 
    594     if (false) test_floor(reporter);
    595 
    596     // disable for now
    597     if (false) test_blend31();  // avoid bit rot, suppress warning
    598 }
    599 
    600 #include "TestClassDef.h"
    601 DEFINE_TESTCLASS("Math", MathTestClass, TestMath)
    602