Grok 10.0.5
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>
69struct ResWindow
70{
71 friend struct TileComponentWindowBase<T>;
72 friend struct TileComponentWindow<T>;
73 typedef grk_buf2d<T, AllocatorAligned> Buf2dAligned;
74
75 private:
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,
79 uint32_t FILTER_WIDTH)
80 : allocated_(false), filterWidth_(FILTER_WIDTH), tileCompAtRes_(tileCompAtRes),
81 tileCompAtLowerRes_(tileCompAtLowerRes),
82 resWindowBuffer_(new Buf2dAligned(resWindow)), resWindowBufferSplit_{nullptr, nullptr},
83 resWindowBufferHighestResREL_(resWindowHighestResREL),
84 resWindowBufferREL_(new Buf2dAligned(resWindow.width(), resWindow.height())),
85 resWindowBufferSplitREL_{nullptr, nullptr}
86 {
87 resWindowBuffer_->setOrigin(tileCompAtRes_, true);
88 uint8_t numDecomps =
89 (resno == 0) ? (uint8_t)(numresolutions - 1U) : (uint8_t)(numresolutions - resno);
90 grk_rect32 resWindowPadded;
91 for(uint8_t orient = 0; orient < ((resno) > 0 ? BAND_NUM_ORIENTATIONS : 1); orient++)
92 {
93 // todo: should only need padding equal to FILTER_WIDTH, not 2*FILTER_WIDTH
94 auto bandWindow =
95 getPaddedBandWindow(numDecomps, orient, tileCompWindowUnreduced, tileCompUnreduced,
96 2 * FILTER_WIDTH, resWindowPadded);
97 grk_rect32 band = tileCompAtRes_.tileBand[BAND_ORIENT_LL];
98 if(resno > 0)
99 band = orient == BAND_ORIENT_LL ? grk_rect32(tileCompAtLowerRes_)
100 : tileCompAtRes_.tileBand[orient - 1];
101 bandWindow.setOrigin(band, true);
102 assert(bandWindow.intersection(band).setOrigin(bandWindow, true) == bandWindow);
103 bandWindowsBoundsPadded_.push_back(bandWindow);
104 }
105 // windowed decompression
106 if(FILTER_WIDTH)
107 {
108 if(tileCompAtLowerRes_.numTileBandWindows)
109 {
110 assert(resno > 0);
111 resWindowBuffer_->setRect(resWindowPadded);
112 resWindowBufferREL_->setRect(resWindowBuffer_->toRelative());
113 resWindowBuffer_->toAbsolute();
114
115 for(uint8_t orient = 0; orient < BAND_NUM_ORIENTATIONS; orient++)
116 {
117 auto bandWindow = bandWindowsBoundsPadded_[orient];
118 bandWindowsBuffersPadded_.push_back(new Buf2dAligned(bandWindow, true));
120 new Buf2dAligned(bandWindow.toRelative(), true));
121 }
122 genSplitWindowBuffers(resWindowBufferSplit_, resWindowBuffer_,
123 bandWindowsBuffersPadded_[BAND_ORIENT_LL],
124 bandWindowsBuffersPadded_[BAND_ORIENT_LH], true);
125 genSplitWindowBuffers(resWindowBufferSplitREL_, resWindowBuffer_,
126 bandWindowsBuffersPadded_[BAND_ORIENT_LL],
127 bandWindowsBuffersPadded_[BAND_ORIENT_LH], false);
128 }
129 }
130 else
131 {
132 assert(tileCompAtRes_.numTileBandWindows == 3 ||
133 !tileCompAtLowerRes.numTileBandWindows);
134
135 // dummy LL band window
136 if(tileCompAtLowerRes_.numTileBandWindows && tileCompAtLowerRes_.valid())
137 {
138 bandWindowsBuffersPadded_.push_back(new Buf2dAligned(0, 0));
139 bandWindowsBuffersPaddedREL_.push_back(new Buf2dAligned(0, 0));
140 for(uint32_t i = 0; i < tileCompAtRes_.numTileBandWindows; ++i)
141 {
142 auto tileCompBand = tileCompAtRes_.tileBand + i;
143
144 auto band = grk_rect32(tileCompBand);
145 bandWindowsBuffersPadded_.push_back(new Buf2dAligned(band));
146 bandWindowsBuffersPaddedREL_.push_back(new Buf2dAligned(band.toRelative()));
147 }
148 for(uint8_t i = 0; i < SPLIT_NUM_ORIENTATIONS; i++)
149 {
150 grk_rect32 split = resWindowBuffer_;
151 split.y0 = (resWindowBuffer_->y0 == 0
152 ? 0
153 : ceildivpow2<uint32_t>(resWindowBuffer_->y0 - i, 1));
154 split.y1 = (resWindowBuffer_->y1 == 0
155 ? 0
156 : ceildivpow2<uint32_t>(resWindowBuffer_->y1 - i, 1));
157 resWindowBufferSplit_[i] = new Buf2dAligned(split);
159 }
160 }
161 }
162 }
163 ~ResWindow()
164 {
165 delete resWindowBufferREL_;
166 for(auto& b : bandWindowsBuffersPaddedREL_)
167 delete b;
168 for(uint32_t i = 0; i < SPLIT_NUM_ORIENTATIONS; ++i)
169 delete resWindowBufferSplitREL_[i];
170
171 delete resWindowBuffer_;
172 for(auto& b : bandWindowsBuffersPadded_)
173 delete b;
174 for(uint32_t i = 0; i < SPLIT_NUM_ORIENTATIONS; ++i)
175 delete resWindowBufferSplit_[i];
176 }
177 void genSplitWindowBuffers(Buf2dAligned** resWindowBufferSplit, Buf2dAligned* resWindowBuffer,
178 Buf2dAligned* bandWindowsBuffersPaddedXL,
179 Buf2dAligned* bandWindowsBuffersPaddedXH, bool absolute)
180 {
181 if(!absolute)
182 {
183 tileCompAtLowerRes_.toRelative();
184 bandWindowsBuffersPaddedXL->toRelative();
185 bandWindowsBuffersPaddedXH->toRelative();
186 }
187
188 // two windows formed by horizontal pass and used as input for vertical pass
189 auto splitResWindowBounds = grk_rect32(resWindowBuffer->x0, bandWindowsBuffersPaddedXL->y0,
190 resWindowBuffer->x1, bandWindowsBuffersPaddedXL->y1);
191 resWindowBufferSplit[SPLIT_L] = new Buf2dAligned(splitResWindowBounds);
192
193 splitResWindowBounds = grk_rect32(
194 resWindowBuffer->x0, tileCompAtLowerRes_.y1 + bandWindowsBuffersPaddedXH->y0,
195 resWindowBuffer->x1, tileCompAtLowerRes_.y1 + bandWindowsBuffersPaddedXH->y1);
196 resWindowBufferSplit[SPLIT_H] = new Buf2dAligned(splitResWindowBounds);
197
198 if(!absolute)
199 {
200 tileCompAtLowerRes_.toAbsolute();
201 bandWindowsBuffersPaddedXL->toAbsolute();
202 bandWindowsBuffersPaddedXH->toAbsolute();
203 }
204 }
205 bool alloc(bool clear)
206 {
207 if(allocated_)
208 return true;
209
210 // if top level window is present, then all buffers attach to this window
212 {
213 // ensure that top level window is allocated
214 if(!resWindowBufferHighestResREL_->alloc2d(clear))
215 return false;
216
217 // don't allocate bandWindows for windowed decompression
218 if(filterWidth_)
219 return true;
220
221 // attach to top level window
224
225 // tileCompResLower_ is null for lowest resolution
226 if(tileCompAtLowerRes_.numTileBandWindows)
227 {
228 for(uint8_t orientation = 0; orientation < bandWindowsBuffersPaddedREL_.size();
229 ++orientation)
230 {
231 switch(orientation)
232 {
233 case BAND_ORIENT_HL:
236 break;
237 case BAND_ORIENT_LH:
240 break;
241 case BAND_ORIENT_HH:
244 tileCompAtLowerRes_.height());
245 break;
246 default:
247 break;
248 }
249 }
252 tileCompAtLowerRes_.height());
253 }
254
255 // attach canvas windows to relative windows
256 for(uint8_t orientation = 0; orientation < bandWindowsBuffersPaddedREL_.size();
257 ++orientation)
258 {
261 }
263 for(uint8_t i = 0; i < SPLIT_NUM_ORIENTATIONS; ++i)
264 {
267 }
268 }
269 else
270 {
271 // 1. allocate resolution window
272 // resolution window is always allocated
273 if(!resWindowBufferREL_->alloc2d(clear))
274 return false;
276
277 // 2, allocate padded band windows
278 // band windows are allocated if present
279 for(auto& b : bandWindowsBuffersPadded_)
280 {
281 if(!b->alloc2d(clear))
282 return false;
283 }
284 for(uint8_t orientation = 0; orientation < bandWindowsBuffersPaddedREL_.size();
285 ++orientation)
286 {
289 }
290
291 // 3. allocate split windows
292 if(tileCompAtLowerRes_.numTileBandWindows)
293 {
295 {
298 tileCompAtLowerRes_.height());
299 }
300 else
301 {
302 resWindowBufferSplit_[SPLIT_L]->alloc2d(clear);
303 resWindowBufferSplit_[SPLIT_H]->alloc2d(clear);
304 }
305 for(uint8_t i = 0; i < SPLIT_NUM_ORIENTATIONS; ++i)
306 {
309 }
310 }
311 }
312
313 allocated_ = true;
314
315 return true;
316 }
317
325 static grk_rect32 getPaddedBandWindow(uint8_t numDecomps, uint8_t orientation,
326 grk_rect32 unreducedTileCompWindow,
327 grk_rect32 unreducedTileComp, uint32_t padding,
328 grk_rect32& paddedResWindow)
329 {
330 assert(orientation < BAND_NUM_ORIENTATIONS);
331 if(numDecomps == 0)
332 {
333 assert(orientation == 0);
334 return unreducedTileCompWindow.grow_IN_PLACE(padding).intersection(&unreducedTileComp);
335 }
336 paddedResWindow = unreducedTileCompWindow;
337 auto oneLessDecompTile = unreducedTileComp;
338 if(numDecomps > 1)
339 {
340 paddedResWindow = ResSimple::getBandWindow(numDecomps - 1, 0, unreducedTileCompWindow);
341 oneLessDecompTile = ResSimple::getBandWindow(numDecomps - 1, 0, unreducedTileComp);
342 }
343 paddedResWindow.grow_IN_PLACE(2 * padding).clip_IN_PLACE(&oneLessDecompTile);
344 paddedResWindow.setOrigin(oneLessDecompTile, true);
345
346 return ResSimple::getBandWindow(1, orientation, paddedResWindow);
347 }
348
349 grk_buf2d_simple<int32_t> getResWindowBufferSimple(void) const
350 {
351 return resWindowBuffer_->simple();
352 }
353 grk_buf2d_simple<float> getResWindowBufferSimpleF(void) const
354 {
355 return resWindowBuffer_->simpleF();
356 }
357 void disableBandWindowAllocation(void)
358 {
360 }
361 Buf2dAligned* getResWindowBufferSplitREL(eSplitOrientation orientation) const
362 {
364 }
365 const grk_rect32* getBandWindowPadded(eBandOrientation orientation) const
366 {
368 }
369 const Buf2dAligned* getBandWindowBufferPaddedREL(eBandOrientation orientation) const
370 {
372 }
373 const grk_buf2d_simple<int32_t>
374 getBandWindowBufferPaddedSimple(eBandOrientation orientation) const
375 {
376 return bandWindowsBuffersPadded_[orientation]->simple();
377 }
378 const grk_buf2d_simple<float>
379 getBandWindowBufferPaddedSimpleF(eBandOrientation orientation) const
380 {
381 return bandWindowsBuffersPadded_[orientation]->simpleF();
382 }
383 Buf2dAligned* getResWindowBufferREL(void) const
384 {
385 return resWindowBufferREL_;
386 }
388 uint32_t filterWidth_;
389
390 ResSimple tileCompAtRes_; // numTileBandWindows> 0 will trigger creation of band window buffers
391 ResSimple tileCompAtLowerRes_; // numTileBandWindows==0 for lowest resolution
392
394 Buf2dAligned* resWindowBufferSplit_[SPLIT_NUM_ORIENTATIONS];
395 std::vector<Buf2dAligned*> bandWindowsBuffersPadded_;
396
397 /*
398 bandWindowsBoundsPadded_ is used for determining which precincts and code blocks overlap
399 the window of interest, in each respective resolution
400 */
401 std::vector<grk_rect32> bandWindowsBoundsPadded_;
402
405 Buf2dAligned* resWindowBufferSplitREL_[SPLIT_NUM_ORIENTATIONS];
406 std::vector<Buf2dAligned*> bandWindowsBuffersPaddedREL_;
407};
408
409} // namespace grk
uint8_t resno
Definition BlockExec.h:53
uint8_t numresolutions
number of resolutions
Definition CodingParams.h:58
Buf2dAligned * resWindowBufferHighestResREL_
Definition ResWindow.h:403
Buf2dAligned * resWindowBufferREL_
Definition ResWindow.h:404
uint32_t filterWidth_
Definition ResWindow.h:388
std::vector< grk_rect32 > bandWindowsBoundsPadded_
Definition ResWindow.h:401
grk_buf2d< T, AllocatorAligned > Buf2dAligned
Definition ResWindow.h:73
std::vector< Buf2dAligned * > bandWindowsBuffersPadded_
Definition ResWindow.h:395
ResSimple tileCompAtLowerRes_
Definition ResWindow.h:391
Buf2dAligned * resWindowBufferSplit_[SPLIT_NUM_ORIENTATIONS]
Definition ResWindow.h:394
ResSimple tileCompAtRes_
Definition ResWindow.h:390
std::vector< Buf2dAligned * > bandWindowsBuffersPaddedREL_
Definition ResWindow.h:406
bool allocated_
Definition ResWindow.h:387
Buf2dAligned * resWindowBuffer_
Definition ResWindow.h:393
Buf2dAligned * resWindowBufferSplitREL_[SPLIT_NUM_ORIENTATIONS]
Definition ResWindow.h:405
grk_rect< uint32_t > grk_rect32
Definition TileCache.h:61
@ BAND_ORIENT_HH
Definition TileCache.h:28
@ BAND_ORIENT_LH
Definition TileCache.h:27
@ BAND_ORIENT_HL
Definition TileCache.h:26
@ SPLIT_L
Definition TileCache.h:47
@ SPLIT_H
Definition TileCache.h:48
@ SPLIT_NUM_ORIENTATIONS
Definition TileCache.h:49
Copyright (C) 2016-2023 Grok Image Compression Inc.
Definition ICacheable.h:20
eSplitOrientation
Definition ResWindow.h:45
@ SPLIT_H
Definition ResWindow.h:47
@ SPLIT_L
Definition ResWindow.h:46
@ SPLIT_NUM_ORIENTATIONS
Definition ResWindow.h:48
uint8_t orientation
Definition plugin_interface.h:42
T y0
Definition TileCache.h:124