Grok 15.1.0
TagTree.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016-2025 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 * This source code incorporates work covered by the BSD 2-clause license.
18 * Please see the LICENSE file in the root directory for details.
19 *
20 */
21
22#pragma once
23
24#include <limits>
25
26namespace grk
27{
31template<typename T>
33{
34 TagTreeNode() : parent(nullptr), value(0), low(0), known(false) {}
35
38 T low;
39 bool known;
40};
41
45template<typename T>
47{
48public:
55 TagTree(uint32_t leavesWidth, uint32_t leavesHeight)
56 : leavesWidth_(leavesWidth), leavesHeight_(leavesHeight), nodeCount(0), nodes(nullptr)
57 {
58 uint32_t resLeavesWidth[32];
59 uint32_t resLeavesHeight[32];
60 int8_t numLevels = 0;
61 resLeavesWidth[0] = leavesWidth_;
62 resLeavesHeight[0] = leavesHeight_;
63 nodeCount = 0;
64 uint64_t nodesPerLevel;
65 do
66 {
67 if(numLevels == 32)
68 {
69 grklog.error("TagTree constructor: num level overflow");
70 throw std::exception();
71 }
72 nodesPerLevel = (uint64_t)resLeavesWidth[numLevels] * resLeavesHeight[numLevels];
73 resLeavesWidth[numLevels + 1] = (uint32_t)(((uint64_t)resLeavesWidth[numLevels] + 1) >> 1);
74 resLeavesHeight[numLevels + 1] = (uint32_t)(((uint64_t)resLeavesHeight[numLevels] + 1) >> 1);
75 nodeCount += nodesPerLevel;
76 ++numLevels;
77 } while(nodesPerLevel > 1);
78
79 if(nodeCount == 0)
80 {
81 grklog.warn("tgt_create numnodes == 0, no tree created.");
82 throw std::runtime_error("tgt_create numnodes == 0, no tree created");
83 }
84
86 auto currentNode = nodes;
87 auto parentNode = nodes + (uint64_t)leavesWidth_ * leavesHeight_;
88 auto parentNodeNext = parentNode;
89
90 for(int8_t i = 0; i < numLevels - 1; ++i)
91 {
92 for(uint32_t j = 0; j < resLeavesHeight[i]; ++j)
93 {
94 int64_t k = resLeavesWidth[i];
95 while(--k >= 0)
96 {
97 currentNode->parent = parentNode;
98 ++currentNode;
99 if(--k >= 0)
100 {
101 currentNode->parent = parentNode;
102 ++currentNode;
103 }
104 ++parentNode;
105 }
106 if((j & 1) || j == resLeavesHeight[i] - 1)
107 {
108 parentNodeNext = parentNode;
109 }
110 else
111 {
112 parentNode = parentNodeNext;
113 parentNodeNext += resLeavesWidth[i];
114 }
115 }
116 }
117 currentNode->parent = nullptr;
118 reset();
119 }
121 {
122 delete[] nodes;
123 }
124
125 constexpr T getUninitializedValue(void)
126 {
127 return (std::numeric_limits<T>::max)();
128 }
129
132 void reset()
133 {
134 for(uint64_t i = 0; i < nodeCount; ++i)
135 {
136 auto current_node = nodes + i;
137 current_node->value = getUninitializedValue();
138 current_node->low = 0;
139 current_node->known = false;
140 }
141 }
142
147 void setvalue(uint64_t leafno, T value)
148 {
149 auto node = nodes + leafno;
150 while(node && node->value > value)
151 {
152 node->value = value;
153 node = node->parent;
154 }
155 }
156
163 bool compress(BitIO* bio, uint64_t leafno, T threshold)
164 {
165 TagTreeNode<T>* nodeStack[31];
166 auto nodeStackPtr = nodeStack;
167 auto node = nodes + leafno;
168 while(node->parent)
169 {
170 *nodeStackPtr++ = node;
171 node = node->parent;
172 }
173 T low = 0;
174 while(true)
175 {
176 if(node->low < low)
177 node->low = low;
178 else
179 low = node->low;
180
181 while(low < threshold)
182 {
183 if(low >= node->value)
184 {
185 if(!node->known)
186 {
187 if(!bio->write(1))
188 return false;
189 node->known = true;
190 }
191 break;
192 }
193 if(!bio->write(0))
194 return false;
195 ++low;
196 }
197 node->low = low;
198 if(nodeStackPtr == nodeStack)
199 break;
200 node = *--nodeStackPtr;
201 }
202 return true;
203 }
204
211 void decodeValue(BitIO* bio, uint64_t leafno, T threshold, T* value)
212 {
213 TagTreeNode<T>* nodeStack[31];
214 *value = getUninitializedValue();
215 auto nodeStackPtr = nodeStack;
216 auto node = nodes + leafno;
217 // climb to top of tree
218 while(node->parent)
219 {
220 *nodeStackPtr++ = node;
221 node = node->parent;
222 }
223 // descend to bottom of tree
224 T low = 0;
225 while(true)
226 {
227 if(node->low < low)
228 node->low = low;
229 else
230 low = node->low;
231 while(low < threshold && low < node->value)
232 {
233 if(bio->read())
234 {
235 node->value = low;
236 break;
237 }
238 low++;
239 }
240 node->low = low;
241 if(nodeStackPtr == nodeStack)
242 break;
243 node = *--nodeStackPtr;
244 }
245 *value = node->value;
246 }
247
248private:
249 uint32_t leavesWidth_;
251 uint64_t nodeCount;
253};
254
257
258} // namespace grk
Definition BitIO.h:33
void read(uint32_t *bits, uint8_t n) override
Read bits.
Definition BitIO.cpp:132
bool write(uint32_t v, uint32_t n) override
Write bits.
Definition BitIO.cpp:111
Tag tree.
Definition TagTree.h:47
uint64_t nodeCount
Definition TagTree.h:251
bool compress(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:163
TagTreeNode< uint8_t > * nodes
Definition TagTree.h:252
TagTree(uint32_t leavesWidth, uint32_t leavesHeight)
Create a tag tree.
Definition TagTree.h:55
void reset()
Reset a tag tree (set all leaves to 0)
Definition TagTree.h:132
void setvalue(uint64_t leafno, T value)
Set the value of a leaf of a tag tree.
Definition TagTree.h:147
~TagTree()
Definition TagTree.h:120
void decodeValue(BitIO *bio, uint64_t leafno, T threshold, T *value)
Decompress the value of a leaf of the tag tree up to a given threshold.
Definition TagTree.h:211
uint32_t leavesHeight_
Definition TagTree.h:250
uint32_t leavesWidth_
Definition TagTree.h:249
constexpr T getUninitializedValue(void)
Definition TagTree.h:125
Copyright (C) 2016-2025 Grok Image Compression Inc.
Definition ICacheable.h:20
TagTree< uint16_t > TagTreeU16
Definition TagTree.h:256
TagTree< uint8_t > TagTreeU8
Definition TagTree.h:255
Logger & grklog
Definition Logger.cpp:20
Tag node.
Definition TagTree.h:33
bool known
Definition TagTree.h:39
T low
Definition TagTree.h:38
TagTreeNode * parent
Definition TagTree.h:36
TagTreeNode()
Definition TagTree.h:34
T value
Definition TagTree.h:37