Changeset 2307


Ignore:
Timestamp:
Feb 1, 2013, 12:30:44 AM (7 years ago)
Author:
sam
Message:

color: slightly tweak the RGB to HSV and HSL conversions for
improved numerical stability on i386.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lol/image/color.h

    r2271 r2307  
    8989        float K = 0.f;
    9090
    91         if (src.b - src.g > 1e-20f)
     91        if (src.g < src.b)
    9292            src = src.rbg, K = -1.f;
    9393
    94         if (src.g - src.r > 1e-20f)
     94        if (src.r < src.g)
    9595            src = src.grb, K = -2.f / 6.f - K;
    9696
    9797        float chroma = src.r - min(src.g, src.b);
    98         return vec3(abs(K + (src.g - src.b) / (6.f * chroma + 1e-20f)),
     98        /* XXX: we use min() here because numerical stability is not
     99         * guaranteed with -ffast-math, I’ve seen it fail on i386. */
     100        return vec3(min(abs(K + (src.g - src.b) / (6.f * chroma)), 1.f),
    99101                    chroma / (src.r + 1e-20f),
    100102                    src.r);
     
    113115        float K = 0.f;
    114116
    115         /* FIXME: this appears to be needed for numerical stability on
    116          * i386 hardware using -ffast-math. Otherwise if (src.g < src.b)
    117          * would suffice. */
    118         if (src.b - src.g > 1e-20f)
     117        if (src.g < src.b)
    119118            src = src.rbg, K = -1.f;
    120119
    121         if (src.g - src.r > 1e-20f)
     120        if (src.r < src.g)
    122121            src = src.grb, K = -2.f / 6.f - K;
    123122
    124123        float chroma = src.r - min(src.g, src.b);
    125124        float luma = src.r + min(src.g, src.b);
    126         return vec3(abs(K + (src.g - src.b) / (6.f * chroma + 1e-20f)),
    127                     chroma / (min(luma, 2.f - luma) + 1e-20f),
    128                     0.5f * luma);
     125        float h = min(abs(K + (src.g - src.b) / (6.f * chroma)), 1.f);
     126        float s = clamp(chroma / (min(luma, 2.f - luma)), 0.f, 1.f);
     127        return vec3(h, s, 0.5f * luma);
    129128    }
    130129
  • trunk/test/unit/color.cpp

    r2218 r2307  
    8585            LOLUNIT_ASSERT_DOUBLES_EQUAL(d1, d2, 0.0001);
    8686            LOLUNIT_ASSERT_DOUBLES_EQUAL(d2, d3, 0.0001);
     87            LOLUNIT_UNSET_CONTEXT();
    8788        }
    8889    }
     
    9596        {
    9697            vec3 v1 = vec3(r / 20.f, g / 20.f, b / 20.f);
    97             vec3 v2 = Color::HSVToRGB(Color::RGBToHSV(v1));
     98            vec3 v2 = Color::RGBToHSV(v1);
     99            vec3 v3 = Color::HSVToRGB(v2);
    98100
    99             LOLUNIT_ASSERT_DOUBLES_EQUAL(v1.r, v2.r, 0.0001);
    100             LOLUNIT_ASSERT_DOUBLES_EQUAL(v1.g, v2.g, 0.0001);
    101             LOLUNIT_ASSERT_DOUBLES_EQUAL(v1.b, v2.b, 0.0001);
     101            String rgb = String::Printf("[%f %f %f]", v1.r, v1.g, v1.b);
     102            LOLUNIT_SET_CONTEXT(&rgb[0]);
     103
     104            if (r != g || g != b)
     105                LOLUNIT_ASSERT_DOUBLES_EQUAL(v1.r, v3.r, 0.0001);
     106            LOLUNIT_ASSERT_DOUBLES_EQUAL(v1.g, v3.g, 0.0001);
     107            LOLUNIT_ASSERT_DOUBLES_EQUAL(v1.b, v3.b, 0.0001);
     108
     109            LOLUNIT_UNSET_CONTEXT();
    102110        }
    103111    }
     
    113121            vec3 v3 = Color::HSVToHSL(Color::RGBToHSV(v1));
    114122
    115             LOLUNIT_ASSERT_DOUBLES_EQUAL(v2.x, v3.x, 0.0001);
     123            String rgb = String::Printf("[%f %f %f]", v1.r, v1.g, v1.b);
     124            LOLUNIT_SET_CONTEXT(&rgb[0]);
     125
     126            if (r != g || g != b)
     127                LOLUNIT_ASSERT_DOUBLES_EQUAL(v2.x, v3.x, 0.0001);
    116128            LOLUNIT_ASSERT_DOUBLES_EQUAL(v2.y, v3.y, 0.0001);
    117129            LOLUNIT_ASSERT_DOUBLES_EQUAL(v2.z, v3.z, 0.0001);
     130
     131            LOLUNIT_UNSET_CONTEXT();
    118132        }
    119133    }
Note: See TracChangeset for help on using the changeset viewer.