Grok 15.1.0
ResWindow.h
Go to the documentation of this file.
17#pragma once
18
19#include "grk_includes.h"
20#include <stdexcept>
21#include <algorithm>
22
23/*
24 Various coordinate systems are used to describe regions in the tile component buffer.
25
26 1) Canvas coordinates: JPEG 2000 global image coordinates.
27
28 2) Tile component coordinates: canvas coordinates with sub-sampling applied
29
30 3) Band coordinates: coordinates relative to a specified sub-band's origin
31
32 4) Buffer coordinates: coordinate system where all resolutions are translated
33 to common origin (0,0). If each code block is translated relative to the origin of the
34 resolution that **it belongs to**, the blocks are then all in buffer coordinate system
35
36 Note: the name of any method or variable returning non canvas coordinates is appended
37 with "REL", to signify relative coordinates.
38
39 */
40
41namespace grk
42{
43
50
51template<typename T>
52struct TileComponentWindow;
53template<typename T>
54struct TileComponentWindowBase;
55
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, grk_rect32 resWindow,
78 grk_rect32 tileCompWindowUnreduced, grk_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 grk_rect32 resWindowPadded;
90 for(uint8_t orient = 0; orient < ((resno) > 0 ? 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 < 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 = grk_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 = grk_rect32(resWindowBuffer->x0, bandWindowsBuffersPaddedXL->y0,
184 resWindowBuffer->x1, bandWindowsBuffersPaddedXL->y1);
185 resWindowBufferSplit[SPLIT_L] = new Buf2dAligned(splitResWindowBounds);
186
187 splitResWindowBounds =
188 grk_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 {
227 case BAND_ORIENT_HL:
229 tileCompAtLowerRes_.width(), 0);
230 break;
231 case BAND_ORIENT_LH:
233 tileCompAtLowerRes_.height());
234 break;
235 case BAND_ORIENT_HH:
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 grk_rect32 getPaddedBandWindow(uint8_t numDecomps, uint8_t orientation,
316 grk_rect32 unreducedTileCompWindow,
317 grk_rect32 unreducedTileComp, uint32_t padding,
318 grk_rect32& paddedResWindow)
319 {
320 assert(orientation < BAND_NUM_ORIENTATIONS);
321 if(numDecomps == 0)
322 {
323 assert(orientation == 0);
324 return unreducedTileCompWindow.grow_IN_PLACE(padding).intersection(&unreducedTileComp);
325 }
326 paddedResWindow = unreducedTileCompWindow;
327 auto oneLessDecompTile = unreducedTileComp;
328 if(numDecomps > 1)
329 {
330 paddedResWindow = ResSimple::getBandWindow(numDecomps - 1, 0, unreducedTileCompWindow);
331 oneLessDecompTile = ResSimple::getBandWindow(numDecomps - 1, 0, unreducedTileComp);
332 }
333 paddedResWindow.grow_IN_PLACE(2 * padding).clip_IN_PLACE(&oneLessDecompTile);
334 paddedResWindow.setOrigin(oneLessDecompTile, true);
335
336 return ResSimple::getBandWindow(1, orientation, paddedResWindow);
337 }
338
340 {
341 return resWindowBuffer_->simple();
342 }
344 {
345 return resWindowBuffer_->simpleF();
346 }
352 {
353 return resWindowBufferSplitREL_[orientation];
354 }
356 {
357 return &bandWindowsBoundsPadded_[orientation];
358 }
360 {
361 return bandWindowsBuffersPaddedREL_[orientation];
362 }
365 {
366 return bandWindowsBuffersPadded_[orientation]->simple();
367 }
369 {
370 return bandWindowsBuffersPadded_[orientation]->simpleF();
371 }
373 {
374 return resWindowBufferREL_;
375 }
377 uint32_t filterWidth_;
378
379 ResSimple tileCompAtRes_; // numTileBandWindows> 0 will trigger creation of band window buffers
380 ResSimple tileCompAtLowerRes_; // numTileBandWindows==0 for lowest resolution
381
384 std::vector<Buf2dAligned*> bandWindowsBuffersPadded_;
385
386 /*
387 bandWindowsBoundsPadded_ is used for determining which precincts and code blocks overlap
388 the window of interest, in each respective resolution
389 */
390 std::vector<grk_rect32> bandWindowsBoundsPadded_;
391
395 std::vector<Buf2dAligned*> bandWindowsBuffersPaddedREL_;
396};
397
398} // namespace grk
Copyright (C) 2016-2025 Grok Image Compression Inc.
Definition ICacheable.h:20
grk_rect< uint32_t > grk_rect32
Definition geometry.h:61
eSplitOrientation
Definition ResWindow.h:45
@ SPLIT_H
Definition ResWindow.h:47
@ SPLIT_L
Definition ResWindow.h:46
@ SPLIT_NUM_ORIENTATIONS
Definition ResWindow.h:48
eBandOrientation
Definition ResSimple.h:23
@ BAND_ORIENT_HH
Definition ResSimple.h:27
@ BAND_ORIENT_HL
Definition ResSimple.h:25
@ BAND_NUM_ORIENTATIONS
Definition ResSimple.h:28
@ BAND_ORIENT_LH
Definition ResSimple.h:26
@ BAND_ORIENT_LL
Definition ResSimple.h:24
T ceildivpow2(T a, uint32_t b)
Definition grk_intmath.h:40
Definition ResSimple.h:43
uint8_t numTileBandWindows
Definition ResSimple.h:109
static grk_rect32 getBandWindow(uint8_t numDecomps, uint8_t orientation, grk_rect32 tileCompWindowUnreduced)
Get band window (in tile component coordinates) for specified number of decompositions.
Definition ResSimple.h:77
void genSplitWindowBuffers(Buf2dAligned **resWindowBufferSplit, Buf2dAligned *resWindowBuffer, Buf2dAligned *bandWindowsBuffersPaddedXL, Buf2dAligned *bandWindowsBuffersPaddedXH, bool absolute)
Definition ResWindow.h:171
uint32_t filterWidth_
Definition ResWindow.h:377
grk_buf2d_simple< float > getResWindowBufferSimpleF(void) const
Definition ResWindow.h:343
ResSimple tileCompAtRes_
Definition ResWindow.h:379
ResWindow(uint8_t numresolutions, uint8_t resno, Buf2dAligned *resWindowHighestResREL, ResSimple tileCompAtRes, ResSimple tileCompAtLowerRes, grk_rect32 resWindow, grk_rect32 tileCompWindowUnreduced, grk_rect32 tileCompUnreduced, uint32_t FILTER_WIDTH)
Definition ResWindow.h:76
const grk_rect32 * getBandWindowPadded(eBandOrientation orientation) const
Definition ResWindow.h:355
Buf2dAligned * resWindowBufferSplit_[SPLIT_NUM_ORIENTATIONS]
Definition ResWindow.h:383
bool allocated_
Definition ResWindow.h:376
Buf2dAligned * resWindowBufferHighestResREL_
Definition ResWindow.h:392
std::vector< Buf2dAligned * > bandWindowsBuffersPadded_
Definition ResWindow.h:384
const grk_buf2d_simple< float > getBandWindowBufferPaddedSimpleF(eBandOrientation orientation) const
Definition ResWindow.h:368
~ResWindow()
Definition ResWindow.h:157
const grk_buf2d_simple< int32_t > getBandWindowBufferPaddedSimple(eBandOrientation orientation) const
Definition ResWindow.h:364
Buf2dAligned * resWindowBufferSplitREL_[SPLIT_NUM_ORIENTATIONS]
Definition ResWindow.h:394
grk_buf2d_simple< int32_t > getResWindowBufferSimple(void) const
Definition ResWindow.h:339
Buf2dAligned * getResWindowBufferSplitREL(eSplitOrientation orientation) const
Definition ResWindow.h:351
Buf2dAligned * resWindowBufferREL_
Definition ResWindow.h:393
void disableBandWindowAllocation(void)
Definition ResWindow.h:347
std::vector< grk_rect32 > bandWindowsBoundsPadded_
Definition ResWindow.h:390
ResSimple tileCompAtLowerRes_
Definition ResWindow.h:380
static grk_rect32 getPaddedBandWindow(uint8_t numDecomps, uint8_t orientation, grk_rect32 unreducedTileCompWindow, grk_rect32 unreducedTileComp, uint32_t padding, grk_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:382
bool alloc(bool clear)
Definition ResWindow.h:199
Buf2dAligned * getResWindowBufferREL(void) const
Definition ResWindow.h:372
grk_buf2d< T, AllocatorAligned > Buf2dAligned
Definition ResWindow.h:73
const Buf2dAligned * getBandWindowBufferPaddedREL(eBandOrientation orientation) const
Definition ResWindow.h:359
std::vector< Buf2dAligned * > bandWindowsBuffersPaddedREL_
Definition ResWindow.h:395
Definition TileComponentWindow.h:54
Definition TileComponentWindow.h:160
Definition buffer.h:206
Definition buffer.h:230
T y1
Definition geometry.h:125
grk_rect< T > & setOrigin(T origx, T origy, bool absolute)
Definition geometry.h:127
T x0
Definition geometry.h:125
grk_rect< T > intersection(const grk_rect< T > rhs) const
Definition geometry.h:281
grk_rect< T > & toRelative(void)
Definition geometry.h:157
T x1
Definition geometry.h:125
grk_rect< T > & toAbsolute(void)
Definition geometry.h:167
grk_rect< T > & clip_IN_PLACE(const grk_rect< T > &rhs)
Definition geometry.h:301
grk_rect< T > & grow_IN_PLACE(T boundary)
Definition geometry.h:368
T y0
Definition geometry.h:125