Line data Source code
1 : ///////////////////////////////////////////////////////////////////////////////
2 : //
3 : // Project: C++ Test Suite for GDAL/OGR
4 : // Purpose: Test frmts/nitf/kdtree_vq_cadrg.h
5 : // Author: Even Rouault <even dot rouault at spatialys.com>
6 : //
7 : ///////////////////////////////////////////////////////////////////////////////
8 : // Copyright (c) 2026, T-Kartor
9 : /*
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #include "gdal_unit_test.h"
14 :
15 : #include "../../frmts/nitf/kdtree_vq_cadrg.h"
16 :
17 : #include "gtest_include.h"
18 :
19 : #include <array>
20 :
21 : namespace
22 : {
23 : struct test_kdtree_vq_cadrg : public ::testing::Test
24 : {
25 : };
26 :
27 4 : TEST_F(test_kdtree_vq_cadrg, Vector_ColorTableBased4x4Pixels)
28 : {
29 : std::vector<GByte> r{0, 10, 20, 30, 40, 50, 60, 70,
30 2 : 80, 90, 100, 110, 120, 130, 140, 150};
31 : std::vector<GByte> g{0 + 1, 10 + 1, 20 + 1, 30 + 1, 40 + 1, 50 + 1,
32 : 60 + 1, 70 + 1, 80 + 1, 90 + 1, 100 + 1, 110 + 1,
33 2 : 120 + 1, 130 + 1, 140 + 1, 150 + 1};
34 : std::vector<GByte> b{0 + 2, 10 + 2, 20 + 2, 30 + 2, 40 + 2, 50 + 2,
35 : 60 + 2, 70 + 2, 80 + 2, 90 + 2, 100 + 2, 110 + 2,
36 2 : 120 + 2, 130 + 2, 140 + 2, 150 + 2};
37 1 : ColorTableBased4x4Pixels colorTable(r, g, b);
38 :
39 1 : std::array<GByte, 16> array{0, 1, 2, 3, 4, 5, 6, 7,
40 : 8, 9, 10, 11, 12, 13, 14, 15};
41 1 : Vector<ColorTableBased4x4Pixels> v1(array);
42 1 : EXPECT_EQ(v1.val(0), 0);
43 1 : EXPECT_EQ(v1.val(15), 15);
44 1 : EXPECT_TRUE(memcmp(v1.vals(), array.data(), 16) == 0);
45 1 : const Vector<ColorTableBased4x4Pixels> &v1_const = v1;
46 1 : EXPECT_EQ(v1_const.vals(), array);
47 1 : EXPECT_EQ(v1.get(0, colorTable), 0);
48 1 : EXPECT_EQ(v1.get(15, colorTable), 150);
49 1 : EXPECT_EQ(v1.get(16, colorTable), 1);
50 1 : EXPECT_EQ(v1.get(31, colorTable), 151);
51 1 : EXPECT_EQ(v1.get(32, colorTable), 2);
52 1 : EXPECT_EQ(v1.get(47, colorTable), 152);
53 1 : EXPECT_EQ(v1.squared_distance(v1, colorTable), 0);
54 17 : for (int i = 0; i < 16; ++i)
55 : {
56 16 : std::array<GByte, 16> array2{0, 1, 2, 3, 4, 5, 6, 7,
57 : 8, 9, 10, 11, 12, 13, 14, 15};
58 16 : if (i < 15)
59 15 : array2[i] += 1;
60 : else
61 1 : array2[i] -= 1;
62 16 : Vector<ColorTableBased4x4Pixels> v2(array2);
63 16 : EXPECT_EQ(v1.squared_distance(v2, colorTable), 300);
64 16 : EXPECT_EQ(v2.squared_distance(v1, colorTable), 300);
65 : }
66 :
67 1 : EXPECT_EQ(Vector<ColorTableBased4x4Pixels>::centroid(v1, 1000, v1, 300,
68 : colorTable),
69 : v1);
70 :
71 1 : std::array<GByte, 16> array0{0, 0, 0, 0, 0, 0, 0, 0,
72 : 0, 0, 0, 0, 0, 0, 0, 0};
73 1 : Vector<ColorTableBased4x4Pixels> v0(array0);
74 1 : std::array<GByte, 16> array15{15, 15, 15, 15, 15, 15, 15, 15,
75 : 15, 15, 15, 15, 15, 15, 15, 15};
76 1 : Vector<ColorTableBased4x4Pixels> v15(array15);
77 1 : std::array<GByte, 16> array7{7, 7, 7, 7, 7, 7, 7, 7,
78 : 7, 7, 7, 7, 7, 7, 7, 7};
79 1 : Vector<ColorTableBased4x4Pixels> v7(array7);
80 1 : EXPECT_EQ(
81 : Vector<ColorTableBased4x4Pixels>::centroid(v0, 10, v15, 10, colorTable),
82 : v7);
83 1 : }
84 :
85 4 : TEST_F(test_kdtree_vq_cadrg, kdtree)
86 : {
87 : std::vector<GByte> r{0, 10, 20, 30, 40, 50, 60, 70,
88 1 : 80, 90, 100, 110, 120, 130, 140, 150};
89 : std::vector<GByte> g{0 + 1, 10 + 1, 20 + 1, 30 + 1, 40 + 1, 50 + 1,
90 : 60 + 1, 70 + 1, 80 + 1, 90 + 1, 100 + 1, 110 + 1,
91 1 : 120 + 1, 130 + 1, 140 + 1, 150 + 1};
92 : std::vector<GByte> b{0 + 2, 10 + 2, 20 + 2, 30 + 2, 40 + 2, 50 + 2,
93 : 60 + 2, 70 + 2, 80 + 2, 90 + 2, 100 + 2, 110 + 2,
94 1 : 120 + 2, 130 + 2, 140 + 2, 150 + 2};
95 1 : ColorTableBased4x4Pixels colorTable(r, g, b);
96 :
97 1 : PNNKDTree<ColorTableBased4x4Pixels> kdtree;
98 1 : std::vector<BucketItem<ColorTableBased4x4Pixels>> vectors;
99 16 : for (GByte i = 0; i < 15; ++i)
100 : {
101 : vectors.emplace_back(
102 15 : Vector<ColorTableBased4x4Pixels>{filled_array<GByte, 16>(i)}, 1,
103 30 : std::vector<int>{i});
104 : }
105 1 : EXPECT_EQ(kdtree.insert(std::move(vectors), colorTable), 15);
106 :
107 1 : EXPECT_EQ(kdtree.cluster(15, 4, colorTable), 4);
108 :
109 1 : std::vector<BucketItem<ColorTableBased4x4Pixels>> items;
110 1 : kdtree.iterateOverLeaves(
111 5 : [&items](PNNKDTree<ColorTableBased4x4Pixels> &node)
112 : {
113 5 : for (auto &it : node.bucketItems())
114 : {
115 4 : items.push_back(std::move(it));
116 : }
117 1 : });
118 1 : ASSERT_EQ(items.size(), 4U);
119 :
120 1 : EXPECT_EQ(items[0].m_count, 4);
121 : const Vector<ColorTableBased4x4Pixels> expect_v0(
122 1 : std::array<GByte, 16>{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1});
123 1 : const auto &got_0 = items[0].m_vec;
124 1 : EXPECT_EQ(got_0, expect_v0);
125 2 : const std::vector<int> indices_0{0, 1, 2, 3};
126 1 : EXPECT_EQ(indices_0, items[0].m_origVectorIndices);
127 :
128 1 : EXPECT_EQ(items[1].m_count, 3);
129 2 : const Vector<ColorTableBased4x4Pixels> expect_v1(std::array<GByte, 16>{
130 1 : 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13});
131 1 : const auto &got_1 = items[1].m_vec;
132 1 : EXPECT_EQ(got_1, expect_v1);
133 2 : const std::vector<int> indices_1{12, 13, 14};
134 1 : EXPECT_EQ(indices_1, items[1].m_origVectorIndices);
135 :
136 1 : EXPECT_EQ(items[2].m_count, 4);
137 : const Vector<ColorTableBased4x4Pixels> expect_v2(
138 1 : std::array<GByte, 16>{5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5});
139 1 : const auto &got_2 = items[2].m_vec;
140 1 : EXPECT_EQ(got_2, expect_v2);
141 2 : const std::vector<int> indices_2{4, 5, 6, 7};
142 1 : EXPECT_EQ(indices_2, items[2].m_origVectorIndices);
143 :
144 1 : EXPECT_EQ(items[3].m_count, 4);
145 : const Vector<ColorTableBased4x4Pixels> expect_v3(
146 1 : std::array<GByte, 16>{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9});
147 1 : const auto &got_3 = items[3].m_vec;
148 1 : EXPECT_EQ(got_3, expect_v3);
149 2 : const std::vector<int> indices_3{8, 9, 10, 11};
150 1 : EXPECT_EQ(indices_3, items[3].m_origVectorIndices);
151 :
152 : #ifdef DEBUG_VERBOSE
153 : for (const auto &it : items)
154 : {
155 : printf("vec: ");
156 : for (int i = 0; i < 16; ++i)
157 : printf("%d, ", it.m_vec.val(i));
158 : printf("\n");
159 : printf("count: %d\n", it.m_count);
160 : printf("origVectorIndices: ");
161 : for (auto idx : it.m_origVectorIndices)
162 : printf("%d, ", idx);
163 : printf("\n");
164 : }
165 : #endif
166 : }
167 :
168 : } // namespace
|