| 13 | constexpr float inf = std::numeric_limits<float>::infinity(); |
| 14 | |
| 15 | void TestLog(float logBase) |
| 16 | { |
| 17 | const float rgbaImage[32] = { 0.0367126f, 0.5f, 1.f, 0.f, |
| 18 | 0.2f, 0.f, .99f, 128.f, |
| 19 | qnan, qnan, qnan, 0.f, |
| 20 | 0.f, 0.f, 0.f, qnan, |
| 21 | inf, inf, inf, 0.f, |
| 22 | 0.f, 0.f, 0.f, inf, |
| 23 | -inf, -inf, -inf, 0.f, |
| 24 | 0.f, 0.f, 0.f, -inf }; |
| 25 | |
| 26 | float rgba[32] = {}; |
| 27 | |
| 28 | OCIO::ConstLogOpDataRcPtr logOp = std::make_shared<OCIO::LogOpData>( |
| 29 | logBase, OCIO::TRANSFORM_DIR_FORWARD); |
| 30 | |
| 31 | OCIO::ConstOpCPURcPtr pRenderer = OCIO::GetLogRenderer(logOp, true); |
| 32 | pRenderer->apply(rgbaImage, rgba, 8); |
| 33 | |
| 34 | const float minValue = std::numeric_limits<float>::min(); |
| 35 | |
| 36 | // LogOpCPU implementation uses optimized logarithm approximation |
| 37 | // cannot use strict comparison. |
| 38 | #if OCIO_USE_SSE2 |
| 39 | const float error = 5e-5f; |
| 40 | #else |
| 41 | const float error = 1e-5f; |
| 42 | #endif // OCIO_USE_SSE2 |
| 43 | |
| 44 | for (unsigned i = 0; i < 8; ++i) |
| 45 | { |
| 46 | const bool isAlpha = (i % 4 == 3); |
| 47 | |
| 48 | const float result = rgba[i]; |
| 49 | float expected = rgbaImage[i]; |
| 50 | if (!isAlpha) |
| 51 | { |
| 52 | expected = logf(std::max(minValue, (float)expected)) / logf(logBase); |
| 53 | } |
| 54 | |
| 55 | // Evaluating output for input rgbaImage[0-7] = { 0.0367126f, 0.5f, 1.f, 0.f, |
| 56 | // 0.2f, 0.f, .99f, 128.f, |
| 57 | // ... } |
| 58 | OCIO_CHECK_CLOSE(result, expected, error); |
| 59 | } |
| 60 | |
| 61 | const float resMin = logf(minValue) / logf(logBase); |
| 62 | |
| 63 | // Evaluating output for input rgbaImage[8-11] = {qnan, qnan, qnan, 0.}. |
| 64 | OCIO_CHECK_CLOSE(rgba[8], resMin, error); |
| 65 | OCIO_CHECK_EQUAL(rgba[11], 0.0f); |
| 66 | |
| 67 | // Evaluating output for input rgbaImage[12-15] = {0., 0., 0., qnan.}. |
| 68 | OCIO_CHECK_CLOSE(rgba[12], resMin, error); |
| 69 | OCIO_CHECK_ASSERT(OCIO::IsNan(rgba[15])); |
| 70 | |
| 71 | // SSE implementation of sseLog2 & sseExp2 do not behave like CPU. |
| 72 | // TODO: Address issues with Inf/NaN handling demonstrated by many of the test results below. |
no test coverage detected