/* -*- tab-width: 4; -*- */ /* vi: set sw=2 ts=4 expandtab: */ /* * Copyright 2010-2020 Mark Callow. * SPDX-License-Identifier: Apache-2.0 */ /** * @internal * @file * @~English * * @brief Tests of internal API functions. * * @author Mark Callow, github.com/MarkCallow */ #if defined(_WIN32) #define _CRT_SECURE_NO_WARNINGS #if _MSC_VER < 1900 #define snprintf _snprintf #endif #endif #include "gtest/gtest.h" #include "image.hpp" namespace { //////////////////////// // normalisation tests //////////////////////// template void test_color(ColorType input, ColorType output) { ColorType color; for (uint32_t i = 0; i < color.comps_count(); ++i) { color.set(i, static_cast(input[i])); } // Verify color components were set correctly for (uint32_t i = 0; i < color.comps_count(); ++i) { EXPECT_EQ(color[i], static_cast(input[i])); } color.normalize(); for (uint32_t i = 0; i < color.comps_count(); ++i) { EXPECT_EQ(color[i], static_cast(output[i])); } } static constexpr uint32_t min_val{0}; static constexpr uint32_t max_val[3]={255, 65535, 4294967295}; static constexpr uint32_t some_val[3]={31, 191, 178}; template void test_by_channel( const uint32_t min_res[], const uint32_t max_res[], const uint32_t some_res8[], const uint32_t some_res16[], const uint32_t some_res32[]) { { color c8i{(uint8_t)min_val, (uint8_t)min_val, (uint8_t)min_val, (uint8_t)min_val}; color c8o{(uint8_t)min_res[0], (uint8_t)min_res[0], (uint8_t)min_res[0], 0}; test_color(c8i, c8o); } { color c8i{(uint8_t)max_val[0], (uint8_t)max_val[0], (uint8_t)max_val[0], (uint8_t)max_val[0]}; color c8o{(uint8_t)max_res[0], (uint8_t)max_res[0], (uint8_t)max_res[0], (uint8_t)max_val[0]}; test_color(c8i, c8o); } { color c8i{(uint8_t)some_val[0], (uint8_t)some_val[1], (uint8_t)some_val[2], 0}; color c8o{(uint8_t)some_res8[0], (uint8_t)some_res8[1], (uint8_t)some_res8[2], 0}; test_color(c8i, c8o); } { color c16i{(uint16_t)min_val, (uint16_t)min_val, (uint16_t)min_val, (uint16_t)min_val}; color c16o{(uint16_t)min_res[1], (uint16_t)min_res[1], (uint16_t)min_res[1], 0}; test_color(c16i, c16o); } { color c16i{(uint16_t)max_val[1], (uint16_t)max_val[1], (uint16_t)max_val[1], (uint16_t)max_val[1]}; color c16o{(uint16_t)max_res[1], (uint16_t)max_res[1], (uint16_t)max_res[1], (uint16_t)max_val[1]}; test_color(c16i, c16o); } { color c16i{(uint16_t)some_val[0], (uint16_t)some_val[1], (uint16_t)some_val[2], 0}; color c16o{(uint16_t)some_res16[0], (uint16_t)some_res16[1], (uint16_t)some_res16[2], 0}; test_color(c16i, c16o); } { color c32i{(uint32_t)min_val, (uint32_t)min_val, (uint32_t)min_val, (uint32_t)min_val}; color c32o{(uint32_t)min_res[2], (uint32_t)min_res[2], (uint32_t)min_res[2], 0}; test_color(c32i, c32o); } { color c32i{(uint32_t)max_val[2], (uint32_t)max_val[2], (uint32_t)max_val[2], (uint32_t)max_val[2]}; color c32o{(uint32_t)max_res[2], (uint32_t)max_res[2], (uint32_t)max_res[2], (uint32_t)max_val[2]}; test_color(c32i, c32o); } { color c32i{(uint32_t)some_val[0], (uint32_t)some_val[1], (uint32_t)some_val[2], 0}; color c32o{(uint32_t)some_res32[0], (uint32_t)some_res32[1], (uint32_t)some_res32[2], 0}; test_color(c32i, c32o); } } // Hand tested vectors and their normalised results in GeoGebra static constexpr uint32_t min_res[3]={54, 13849, 907633408}; // These are -0.577350 float in 8bit-UNORM, 16bit-UNORM and 32bit-UNORM values static constexpr uint32_t max_res[3]={201, 51686, 3387333888}; static constexpr uint32_t some_res8[3]={30, 192, 179}; static constexpr uint32_t some_res16[3]={13790, 13883, 13875}; static constexpr uint32_t some_res32[3]={907633408, 907633408, 907633408}; static constexpr uint32_t min_res2[3]={37, 9597, 628983424}; static constexpr uint32_t max_res2[3]={218, 55938, 3665984000}; static constexpr uint32_t some_res8_2[3]={21, 198, 128}; static constexpr uint32_t some_res16_2[3]={9541, 9654, 32768}; static constexpr uint32_t some_res32_2[3]={628983424, 628983424, 2147483648}; static constexpr uint32_t min_res1[3]={0, 0, 0}; static constexpr uint32_t max_res1[3]={255, 65535, 4294967295}; static constexpr uint32_t some_res8_1[3]={255, 0, 0}; // Second and third values are unused because its single channel image result static constexpr uint32_t some_res16_1[3]={65535, 0, 0}; // Same as above static constexpr uint32_t some_res32_1[3]={4294967295, 0, 0}; // Same as above TEST(NormaliseColorTest, multi_channel_test) { test_by_channel<4>(min_res, max_res, some_res8, some_res16, some_res32); test_by_channel<3>(min_res, max_res, some_res8, some_res16, some_res32); test_by_channel<2>(min_res2, max_res2, some_res8_2, some_res16_2, some_res32_2); test_by_channel<1>(min_res1, max_res1, some_res8_1, some_res16_1, some_res32_1); } } // namespace