Grok 20.3.2
TagTree.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016-2026 Grok Image Compression Inc.
3 *
4 * This source code is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License, version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This source code is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Affero General Public License for more details.
12 *
13 * You should have received a copy of the GNU Affero General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18#pragma once
19
20#include <limits>
21#include <stdexcept>
22#include <iostream>
23#include <vector>
24
25namespace grk
26{
27
28template<typename T>
30{
31public:
40
41 TagTree(uint16_t leavesWidth, uint16_t leavesHeight)
42 : leavesWidth_(leavesWidth), leavesHeight_(leavesHeight)
43 {
44 buildTree();
45 reset();
46 }
47
48 ~TagTree() = default;
49
50 constexpr T getUninitializedValue() const noexcept
51 {
52 return (std::numeric_limits<T>::max)();
53 }
54
58 void reset()
59 {
60 for(auto& n : nodes_)
61 {
62 n.value = getUninitializedValue();
63 n.low = 0;
64 n.known = false;
65 }
66 for(auto& v : leafCache_)
68 }
69
75 void set(uint64_t leafno, T value)
76 {
77 uint32_t node = static_cast<uint32_t>(leafno);
78 while(node != UINT32_MAX && nodes_[node].value > value)
79 {
80 nodes_[node].value = value;
81 node = parents_[node];
82 }
83 }
84
92 bool encode(t1_t2::BitIO* bio, uint64_t leafno, T threshold)
93 {
94 // exact original encode logic, using flat indices
95 uint32_t nodeStack[16];
96 int stackPtr = 0;
97 uint32_t node = static_cast<uint32_t>(leafno);
98 while(parents_[node] != UINT32_MAX)
99 {
100 nodeStack[stackPtr++] = node;
101 node = parents_[node];
102 }
103 T low = 0;
104 while(true)
105 {
106 auto& n = nodes_[node];
107 if(n.low < low)
108 n.low = low;
109 else
110 low = n.low;
111
112 while(low < threshold)
113 {
114 if(low >= n.value)
115 {
116 if(!n.known)
117 {
118 if(!bio->write(1))
119 return false;
120 n.known = true;
121 }
122 break;
123 }
124 if(!bio->write(0))
125 return false;
126 ++low;
127 }
128 n.low = low;
129 if(stackPtr == 0)
130 break;
131 node = nodeStack[--stackPtr];
132 }
133 return true;
134 }
135
143 void decode(t1_t2::BitIO* bio, uint64_t leafno, T threshold, T* value)
144 {
145 if(leafCache_[leafno] < threshold) [[likely]]
146 {
147 *value = leafCache_[leafno];
148 return;
149 }
150
151 *value = getUninitializedValue();
152
153 uint32_t nodeStack[16];
154 int stackPtr = 0;
155 uint32_t node = static_cast<uint32_t>(leafno);
156
157 // climb to root (exact same path as encode)
158 while(parents_[node] != UINT32_MAX)
159 {
160 nodeStack[stackPtr++] = node;
161 node = parents_[node];
162 }
163
164 T low = 0;
165 while(true)
166 {
167 auto& n = nodes_[node];
168
169 if(n.low < low)
170 n.low = low;
171 else
172 low = n.low;
173
174 while(low < threshold && low < n.value) [[likely]]
175 {
176 if(bio->read())
177 {
178 n.value = low;
179 break;
180 }
181 ++low;
182 }
183 n.low = low;
184
185 if(stackPtr == 0) [[unlikely]]
186 break;
187
188 node = nodeStack[--stackPtr]; // descend to child
189 }
190
191 *value = nodes_[node].value; // now guaranteed to be the leaf node
192 if(*value < threshold)
193 leafCache_[leafno] = *value;
194 }
195
196private:
197 struct Node
198 {
201 bool known;
202 };
203
205 {
206 // same level calculation as original
207 uint16_t resW[16]{}, resH[16]{};
208 int8_t levels = 0;
209 resW[0] = leavesWidth_;
210 resH[0] = leavesHeight_;
211 uint64_t totalNodes = 0;
212 uint32_t nodesPerLevel;
213
214 do
215 {
216 nodesPerLevel = static_cast<uint32_t>(resW[levels]) * resH[levels];
217 resW[levels + 1] = (uint16_t)((resW[levels] + 1) >> 1);
218 resH[levels + 1] = (uint16_t)((resH[levels] + 1) >> 1);
219 totalNodes += nodesPerLevel;
220 ++levels;
221 } while(nodesPerLevel > 1);
222
223 nodes_.resize(totalNodes);
224 parents_.resize(totalNodes, UINT32_MAX);
225 leafCache_.resize(static_cast<uint64_t>(leavesWidth_) * leavesHeight_);
226
227 // build parents (exact same linking logic as original, but with indices)
228 uint64_t parentBase = static_cast<uint64_t>(leavesWidth_) * leavesHeight_;
229 uint64_t cur = 0;
230
231 for(int8_t lvl = 0; lvl < levels - 1; ++lvl)
232 {
233 uint32_t w = resW[lvl];
234 uint32_t h = resH[lvl];
235 for(uint32_t j = 0; j < h; ++j)
236 {
237 for(uint32_t k = 0; k < w; ++k)
238 {
239 parents_[cur] = static_cast<uint32_t>(parentBase + (j >> 1) * resW[lvl + 1] + (k >> 1));
240 ++cur;
241 }
242 }
243 parentBase += static_cast<uint64_t>(resW[lvl + 1]) * resH[lvl + 1];
244 }
245 }
246
247 uint16_t leavesWidth_;
249 std::vector<Node> nodes_;
250 std::vector<uint32_t> parents_; // UINT32_MAX = root
251 std::vector<T> leafCache_;
252};
253
256
257} // namespace grk
Definition TagTree.h:30
~TagTree()=default
constexpr T getUninitializedValue() const noexcept
Definition TagTree.h:50
void buildTree()
Definition TagTree.h:204
TagTree(uint16_t leavesWidth, uint16_t leavesHeight)
TagTree constructor.
Definition TagTree.h:41
void decode(t1_t2::BitIO *bio, uint64_t leafno, T threshold, T *value)
Decode the value of a leaf of the tag tree up to a given threshold.
Definition TagTree.h:143
void reset()
Reset a tag tree (set all leaves to 0).
Definition TagTree.h:58
std::vector< Node > nodes_
Definition TagTree.h:249
void set(uint64_t leafno, T value)
Set the value of a leaf of a tag tree.
Definition TagTree.h:75
std::vector< uint32_t > parents_
Definition TagTree.h:250
bool encode(t1_t2::BitIO *bio, uint64_t leafno, T threshold)
Encode the value of a leaf of the tag tree up to a given threshold.
Definition TagTree.h:92
std::vector< uint8_t > leafCache_
Definition TagTree.h:251
uint16_t leavesWidth_
Definition TagTree.h:247
uint16_t leavesHeight_
Definition TagTree.h:248
Definition BitIO.h:47
void read(T *bits, uint8_t n)
Reads bits.
Definition BitIO.h:114
bool write(uint32_t v, uint8_t n)
Writes bits.
Definition BitIO.h:87
ResWindow.
Definition CompressedChunkCache.h:36
TagTree< uint8_t > TagTreeU8
Definition TagTree.h:254
TagTree< uint16_t > TagTreeU16
Definition TagTree.h:255
Definition TagTree.h:198
bool known
Definition TagTree.h:201
T value
Definition TagTree.h:199
T low
Definition TagTree.h:200