1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10
11 #include <vtkm/cont/testing/Testing.h>
12 #include <vtkm/io/PixelTypes.h>
13
14 #include <string>
15
16 using namespace vtkm::io;
17
18 template <typename PixelType>
TestPixelTypeOperations(const vtkm::UInt16 & numPixels=10)19 void TestPixelTypeOperations(const vtkm::UInt16& numPixels = 10)
20 {
21 using ValType = typename PixelType::ComponentType;
22 const ValType numBytes = static_cast<ValType>(PixelType::NUM_BYTES);
23 const ValType numChannels = static_cast<ValType>(PixelType::NUM_CHANNELS);
24
25 // Fill in the imageData through FillPixelData
26 std::vector<unsigned char> imageData(numPixels * numBytes * numChannels);
27 std::vector<PixelType> pixelVector(numPixels);
28 for (ValType i = 0; i < numPixels; i++)
29 {
30 ValType pixelVal = 0;
31 for (ValType j = 0, shift = numBytes - 1; j < numBytes; shift--, j++)
32 {
33 pixelVal += (i + j) << (shift * 8);
34 }
35
36 PixelType pixel(pixelVal);
37 pixelVector[i] = pixel;
38 pixel.FillImageAtIndexWithPixel(imageData.data(), i);
39 }
40
41 // Test that the imageData values were set correctly
42 VTKM_TEST_ASSERT(static_cast<vtkm::Id>(imageData.size()) == numPixels * numChannels * numBytes,
43 "Wrong number of elements");
44 for (ValType j = 0; j < numBytes; j++)
45 {
46 for (ValType i = 0; i < numPixels; i++)
47 {
48 for (ValType k = numChannels * i; k < numChannels * i + numChannels; k++)
49 {
50 VTKM_TEST_ASSERT(imageData[k * numBytes + j] == i + j,
51 "Wrong value at index[" + std::to_string(k * numBytes + j) +
52 "]: " + std::to_string(imageData[k * numBytes + j]) +
53 " != " + std::to_string(i + j));
54 }
55 }
56 }
57
58 // Test that a pixel can be retreived from the filled out data vector
59 for (vtkm::Id i = 0; i < numPixels; i++)
60 {
61 VTKM_TEST_ASSERT(pixelVector[static_cast<typename std::vector<PixelType>::size_type>(i)] ==
62 PixelType(imageData.data(), i),
63 "Incorrect pixel value");
64 }
65 }
66
TestDifferentPixelTypes()67 void TestDifferentPixelTypes()
68 {
69 VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Testing 8 bit RGB");
70 TestPixelTypeOperations<RGBPixel_8>();
71
72 VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Testing 8 bit Grey");
73 TestPixelTypeOperations<GreyPixel_8>();
74
75 VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Testing 16 bit RGB");
76 TestPixelTypeOperations<RGBPixel_16>();
77
78 VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Testing 16 bit Grey");
79 TestPixelTypeOperations<GreyPixel_16>();
80 }
81
TestGreyPixelConstructors()82 void TestGreyPixelConstructors()
83 {
84 std::vector<unsigned char> initData{ 1, 2 };
85
86 auto pixel_1 = GreyPixel_8(1);
87 auto pixel_2 = GreyPixel_8(1);
88 auto pixel_3 = GreyPixel_8(2);
89 auto pixel_4 = GreyPixel_8(initData.data(), 0);
90 auto pixel_5 = GreyPixel_8(initData.data(), 1);
91 auto pixel_6 = GreyPixel_16(initData.data(), 0);
92
93 float color = 10.0f / GreyPixel_16::MAX_COLOR_VALUE;
94 auto pixel_7 = GreyPixel_16({ color, color, color, 5 });
95
96 VTKM_TEST_ASSERT(vtkm::UInt16(1) == pixel_1[0], "Type mis-match");
97 VTKM_TEST_ASSERT(vtkm::FloatDefault(0) == pixel_1.Diff(pixel_2), "Incorrect Diff");
98 VTKM_TEST_ASSERT(vtkm::FloatDefault(1) == pixel_1.Diff(pixel_3), "Incorrect Diff");
99 VTKM_TEST_ASSERT(vtkm::Vec4f_32(1.0f / 255, 1.0f / 255, 1.0f / 255, 1) == pixel_1.ToVec4f(),
100 "Incorrect Conversion");
101 VTKM_TEST_ASSERT(vtkm::Vec<vtkm::UInt8, 1>(1) == pixel_4, "Bad 1st value 8 bit construct");
102 VTKM_TEST_ASSERT(vtkm::Vec<vtkm::UInt8, 1>(2) == pixel_5, "Bad 2nd value 8 bit construct");
103 VTKM_TEST_ASSERT(vtkm::Vec<vtkm::UInt16, 1>(258) == pixel_6, "Bad 16 bit construct");
104 VTKM_TEST_ASSERT(vtkm::Vec4f_32(258.0f / 65535, 258.0f / 65535, 258.0f / 65535, 1) ==
105 pixel_6.ToVec4f(),
106 "Incorrect Conversion");
107 VTKM_TEST_ASSERT(vtkm::Vec<vtkm::UInt16, 1>(10) == pixel_7, "Bad Vec4f_32 construction");
108
109 VTKM_TEST_ASSERT(GreyPixel<16>::BIT_DEPTH == 16, "Bad BitDepth");
110 VTKM_TEST_ASSERT(GreyPixel<16>::NUM_BYTES == 2, "Bad NumBytes");
111 VTKM_TEST_ASSERT(GreyPixel<16>::MAX_COLOR_VALUE == 65535, "Bad NumBytes");
112 VTKM_TEST_ASSERT(GreyPixel<16>::NUM_CHANNELS == 1, "Bad NumChannels");
113 VTKM_TEST_ASSERT(GreyPixel<16>::BYTES_PER_PIXEL == 2, "Wrong Pixel Byte distance");
114
115 // Shouldn't compile
116 // auto pixel_4 = RGBPixel_8(1, 1, 1);
117 // pixel_1.Diff(pixel_4);
118 }
119
TestRGBPixelConstructors()120 void TestRGBPixelConstructors()
121 {
122 std::vector<unsigned char> initData{ 1, 2, 3, 4, 5, 6 };
123
124 auto pixel_1 = RGBPixel_8(1, 1, 1);
125 auto pixel_2 = RGBPixel_8(1, 1, 1);
126 auto pixel_3 = RGBPixel_8(1);
127 auto pixel_4 = RGBPixel_8(2, 2, 2);
128 auto pixel_5 = RGBPixel_8(initData.data(), 0);
129 auto pixel_6 = RGBPixel_8(initData.data(), 1);
130 auto pixel_7 = RGBPixel_16(initData.data(), 0);
131
132 float color = 10.0f / RGBPixel_16::MAX_COLOR_VALUE;
133 auto pixel_8 = RGBPixel_16({ color, color, color, 5 });
134
135 VTKM_TEST_ASSERT(vtkm::Vec3ui_8(1, 1, 1) == pixel_1, "Type mis-match");
136 VTKM_TEST_ASSERT(vtkm::FloatDefault(0) == pixel_1.Diff(pixel_2), "Incorrect Diff");
137 VTKM_TEST_ASSERT(vtkm::FloatDefault(0) == pixel_1.Diff(pixel_3), "Incorrect Diff");
138 VTKM_TEST_ASSERT(vtkm::FloatDefault(3) == pixel_1.Diff(pixel_4), "Incorrect Diff");
139 VTKM_TEST_ASSERT(vtkm::Vec4f_32(1.0f / 255, 1.0f / 255, 1.0f / 255, 1) == pixel_1.ToVec4f(),
140 "Incorrect Conversion");
141 VTKM_TEST_ASSERT(vtkm::Vec3ui_8(1, 2, 3) == pixel_5, "Bad 1st value 8 bit construct");
142 VTKM_TEST_ASSERT(vtkm::Vec3ui_8(4, 5, 6) == pixel_6, "Bad 2nd value 8 bit construct");
143 VTKM_TEST_ASSERT(vtkm::Vec3ui_16(258, 772, 1286) == pixel_7, "Bad 16 bit construct");
144 VTKM_TEST_ASSERT(vtkm::Vec4f_32(258.0f / 65535, 772.0f / 65535, 1286.0f / 65535, 1) ==
145 pixel_7.ToVec4f(),
146 "Incorrect Conversion");
147 VTKM_TEST_ASSERT(vtkm::Vec<vtkm::UInt16, 3>(10, 10, 10) == pixel_8, "Bad Vec4f_32 construction");
148
149 VTKM_TEST_ASSERT(RGBPixel<16>::BIT_DEPTH == 16, "Bad BitDepth");
150 VTKM_TEST_ASSERT(RGBPixel<16>::NUM_BYTES == 2, "Bad NumBytes");
151 VTKM_TEST_ASSERT(RGBPixel<16>::MAX_COLOR_VALUE == 65535, "Bad NumBytes");
152 VTKM_TEST_ASSERT(RGBPixel<16>::NUM_CHANNELS == 3, "Bad NumChannels");
153 VTKM_TEST_ASSERT(RGBPixel<16>::BYTES_PER_PIXEL == 6, "Wrong Pixel Byte distance");
154
155 // Shouldn't compile
156 // auto pixel_8 = GreyPixel_8(1);
157 // pixel_1.Diff(pixel_8);
158 }
159
TestPixelTypes()160 void TestPixelTypes()
161 {
162 VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Testing RGBPixel");
163 TestRGBPixelConstructors();
164
165 VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Testing GreyPixel");
166 TestGreyPixelConstructors();
167
168 VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Testing Pixel Types");
169 TestDifferentPixelTypes();
170 }
171
UnitTestPixelTypes(int argc,char * argv[])172 int UnitTestPixelTypes(int argc, char* argv[])
173 {
174 return vtkm::cont::testing::Testing::Run(TestPixelTypes, argc, argv);
175 }
176