Grok 20.3.2
ResWindow.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
30
31/*
32 Various coordinate systems are used to describe regions in the tile component buffer.
33
34 1) Canvas coordinates: JPEG 2000 global image coordinates.
35
36 2) Tile component coordinates: canvas coordinates with sub-sampling applied
37
38 3) Band coordinates: coordinates relative to a specified sub-band's origin
39
40 4) Buffer coordinates: coordinate system where all resolutions are translated
41 to common origin (0,0). If each code block is translated relative to the origin of the
42 resolution that **it belongs to**, the blocks are then all in buffer coordinate system
43
44 Note: the name of any method or variable returning non canvas coordinates is appended
45 with "REL", to signify relative coordinates.
46
47 */
48
49#pragma once
50
51#include "ResSimple.h"
52
53namespace grk
54{
55
62
63template<typename T>
64struct TileComponentWindow;
65template<typename T>
66struct TileComponentWindowBase;
67
68template<typename T>
70{
71 friend struct TileComponentWindowBase<T>;
72 friend struct TileComponentWindow<T>;
74
75private:
76 ResWindow(uint8_t numresolutions, uint8_t resno, Buf2dAligned* resWindowHighestResREL,
77 ResSimple tileCompAtRes, ResSimple tileCompAtLowerRes, Rect32 resWindow,
78 Rect32 tileCompWindowUnreduced, Rect32 tileCompUnreduced, uint32_t FILTER_WIDTH)
79 : allocated_(false), filterWidth_(FILTER_WIDTH), tileCompAtRes_(tileCompAtRes),
80 tileCompAtLowerRes_(tileCompAtLowerRes), resWindowBuffer_(new Buf2dAligned(resWindow)),
81 resWindowBufferSplit_{nullptr, nullptr},
82 resWindowBufferHighestResREL_(resWindowHighestResREL),
83 resWindowBufferREL_(new Buf2dAligned(resWindow.width(), resWindow.height())),
84 resWindowBufferSplitREL_{nullptr, nullptr}
85 {
86 resWindowBuffer_->setOrigin(tileCompAtRes_, true);
87 uint8_t numDecomps =
88 (resno == 0) ? (uint8_t)(numresolutions - 1U) : (uint8_t)(numresolutions - resno);
89 Rect32 resWindowPadded;
90 for(uint8_t orient = 0; orient < ((resno) > 0 ? t1::BAND_NUM_ORIENTATIONS : 1); orient++)
91 {
92 // todo: should only need padding equal to FILTER_WIDTH, not 2*FILTER_WIDTH
93 auto bandWindow = getPaddedBandWindow(numDecomps, orient, tileCompWindowUnreduced,
94 tileCompUnreduced, 2 * FILTER_WIDTH, resWindowPadded);
96 if(resno > 0)
98 : tileCompAtRes_.tileBand[orient - 1];
99 bandWindow.setOrigin(band, true);
100 assert(bandWindow.intersection(band).setOrigin(bandWindow, true) == bandWindow);
101 bandWindowsBoundsPadded_.push_back(bandWindow);
102 }
103 // windowed decompression
104 if(FILTER_WIDTH)
105 {
106 if(tileCompAtLowerRes_.numTileBandWindows)
107 {
108 assert(resno > 0);
109 resWindowBuffer_->setRect(resWindowPadded);
110 resWindowBufferREL_->setRect(resWindowBuffer_->toRelative());
111 resWindowBuffer_->toAbsolute();
112
113 for(uint8_t orient = 0; orient < t1::BAND_NUM_ORIENTATIONS; orient++)
114 {
115 auto bandWindow = bandWindowsBoundsPadded_[orient];
116 bandWindowsBuffersPadded_.push_back(new Buf2dAligned(bandWindow, true));
117 bandWindowsBuffersPaddedREL_.push_back(new Buf2dAligned(bandWindow.toRelative(), true));
118 }
125 }
126 }
127 else
128 {
129 assert(tileCompAtRes_.numTileBandWindows == 3 || !tileCompAtLowerRes.numTileBandWindows);
130
131 // dummy LL band window
132 if(tileCompAtLowerRes_.numTileBandWindows && tileCompAtLowerRes_.valid())
133 {
134 bandWindowsBuffersPadded_.push_back(new Buf2dAligned(0, 0));
135 bandWindowsBuffersPaddedREL_.push_back(new Buf2dAligned(0, 0));
136 for(uint32_t i = 0; i < tileCompAtRes_.numTileBandWindows; ++i)
137 {
138 auto tileCompBand = tileCompAtRes_.tileBand + i;
139
140 auto band = Rect32(tileCompBand);
141 bandWindowsBuffersPadded_.push_back(new Buf2dAligned(band));
142 bandWindowsBuffersPaddedREL_.push_back(new Buf2dAligned(band.toRelative()));
143 }
144 for(uint8_t i = 0; i < SPLIT_NUM_ORIENTATIONS; i++)
145 {
147 split.y0 =
148 (resWindowBuffer_->y0 == 0 ? 0 : ceildivpow2<uint32_t>(resWindowBuffer_->y0 - i, 1));
149 split.y1 =
150 (resWindowBuffer_->y1 == 0 ? 0 : ceildivpow2<uint32_t>(resWindowBuffer_->y1 - i, 1));
151 resWindowBufferSplit_[i] = new Buf2dAligned(split);
153 }
154 }
155 }
156 }
158 {
159 delete resWindowBufferREL_;
160 for(auto& b : bandWindowsBuffersPaddedREL_)
161 delete b;
162 for(uint32_t i = 0; i < SPLIT_NUM_ORIENTATIONS; ++i)
163 delete resWindowBufferSplitREL_[i];
164
165 delete resWindowBuffer_;
166 for(auto& b : bandWindowsBuffersPadded_)
167 delete b;
168 for(uint32_t i = 0; i < SPLIT_NUM_ORIENTATIONS; ++i)
169 delete resWindowBufferSplit_[i];
170 }
171 void genSplitWindowBuffers(Buf2dAligned** resWindowBufferSplit, Buf2dAligned* resWindowBuffer,
172 Buf2dAligned* bandWindowsBuffersPaddedXL,
173 Buf2dAligned* bandWindowsBuffersPaddedXH, bool absolute)
174 {
175 if(!absolute)
176 {
177 tileCompAtLowerRes_.toRelative();
178 bandWindowsBuffersPaddedXL->toRelative();
179 bandWindowsBuffersPaddedXH->toRelative();
180 }
181
182 // two windows formed by horizontal pass and used as input for vertical pass
183 auto splitResWindowBounds = Rect32(resWindowBuffer->x0, bandWindowsBuffersPaddedXL->y0,
184 resWindowBuffer->x1, bandWindowsBuffersPaddedXL->y1);
185 resWindowBufferSplit[SPLIT_L] = new Buf2dAligned(splitResWindowBounds);
186
187 splitResWindowBounds =
188 Rect32(resWindowBuffer->x0, tileCompAtLowerRes_.y1 + bandWindowsBuffersPaddedXH->y0,
189 resWindowBuffer->x1, tileCompAtLowerRes_.y1 + bandWindowsBuffersPaddedXH->y1);
190 resWindowBufferSplit[SPLIT_H] = new Buf2dAligned(splitResWindowBounds);
191
192 if(!absolute)
193 {
194 tileCompAtLowerRes_.toAbsolute();
195 bandWindowsBuffersPaddedXL->toAbsolute();
196 bandWindowsBuffersPaddedXH->toAbsolute();
197 }
198 }
199 bool alloc(bool clear)
200 {
201 if(allocated_)
202 return true;
203
204 // if top level window is present, then all buffers attach to this window
206 {
207 // ensure that top level window is allocated
208 if(!resWindowBufferHighestResREL_->alloc2d(clear))
209 return false;
210
211 // don't allocate bandWindows for windowed decompression
212 if(filterWidth_)
213 return true;
214
215 // attach to top level window
218
219 // tileCompResLower_ is null for lowest resolution
220 if(tileCompAtLowerRes_.numTileBandWindows)
221 {
222 for(uint8_t orientation = 0; orientation < bandWindowsBuffersPaddedREL_.size();
223 ++orientation)
224 {
225 switch(orientation)
226 {
229 tileCompAtLowerRes_.width(), 0);
230 break;
233 tileCompAtLowerRes_.height());
234 break;
237 tileCompAtLowerRes_.width(),
238 tileCompAtLowerRes_.height());
239 break;
240 default:
241 break;
242 }
243 }
246 tileCompAtLowerRes_.height());
247 }
248
249 // attach canvas windows to relative windows
250 for(uint8_t orientation = 0; orientation < bandWindowsBuffersPaddedREL_.size(); ++orientation)
251 {
252 bandWindowsBuffersPadded_[orientation]->attach(bandWindowsBuffersPaddedREL_[orientation]);
253 }
255 for(uint8_t i = 0; i < SPLIT_NUM_ORIENTATIONS; ++i)
256 {
259 }
260 }
261 else
262 {
263 // 1. allocate resolution window
264 // resolution window is always allocated
265 if(!resWindowBufferREL_->alloc2d(clear))
266 return false;
268
269 // 2, allocate padded band windows
270 // band windows are allocated if present
271 for(auto& b : bandWindowsBuffersPadded_)
272 {
273 if(!b->alloc2d(clear))
274 return false;
275 }
276 for(uint8_t orientation = 0; orientation < bandWindowsBuffersPaddedREL_.size(); ++orientation)
277 {
278 bandWindowsBuffersPaddedREL_[orientation]->attach(
279 bandWindowsBuffersPaddedREL_[orientation]);
280 }
281
282 // 3. allocate split windows
283 if(tileCompAtLowerRes_.numTileBandWindows)
284 {
286 {
289 }
290 else
291 {
292 resWindowBufferSplit_[SPLIT_L]->alloc2d(clear);
293 resWindowBufferSplit_[SPLIT_H]->alloc2d(clear);
294 }
295 for(uint8_t i = 0; i < SPLIT_NUM_ORIENTATIONS; ++i)
296 {
299 }
300 }
301 }
302
303 allocated_ = true;
304
305 return true;
306 }
307
315 static Rect32 getPaddedBandWindow(uint8_t numDecomps, uint8_t orientation,
316 Rect32 unreducedTileCompWindow, Rect32 unreducedTileComp,
317 uint32_t padding, Rect32& paddedResWindow)
318 {
319 assert(orientation < t1::BAND_NUM_ORIENTATIONS);
320 if(numDecomps == 0)
321 {
322 assert(orientation == 0);
323 return unreducedTileCompWindow.grow_IN_PLACE(padding).intersection(&unreducedTileComp);
324 }
325 paddedResWindow = unreducedTileCompWindow;
326 auto oneLessDecompTile = unreducedTileComp;
327 if(numDecomps > 1)
328 {
329 paddedResWindow = ResSimple::getBandWindow(numDecomps - 1, 0, unreducedTileCompWindow);
330 oneLessDecompTile = ResSimple::getBandWindow(numDecomps - 1, 0, unreducedTileComp);
331 }
332 paddedResWindow.grow_IN_PLACE(2 * padding).clip_IN_PLACE(oneLessDecompTile);
333 paddedResWindow.setOrigin(oneLessDecompTile, true);
334
335 return ResSimple::getBandWindow(1, orientation, paddedResWindow);
336 }
337
339 {
340 return resWindowBuffer_->simple();
341 }
343 {
344 return resWindowBuffer_->simpleF();
345 }
351 {
352 return resWindowBufferSplitREL_[orientation];
353 }
355 {
356 return &bandWindowsBoundsPadded_[orientation];
357 }
359 {
360 return bandWindowsBuffersPaddedREL_[orientation];
361 }
363 {
364 return bandWindowsBuffersPadded_[orientation]->simple();
365 }
368 {
369 return bandWindowsBuffersPadded_[orientation]->simpleF();
370 }
372 {
373 return resWindowBufferREL_;
374 }
376 uint32_t filterWidth_;
377
378 ResSimple tileCompAtRes_; // numTileBandWindows> 0 will trigger creation of band window buffers
379 ResSimple tileCompAtLowerRes_; // numTileBandWindows==0 for lowest resolution
380
383 std::vector<Buf2dAligned*> bandWindowsBuffersPadded_;
384
385 /*
386 bandWindowsBoundsPadded_ is used for determining which precincts and code blocks overlap
387 the window of interest, in each respective resolution
388 */
389 std::vector<Rect32> bandWindowsBoundsPadded_;
390
394 std::vector<Buf2dAligned*> bandWindowsBuffersPaddedREL_;
395};
396
397} // namespace grk
eBandOrientation
Definition t1_common.h:28
@ BAND_ORIENT_HH
Definition t1_common.h:32
@ BAND_ORIENT_LL
Definition t1_common.h:29
@ BAND_ORIENT_LH
Definition t1_common.h:31
@ BAND_NUM_ORIENTATIONS
Definition t1_common.h:33
@ BAND_ORIENT_HL
Definition t1_common.h:30
ResWindow.
Definition CompressedChunkCache.h:36
eSplitOrientation
Definition ResWindow.h:57
@ SPLIT_H
Definition ResWindow.h:59
@ SPLIT_L
Definition ResWindow.h:58
@ SPLIT_NUM_ORIENTATIONS
Definition ResWindow.h:60
Rect< uint32_t > Rect32
Definition geometry.h:64
T ceildivpow2(T a, uint8_t b)
Definition intmath.h:39
Definition buffer.h:288
Definition buffer.h:262
T x1
Definition geometry.h:192
Rect< T > & clip_IN_PLACE(const Rect &rhs)
Definition geometry.h:372
Rect< T > intersection(const Rect< T > &rhs) const
Definition geometry.h:347
Rect< T > & toRelative(void)
Definition geometry.h:224
T x0
Definition geometry.h:192
Rect< T > & setOrigin(T origx, T origy, bool absolute)
Definition geometry.h:194
T y0
Definition geometry.h:192
Rect< T > & grow_IN_PLACE(T boundary)
Definition geometry.h:444
T y1
Definition geometry.h:192
Rect< T > & toAbsolute(void)
Definition geometry.h:234
Definition ResSimple.h:26
static Rect32 getBandWindow(uint8_t numDecomps, uint8_t orientation, Rect32 tileCompWindowUnreduced)
Get band window (in tile component coordinates) for specified number of decompositions.
Definition ResSimple.h:60
uint8_t numTileBandWindows
Definition ResSimple.h:92
void genSplitWindowBuffers(Buf2dAligned **resWindowBufferSplit, Buf2dAligned *resWindowBuffer, Buf2dAligned *bandWindowsBuffersPaddedXL, Buf2dAligned *bandWindowsBuffersPaddedXH, bool absolute)
Definition ResWindow.h:171
uint32_t filterWidth_
Definition ResWindow.h:376
ResSimple tileCompAtRes_
Definition ResWindow.h:378
Buf2dAligned * resWindowBufferSplit_[SPLIT_NUM_ORIENTATIONS]
Definition ResWindow.h:382
bool allocated_
Definition ResWindow.h:375
Buf2dAligned * resWindowBufferHighestResREL_
Definition ResWindow.h:391
std::vector< Buf2dAligned * > bandWindowsBuffersPadded_
Definition ResWindow.h:383
ResWindow(uint8_t numresolutions, uint8_t resno, Buf2dAligned *resWindowHighestResREL, ResSimple tileCompAtRes, ResSimple tileCompAtLowerRes, Rect32 resWindow, Rect32 tileCompWindowUnreduced, Rect32 tileCompUnreduced, uint32_t FILTER_WIDTH)
Definition ResWindow.h:76
~ResWindow()
Definition ResWindow.h:157
const Buf2dAligned * getBandWindowBufferPaddedREL(t1::eBandOrientation orientation) const
Definition ResWindow.h:358
const Buffer2dSimple< float > getBandWindowBufferPaddedSimpleF(t1::eBandOrientation orientation) const
Definition ResWindow.h:367
Buffer2d< T, AllocatorAligned > Buf2dAligned
Definition ResWindow.h:73
Buf2dAligned * resWindowBufferSplitREL_[SPLIT_NUM_ORIENTATIONS]
Definition ResWindow.h:393
const Buffer2dSimple< T > getBandWindowBufferPaddedSimple(t1::eBandOrientation orientation) const
Definition ResWindow.h:362
std::vector< Rect32 > bandWindowsBoundsPadded_
Definition ResWindow.h:389
Buf2dAligned * getResWindowBufferSplitREL(eSplitOrientation orientation) const
Definition ResWindow.h:350
Buf2dAligned * resWindowBufferREL_
Definition ResWindow.h:392
void disableBandWindowAllocation(void)
Definition ResWindow.h:346
Buffer2dSimple< T > getResWindowBufferSimple(void) const
Definition ResWindow.h:338
ResSimple tileCompAtLowerRes_
Definition ResWindow.h:379
Buffer2dSimple< float > getResWindowBufferSimpleF(void) const
Definition ResWindow.h:342
static Rect32 getPaddedBandWindow(uint8_t numDecomps, uint8_t orientation, Rect32 unreducedTileCompWindow, Rect32 unreducedTileComp, uint32_t padding, Rect32 &paddedResWindow)
Get band window (in tile component coordinates) for specified number of decompositions (with padding)...
Definition ResWindow.h:315
Buf2dAligned * resWindowBuffer_
Definition ResWindow.h:381
bool alloc(bool clear)
Definition ResWindow.h:199
Buf2dAligned * getResWindowBufferREL(void) const
Definition ResWindow.h:371
std::vector< Buf2dAligned * > bandWindowsBuffersPaddedREL_
Definition ResWindow.h:394
const Rect32 * getBandWindowPadded(t1::eBandOrientation orientation) const
Definition ResWindow.h:354
Definition TileComponentWindow.h:96
Definition TileComponentWindow.h:197