Grok 10.0.5
TileComponentWindow.h
Go to the documentation of this file.
1
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
41#include "ResWindow.h"
42
43namespace grk
44{
45
46template<class T>
47constexpr T getFilterPad(bool lossless)
48{
49 return lossless ? 1 : 2;
50}
51
52template<typename T>
53struct TileComponentWindowBase
54{
55 TileComponentWindowBase(bool isCompressor, bool lossless, bool wholeTileDecompress,
56 grk_rect32 unreducedTileComp, grk_rect32 reducedTileComp,
57 grk_rect32 unreducedImageCompWindow, uint8_t numresolutions,
58 uint8_t reducedNumResolutions)
59 : unreducedBounds_(unreducedTileComp), bounds_(reducedTileComp), compress_(isCompressor),
61 {
62 assert(reducedNumResolutions > 0);
63 auto currentRes = unreducedTileComp;
64 for(uint8_t i = 0; i < numresolutions; ++i)
65 {
66 bool finalResolution = i == numresolutions - 1;
67 ResSimple r(currentRes, finalResolution);
68 resolution_.push_back(r);
69 if(!finalResolution)
70 currentRes = ResSimple::getBandWindow(1, 0, currentRes);
71 }
72 std::reverse(resolution_.begin(), resolution_.end());
73
74 // generate bounds
75 unreducedBounds_ = unreducedImageCompWindow.intersection(unreducedBounds_);
76 assert(unreducedBounds_.valid());
77 bounds_ = unreducedImageCompWindow.scaleDownCeilPow2(
78 (uint32_t)(numresolutions - reducedNumResolutions));
79 bounds_ = bounds_.intersection(reducedTileComp);
80 assert(bounds_.valid());
81
82 // fill resolutions vector
83 auto tileCompAtRes = resolution_[reducedNumResolutions - 1];
84 auto tileCompAtLowerRes =
85 reducedNumResolutions > 1 ? resolution_[reducedNumResolutions - 2] : ResSimple();
86 // create resolution buffers
87 auto highestResWindow = new ResWindow<T>(
88 numresolutions, (uint8_t)(reducedNumResolutions - 1U), nullptr, tileCompAtRes,
89 tileCompAtLowerRes, bounds_, unreducedBounds_, unreducedTileComp,
90 wholeTileDecompress ? 0 : getFilterPad<uint32_t>(lossless));
91 // setting top level prevents allocation of tileCompBandWindows buffers
92 if(!useBandWindows())
93 highestResWindow->disableBandWindowAllocation();
94
95 // create windows for all resolutions except highest resolution
96 for(uint8_t resno = 0; resno < reducedNumResolutions - 1; ++resno)
97 {
98 // resolution window == LL band window of next highest resolution
99 auto resWindow = ResSimple::getBandWindow((uint8_t)(numresolutions - 1 - resno), 0,
101 resWindows.push_back(new ResWindow<T>(
103 useBandWindows() ? nullptr : highestResWindow->getResWindowBufferREL(),
104 resolution_[resno], resno > 0 ? resolution_[resno - 1] : ResSimple(), resWindow,
105 unreducedBounds_, unreducedTileComp,
106 wholeTileDecompress ? 0 : getFilterPad<uint32_t>(lossless)));
107 }
108 resWindows.push_back(highestResWindow);
109 }
110 virtual ~TileComponentWindowBase()
111 {
112 for(auto& b : this->resWindows)
113 delete b;
114 }
120 grk_rect32 bounds() const
121 {
122 return bounds_;
123 }
124 grk_rect32 unreducedBounds() const
125 {
126 return unreducedBounds_;
127 }
128 bool alloc()
129 {
130 for(auto& b : resWindows)
131 {
132 if(!b->alloc(!compress_))
133 return false;
134 }
135
136 return true;
137 }
138
139 protected:
140 bool useBandWindows() const
141 {
142 return !this->wholeTileDecompress_;
143 }
144 // windowed bounds for windowed decompress, otherwise full bounds
145 std::vector<ResWindow<T>*> resWindows;
146 /******************************************************/
147 // decompress: unreduced/reduced image component window
148 // compress: unreduced/reduced tile component
150 grk_rect32 bounds_;
151 /******************************************************/
152
153 std::vector<ResSimple> resolution_;
156};
157
158template<typename T>
159struct TileComponentWindow : public TileComponentWindowBase<T>
160{
161 typedef grk_buf2d<T, AllocatorAligned> Buf2dAligned;
162 TileComponentWindow(bool isCompressor, bool lossless, bool wholeTileDecompress,
163 grk_rect32 unreducedTileComp, grk_rect32 reducedTileComp,
164 grk_rect32 unreducedImageCompWindow, uint8_t numresolutions,
165 uint8_t reducedNumResolutions)
166 : TileComponentWindowBase<T>(isCompressor, lossless, wholeTileDecompress, unreducedTileComp,
167 reducedTileComp, unreducedImageCompWindow, numresolutions,
168 reducedNumResolutions)
169
170 {}
171 ~TileComponentWindow() = default;
172
187 void toRelativeCoordinates(uint8_t resno, eBandOrientation orientation, uint32_t& offsetx,
188 uint32_t& offsety) const
189 {
190 assert(resno < this->resolution_.size());
191
192 auto res = this->resolution_[resno];
193 auto band = res.tileBand + getBandIndex(resno, orientation);
194
195 // get offset relative to band
196 offsetx -= band->x0;
197 offsety -= band->y0;
198
199 if(useBufferCoordinatesForCodeblock() && resno > 0)
200 {
201 auto resLower = this->resolution_[resno - 1U];
202
203 if(orientation & 1)
204 offsetx += resLower.width();
205 if(orientation & 2)
206 offsety += resLower.height();
207 }
208 }
209 template<typename F>
210 void postProcess(Buf2dAligned& src, uint8_t resno, eBandOrientation bandOrientation,
211 DecompressBlockExec* block)
212 {
213 grk_buf2d<int32_t, AllocatorAligned> dst;
214 dst = getCodeBlockDestWindowREL(resno, bandOrientation);
215 dst.copyFrom<F>(src, F(block));
216 }
217
227 const Buf2dAligned* getBandWindowBufferPaddedREL(uint8_t resno,
228 eBandOrientation orientation) const
229 {
230 assert(resno < this->resolution_.size());
231 assert(resno > 0 || orientation == BAND_ORIENT_LL);
232
233 if(resno == 0 && (this->compress_ || this->wholeTileDecompress_))
234 return this->resWindows[0]->getResWindowBufferREL();
235
236 return this->resWindows[resno]->getBandWindowBufferPaddedREL(orientation);
237 }
247 const grk_buf2d_simple<int32_t>
248 getBandWindowBufferPaddedSimple(uint8_t resno, eBandOrientation orientation) const
249 {
250 assert(resno < this->resolution_.size());
251 assert(resno > 0 || orientation == BAND_ORIENT_LL);
252
253 if(resno == 0 && (this->compress_ || this->wholeTileDecompress_))
254 return this->resWindows[0]->getResWindowBufferSimple();
255
256 return this->resWindows[resno]->getBandWindowBufferPaddedSimple(orientation);
257 }
267 const grk_buf2d_simple<float>
268 getBandWindowBufferPaddedSimpleF(uint8_t resno, eBandOrientation orientation) const
269 {
270 assert(resno < this->resolution_.size());
271 assert(resno > 0 || orientation == BAND_ORIENT_LL);
272
273 if(resno == 0 && (this->compress_ || this->wholeTileDecompress_))
274 return this->resWindows[0]->getResWindowBufferSimpleF();
275
276 return this->resWindows[resno]->getBandWindowBufferPaddedSimpleF(orientation);
277 }
278
286 const grk_rect32* getBandWindowPadded(uint8_t resno, eBandOrientation orientation) const
287 {
288 return this->resWindows[resno]->getBandWindowPadded(orientation);
289 }
290 /*
291 * Get intermediate split window
292 *
293 * @param orientation 0 for upper split window, and 1 for lower split window
294 */
295 const Buf2dAligned* getResWindowBufferSplitREL(uint8_t resno,
296 eSplitOrientation orientation) const
297 {
298 assert(resno > 0 && resno < this->resolution_.size());
299
300 return this->resWindows[resno]->getResWindowBufferSplitREL(orientation);
301 }
302 /*
303 * Get intermediate split window simple buffer
304 *
305 * @param orientation 0 for upper split window, and 1 for lower split window
306 */
307 const grk_buf2d_simple<int32_t>
308 getResWindowBufferSplitSimple(uint8_t resno, eSplitOrientation orientation) const
309 {
310 return getResWindowBufferSplitREL(resno, orientation)->simple();
311 }
312
313 /*
314 * Get intermediate split window simpleF buffer
315 *
316 * @param orientation 0 for upper split window, and 1 for lower split window
317 */
318 const grk_buf2d_simple<float>
319 getResWindowBufferSplitSimpleF(uint8_t resno, eSplitOrientation orientation) const
320 {
321 return getResWindowBufferSplitREL(resno, orientation)->simpleF();
322 }
323
330 const Buf2dAligned* getResWindowBufferREL(uint32_t resno) const
331 {
332 return this->resWindows[resno]->getResWindowBufferREL();
333 }
340 const grk_buf2d_simple<int32_t> getResWindowBufferSimple(uint32_t resno) const
341 {
342 return getResWindowBufferREL(resno)->simple();
343 }
350 const grk_buf2d_simple<float> getResWindowBufferSimpleF(uint32_t resno) const
351 {
352 return getResWindowBufferREL(resno)->simpleF();
353 }
354
360 uint32_t getResWindowBufferHighestStride(void) const
361 {
362 return getResWindowBufferHighestREL()->stride;
363 }
364
370 grk_buf2d_simple<int32_t> getResWindowBufferHighestSimple(void) const
371 {
372 return getResWindowBufferHighestREL()->simple();
373 }
379 grk_buf2d_simple<float> getResWindowBufferHighestSimpleF(void) const
380 {
381 return getResWindowBufferHighestREL()->simpleF();
382 }
383 uint64_t stridedArea(void) const
384 {
385 auto win = getResWindowBufferHighestREL();
386 return win->stride * win->height();
387 }
388
389 // set data to buf without owning it
390 void attach(T* buffer, uint32_t stride)
391 {
392 getResWindowBufferHighestREL()->attach(buffer, stride);
393 }
394 // transfer data to buf, and cease owning it
395 void transfer(T** buffer, uint32_t* stride)
396 {
397 getResWindowBufferHighestREL()->transfer(buffer, stride);
398 }
399
400 private:
408 const Buf2dAligned* getCodeBlockDestWindowREL(uint8_t resno, eBandOrientation orientation) const
409 {
410 return (useBufferCoordinatesForCodeblock())
411 ? getResWindowBufferHighestREL()
412 : getBandWindowBufferPaddedREL(resno, orientation);
413 }
419 Buf2dAligned* getResWindowBufferHighestREL(void) const
420 {
421 return this->resWindows.back()->getResWindowBufferREL();
422 }
423 bool useBufferCoordinatesForCodeblock() const
424 {
425 return this->compress_ || !this->wholeTileDecompress_;
426 }
427 uint8_t getBandIndex(uint8_t resno, eBandOrientation orientation) const
428 {
429 uint8_t index = 0;
430 if(resno > 0)
431 index = (uint8_t)orientation - 1;
432
433 return index;
434 }
435};
436
437} // namespace grk
uint8_t resno
Definition BlockExec.h:53
eBandOrientation bandOrientation
Definition BlockExec.h:33
uint8_t numresolutions
number of resolutions
Definition CodingParams.h:58
uint8_t * buffer
packet header storage original buffer
Definition PPMMarker.h:64
grk_rect32 bounds_
Definition Precinct.h:57
grk_buf2d< T, AllocatorAligned > Buf2dAligned
Definition ResWindow.h:73
grk_rect32 bounds
Definition SparseCanvas.h:275
bool wholeTileDecompress
Definition TileComponent.h:56
grk_rect32 unreducedBounds_
Definition TileComponentWindow.h:149
bool compress_
Definition TileComponentWindow.h:154
std::vector< ResSimple > resolution_
Definition TileComponentWindow.h:153
std::vector< ResWindow< T > * > resWindows
Definition TileComponentWindow.h:145
bool wholeTileDecompress_
Definition TileComponentWindow.h:155
grk_rect< uint32_t > grk_rect32
Definition TileCache.h:61
Copyright (C) 2016-2023 Grok Image Compression Inc.
Definition ICacheable.h:20
constexpr T getFilterPad(bool lossless)
Definition TileComponentWindow.h:47
uint8_t orientation
Definition plugin_interface.h:42