Grok  7.6.6
TileComponentWindowBuffer.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 namespace grk {
24 
30 template<typename T> struct ResWindow {
31 
32  // note:
33  // 1. any variable with 'tile' in its name is in canvas coordinates
34  // 2. band windows are relative to band origin
35  // 3. res windows are relate to LL band windows
36  ResWindow(uint8_t numresolutions,
37  uint8_t resno,
38  grk_buffer_2d<T> *resWindowTopLevel,
39  Resolution *tileCompAtRes,
40  Resolution *tileCompAtLowerRes,
41  grk_rect_u32 tileCompWindow,
42  grk_rect_u32 tileCompWindowUnreduced,
43  grk_rect_u32 tileCompUnreduced,
44  uint32_t FILTER_WIDTH) : m_allocated(false),
45  m_tileCompRes(tileCompAtRes),
46  m_tileCompResLower(tileCompAtLowerRes),
47  m_resWindow(new grk_buffer_2d<T>(tileCompWindow.width(), tileCompWindow.height())),
48  m_resWindowTopLevel(resWindowTopLevel),
49  m_filterWidth(FILTER_WIDTH)
50  {
51  (void)tileCompUnreduced;
52  for (uint32_t i = 0; i < SPLIT_NUM_ORIENTATIONS; ++i)
53  m_splitResWindow[i] = nullptr;
54  if (FILTER_WIDTH) {
55 
56  for (uint8_t orient = 0; orient < ( (resno) > 0 ? BAND_NUM_ORIENTATIONS : 1); orient++) {
57  grk_rect_u32 temp = getTileCompBandWindow(numresolutions, resno, orient,tileCompWindowUnreduced);
58  m_paddedTileBandWindow.push_back(temp.grow(2 * FILTER_WIDTH));
59  }
60 
61  if (m_tileCompResLower) {
62 
63  std::vector< grk_buffer_2d<T>* > unpaddedBandWindows;
64 
65  // 1. set up windows for horizontal and vertical passes
66  for (uint8_t i = 0; i < BAND_NUM_ORIENTATIONS; ++i) {
67  auto bandWindow = getTileCompBandWindow(numresolutions,resno,i,tileCompWindowUnreduced);
68  auto band = i ==0 ? *((grk_rect_u32*)m_tileCompResLower) : m_tileCompRes->band[i-1];
69  m_bandWindowBufferDim.push_back(new grk_buffer_2d<T>(bandWindow.grow(2 * FILTER_WIDTH, band).pan(-(int64_t)band.x0, -(int64_t)band.y0)));
70  unpaddedBandWindows.push_back(new grk_buffer_2d<T>(bandWindow.pan(-(int64_t)band.x0, -(int64_t)band.y0)));
71  }
72 
73  auto win_low = unpaddedBandWindows[BAND_ORIENT_LL];
74  auto win_high = unpaddedBandWindows[BAND_ORIENT_HL];
75  m_resWindow->x0 = min<uint32_t>(2 * win_low->x0, 2 * win_high->x0 + 1);
76  m_resWindow->x1 = min<uint32_t>(max<uint32_t>(2 * win_low->x1, 2 * win_high->x1 + 1), m_tileCompRes->width());
77  win_low = unpaddedBandWindows[BAND_ORIENT_LL];
78  win_high = unpaddedBandWindows[BAND_ORIENT_LH];
79  m_resWindow->y0 = min<uint32_t>(2 * win_low->y0, 2 * win_high->y0 + 1);
80  m_resWindow->y1 = min<uint32_t>(max<uint32_t>(2 * win_low->y1, 2 * win_high->y1 + 1), m_tileCompRes->height());
81 
82  // two windows formed by horizontal pass and used as input for vertical pass
83  grk_rect_u32 splitResWindowRect[SPLIT_NUM_ORIENTATIONS];
84  splitResWindowRect[SPLIT_L] = grk_rect_u32(m_resWindow->x0,
85  unpaddedBandWindows[BAND_ORIENT_LL]->y0,
86  m_resWindow->x1,
87  unpaddedBandWindows[BAND_ORIENT_LL]->y1);
88  m_splitResWindow[SPLIT_L] = new grk_buffer_2d<T>(splitResWindowRect[SPLIT_L]);
89 
90  splitResWindowRect[SPLIT_H] = grk_rect_u32(m_resWindow->x0,
91  unpaddedBandWindows[BAND_ORIENT_LH]->y0 + m_tileCompResLower->height(),
92  m_resWindow->x1,
93  unpaddedBandWindows[BAND_ORIENT_LH]->y1 + m_tileCompResLower->height());
94  m_splitResWindow[SPLIT_H] = new grk_buffer_2d<T>(splitResWindowRect[SPLIT_H]);
95 
96  for (auto &b : unpaddedBandWindows)
97  delete b;
98  }
99  } else {
100  // dummy LL band window
101  m_bandWindowBufferDim.push_back( new grk_buffer_2d<T>( 0,0) );
102  assert(tileCompAtRes->numBandWindows == 3 || !tileCompAtLowerRes);
103  if (tileCompAtLowerRes) {
104  for (uint32_t i = 0; i < tileCompAtRes->numBandWindows; ++i){
105  auto b = tileCompAtRes->band + i;
106  m_bandWindowBufferDim.push_back( new grk_buffer_2d<T>(b->width(),b->height() ) );
107  }
108  for (uint32_t i = 0; i < SPLIT_NUM_ORIENTATIONS; ++i) {
109  auto b = &tileCompWindow;
110  m_splitResWindow[i] = new grk_buffer_2d<T>(b->width(), b->height());
111  }
112  m_splitResWindow[SPLIT_L]->y1 = tileCompWindow.y0 + tileCompAtLowerRes->height();
114  }
115  }
116  }
118  delete m_resWindow;
119  for (auto &b : m_bandWindowBufferDim)
120  delete b;
121  for (uint32_t i = 0; i < SPLIT_NUM_ORIENTATIONS; ++i)
122  delete m_splitResWindow[i];
123  }
124 
125  bool alloc(bool clear){
126  if (m_allocated)
127  return true;
128 
129  // if top level window is present, then all buffers attach to this window
130  if (m_resWindowTopLevel) {
131  // ensure that top level window is allocated
132  if (!m_resWindowTopLevel->alloc(clear))
133  return false;
134 
135  // for now, we don't allocate bandWindows for windowed decode
136  if (m_filterWidth)
137  return true;
138 
139  // attach to top level window
141  m_resWindow->attach(m_resWindowTopLevel->data, m_resWindowTopLevel->stride);
142 
143  // m_tileCompResLower is null for lowest resolution
144  if (m_tileCompResLower) {
145  for (uint8_t orientation = 0; orientation < m_bandWindowBufferDim.size(); ++orientation){
146  switch(orientation){
147  case BAND_ORIENT_HL:
148  m_bandWindowBufferDim[orientation]->attach(m_resWindowTopLevel->data + m_tileCompResLower->width(),
149  m_resWindowTopLevel->stride);
150  break;
151  case BAND_ORIENT_LH:
153  m_resWindowTopLevel->stride);
154  break;
155  case BAND_ORIENT_HH:
156  m_bandWindowBufferDim[orientation]->attach(m_resWindowTopLevel->data + m_tileCompResLower->width() +
158  m_resWindowTopLevel->stride);
159  break;
160  default:
161  break;
162  }
163  }
166  m_resWindowTopLevel->stride);
167  }
168  } else {
169  // resolution window is always allocated
170  if (!m_resWindow->alloc(clear))
171  return false;
172  // for now, we don't allocate bandWindows for windowed decode
173  if (m_filterWidth)
174  return true;
175 
176  // band windows are allocated if present
177  for (auto &b : m_bandWindowBufferDim){
178  if (!b->alloc(clear))
179  return false;
180  }
181  if (m_tileCompResLower){
182  m_splitResWindow[SPLIT_L]->attach(m_resWindow->data, m_resWindow->stride);
184  }
185  }
186  m_allocated = true;
187 
188  return true;
189  }
190 
192  Resolution *m_tileCompRes; // when non-null, it triggers creation of band window buffers
193  Resolution *m_tileCompResLower; // null for lowest resolution
194  std::vector< grk_buffer_2d<T>* > m_bandWindowBufferDim; // coordinates are relative to band origin
195  std::vector< grk_rect_u32 > m_paddedTileBandWindow; // canvas coordinates
197  grk_buffer_2d<T> *m_resWindow; // resolution coordinates
198  grk_buffer_2d<T> *m_resWindowTopLevel; // resolution coordinates
199  uint32_t m_filterWidth;
200 };
201 
202 
203 /*
204  Various coordinate systems are used to describe windows in the tile component buffer.
205 
206  1) Canvas coordinate system: JPEG 2000 global image coordinates, independent of sub-sampling
207 
208  2) Tile coordinate system: canvas coordinates with sub-sampling accounted for
209 
210  3) Resolution coordinate system: coordinates relative to a particular resolution's top left hand corner
211 
212  4) Sub-band coordinate system: coordinates relative to a particular sub-band's top left hand corner
213 
214  */
215 template<typename T> struct TileComponentWindowBuffer {
216  TileComponentWindowBuffer(bool isCompressor,
217  bool lossless,
218  bool wholeTileDecompress,
219  grk_rect_u32 tileCompUnreduced,
220  grk_rect_u32 tileCompReduced,
221  grk_rect_u32 unreducedTileOrImageCompWindow,
222  Resolution *tileCompResolutions,
223  uint8_t numresolutions,
224  uint8_t reducedNumResolutions) : m_unreducedBounds(tileCompUnreduced),
225  m_bounds(tileCompReduced),
226  m_numResolutions(numresolutions),
227  m_compress(isCompressor),
228  m_wholeTileDecompress(wholeTileDecompress) {
229  if (!m_compress) {
230  auto unreducedImageCompWindow = unreducedTileOrImageCompWindow;
231  m_bounds = unreducedImageCompWindow.rectceildivpow2(m_numResolutions - reducedNumResolutions);
232  m_bounds = m_bounds.intersection(tileCompReduced);
233  assert(m_bounds.is_valid());
234  m_unreducedBounds = unreducedImageCompWindow.intersection(tileCompUnreduced);
235  assert(m_unreducedBounds.is_valid());
236  }
237  // fill resolutions vector
238  assert(reducedNumResolutions > 0);
239  for (uint32_t resno = 0; resno < reducedNumResolutions; ++resno)
240  m_tileCompResolutions.push_back(tileCompResolutions + resno);
241 
242  auto tileCompAtRes = tileCompResolutions + reducedNumResolutions - 1;
243  auto tileCompAtLowerRes = reducedNumResolutions > 1 ? tileCompResolutions + reducedNumResolutions - 2 : nullptr;
244  // create resolution buffers
245  auto topLevel = new ResWindow<T>(numresolutions,
246  reducedNumResolutions - 1,
247  nullptr,
248  tileCompAtRes,
249  tileCompAtLowerRes,
250  m_bounds,
252  tileCompUnreduced,
253  wholeTileDecompress ? 0 : getFilterPad<uint32_t>(lossless));
254  // setting top level blocks allocation of tileCompBandWindows buffers
255  if (!useBandWindows())
256  topLevel->m_resWindowTopLevel = topLevel->m_resWindow;
257 
258  for (uint8_t resno = 0; resno < reducedNumResolutions - 1; ++resno) {
259  // resolution window == next resolution band window at orientation 0
260  auto res_dims = getTileCompBandWindow(m_numResolutions, (uint8_t) ((resno + 1)), 0, unreducedTileOrImageCompWindow);
261  m_resWindows.push_back(
262  new ResWindow<T>(numresolutions,
263  resno,
264  useBandWindows() ? nullptr : topLevel->m_resWindow,
265  tileCompResolutions + resno,
266  resno > 0 ? tileCompResolutions + resno - 1 : nullptr,
267  res_dims,
269  tileCompUnreduced,
270  wholeTileDecompress ? 0 : getFilterPad<uint32_t>(lossless))
271  );
272  }
273  m_resWindows.push_back(topLevel);
274  }
275 
277  for (auto& b : m_resWindows)
278  delete b;
279  }
280 
290  void transform(uint8_t resno,eBandOrientation orientation, uint32_t &offsetx, uint32_t &offsety) const {
291  assert(resno < m_tileCompResolutions.size());
292 
293  auto res = m_tileCompResolutions[resno];
294  auto band = res->band + getBandIndex(resno,orientation);
295 
296  uint32_t x = offsetx;
297  uint32_t y = offsety;
298 
299  // get offset relative to band
300  x -= band->x0;
301  y -= band->y0;
302 
303  if (useResCoordsForCodeBlock() && resno > 0){
304  auto resLower = m_tileCompResolutions[ resno - 1];
305 
306  if (orientation & 1)
307  x += resLower->width();
308  if (orientation & 2)
309  y += resLower->height();
310  }
311  offsetx = x;
312  offsety = y;
313  }
314 
322  const grk_buffer_2d<T>* getCodeBlockDestWindow(uint8_t resno,eBandOrientation orientation) const {
323  return (useResCoordsForCodeBlock()) ? getTileBuf() : getBandWindow(resno,orientation);
324  }
325 
333  const grk_buffer_2d<T>* getWindow(uint8_t resno,eBandOrientation orientation) const{
334  return getBandWindow(resno,orientation);
335  }
336 
337  const grk_rect_u32 getPaddedTileBandWindow(uint8_t resno,eBandOrientation orientation) const{
338  if (m_resWindows[resno]->m_paddedTileBandWindow.empty())
339  return grk_rect_u32();
340  return m_resWindows[resno]->m_paddedTileBandWindow[orientation];
341  }
342 
343  /*
344  * Get intermediate split window.
345  *
346  * @param orientation 0 for upper split window, and 1 for lower split window
347  */
348  const grk_buffer_2d<T>* getSplitWindow(uint8_t resno,eSplitOrientation orientation) const{
349  assert(resno > 0 && resno < m_tileCompResolutions.size());
350 
351  return m_resWindows[resno]->m_splitResWindow[orientation];
352  }
353 
360  const grk_buffer_2d<T>* getWindow(uint32_t resno) const{
361  return m_resWindows[resno]->m_resWindow;
362  }
363 
369  const grk_buffer_2d<T>* getWindow(void) const{
370  return getTileBuf();
371  }
372 
373  bool alloc(){
374  for (auto& b : m_resWindows) {
375  if (!b->alloc(!m_compress))
376  return false;
377  }
378 
379  return true;
380  }
381 
388  return m_bounds;
389  }
390 
392  return m_unreducedBounds;
393  }
394 
395  uint64_t strided_area(void) const{
396  return getTileBuf()->stride * m_bounds.height();
397  }
398 
399  // set data to buf without owning it
400  void attach(T* buffer,uint32_t stride){
401  getTileBuf()->attach(buffer,stride);
402  }
403  // transfer data to buf, and cease owning it
404  void transfer(T** buffer, bool* owns, uint32_t *stride){
405  getTileBuf()->transfer(buffer,owns,stride);
406  }
407 
408 
409 private:
410 
411  bool useBandWindows() const{
412  //return !m_compress && m_wholeTileDecompress;
413  return false;
414  }
415 
418  }
419 
420  uint8_t getBandIndex(uint8_t resno, eBandOrientation orientation) const{
421  uint8_t index = 0;
422  if (resno > 0) {
423  index = (uint8_t)orientation;
424  index--;
425  }
426  return index;
427  }
428 
432  grk_buffer_2d<T>* getBandWindow(uint8_t resno,eBandOrientation orientation) const{
433  assert(resno < m_tileCompResolutions.size());
434 
435  return resno > 0 ? m_resWindows[resno]->m_bandWindowBufferDim[orientation] : m_resWindows[0]->m_resWindow;
436  }
437 
438  // top-level buffer
440  return m_resWindows.back()->m_resWindow;
441  }
442 
443  /******************************************************/
444  // decompress: unreduced/reduced image component window
445  // compress: unreduced/reduced tile component
448  /******************************************************/
449 
450  // tile component coords
451  std::vector<Resolution*> m_tileCompResolutions;
452 
453  // windowed bounds for windowed decompress, otherwise full bounds
454  std::vector<ResWindow<T>* > m_resWindows;
455 
456  // unreduced number of resolutions
458 
461 };
462 
463 }
Copyright (C) 2016-2021 Grok Image Compression Inc.
Definition: BitIO.cpp:23
grk_rect_u32 getTileCompBandWindow(uint8_t num_res, uint8_t resno, uint8_t orientation, grk_rect_u32 unreducedTileCompWindow)
Get band window in tile component coordinates for specified resolution and band orientation.
Definition: util.cpp:32
eSplitOrientation
Definition: T1Structs.h:29
@ SPLIT_H
Definition: T1Structs.h:31
@ SPLIT_L
Definition: T1Structs.h:30
@ SPLIT_NUM_ORIENTATIONS
Definition: T1Structs.h:32
eBandOrientation
Definition: T1Structs.h:36
@ BAND_ORIENT_HH
Definition: T1Structs.h:40
@ BAND_ORIENT_HL
Definition: T1Structs.h:38
@ BAND_NUM_ORIENTATIONS
Definition: T1Structs.h:41
@ BAND_ORIENT_LH
Definition: T1Structs.h:39
@ BAND_ORIENT_LL
Definition: T1Structs.h:37
grk_rectangle< uint32_t > grk_rect_u32
Definition: util.h:56
Class to manage multiple buffers needed to perform DWT transform.
Definition: TileComponentWindowBuffer.h:30
grk_buffer_2d< T > * m_resWindowTopLevel
Definition: TileComponentWindowBuffer.h:198
Resolution * m_tileCompRes
Definition: TileComponentWindowBuffer.h:192
grk_buffer_2d< T > * m_splitResWindow[SPLIT_NUM_ORIENTATIONS]
Definition: TileComponentWindowBuffer.h:196
~ResWindow()
Definition: TileComponentWindowBuffer.h:117
bool m_allocated
Definition: TileComponentWindowBuffer.h:191
std::vector< grk_rect_u32 > m_paddedTileBandWindow
Definition: TileComponentWindowBuffer.h:195
ResWindow(uint8_t numresolutions, uint8_t resno, grk_buffer_2d< T > *resWindowTopLevel, Resolution *tileCompAtRes, Resolution *tileCompAtLowerRes, grk_rect_u32 tileCompWindow, grk_rect_u32 tileCompWindowUnreduced, grk_rect_u32 tileCompUnreduced, uint32_t FILTER_WIDTH)
Definition: TileComponentWindowBuffer.h:36
uint32_t m_filterWidth
Definition: TileComponentWindowBuffer.h:199
Resolution * m_tileCompResLower
Definition: TileComponentWindowBuffer.h:193
grk_buffer_2d< T > * m_resWindow
Definition: TileComponentWindowBuffer.h:197
std::vector< grk_buffer_2d< T > * > m_bandWindowBufferDim
Definition: TileComponentWindowBuffer.h:194
bool alloc(bool clear)
Definition: TileComponentWindowBuffer.h:125
Definition: T1Structs.h:228
uint32_t numBandWindows
Definition: T1Structs.h:239
Subband band[BAND_NUM_INDICES]
Definition: T1Structs.h:237
Definition: TileComponentWindowBuffer.h:215
bool useBandWindows() const
Definition: TileComponentWindowBuffer.h:411
std::vector< Resolution * > m_tileCompResolutions
Definition: TileComponentWindowBuffer.h:451
bool useResCoordsForCodeBlock() const
Definition: TileComponentWindowBuffer.h:416
uint8_t m_numResolutions
Definition: TileComponentWindowBuffer.h:457
const grk_buffer_2d< T > * getWindow(void) const
Get tile window.
Definition: TileComponentWindowBuffer.h:369
~TileComponentWindowBuffer()
Definition: TileComponentWindowBuffer.h:276
const grk_buffer_2d< T > * getWindow(uint32_t resno) const
Get resolution window.
Definition: TileComponentWindowBuffer.h:360
grk_rect_u32 m_bounds
Definition: TileComponentWindowBuffer.h:447
grk_rect_u32 unreduced_bounds() const
Definition: TileComponentWindowBuffer.h:391
bool m_wholeTileDecompress
Definition: TileComponentWindowBuffer.h:460
const grk_buffer_2d< T > * getCodeBlockDestWindow(uint8_t resno, eBandOrientation orientation) const
Get code block destination window.
Definition: TileComponentWindowBuffer.h:322
uint8_t getBandIndex(uint8_t resno, eBandOrientation orientation) const
Definition: TileComponentWindowBuffer.h:420
uint64_t strided_area(void) const
Definition: TileComponentWindowBuffer.h:395
TileComponentWindowBuffer(bool isCompressor, bool lossless, bool wholeTileDecompress, grk_rect_u32 tileCompUnreduced, grk_rect_u32 tileCompReduced, grk_rect_u32 unreducedTileOrImageCompWindow, Resolution *tileCompResolutions, uint8_t numresolutions, uint8_t reducedNumResolutions)
Definition: TileComponentWindowBuffer.h:216
const grk_buffer_2d< T > * getWindow(uint8_t resno, eBandOrientation orientation) const
Get non-LL band window.
Definition: TileComponentWindowBuffer.h:333
grk_rect_u32 m_unreducedBounds
Definition: TileComponentWindowBuffer.h:446
bool m_compress
Definition: TileComponentWindowBuffer.h:459
const grk_rect_u32 getPaddedTileBandWindow(uint8_t resno, eBandOrientation orientation) const
Definition: TileComponentWindowBuffer.h:337
void transfer(T **buffer, bool *owns, uint32_t *stride)
Definition: TileComponentWindowBuffer.h:404
std::vector< ResWindow< T > * > m_resWindows
Definition: TileComponentWindowBuffer.h:454
void transform(uint8_t resno, eBandOrientation orientation, uint32_t &offsetx, uint32_t &offsety) const
Tranform code block offsets to either band coordinates or resolution coordinates.
Definition: TileComponentWindowBuffer.h:290
grk_rect_u32 bounds() const
Get bounds of tile component decompress: reduced tile component coordinates of window compress: unred...
Definition: TileComponentWindowBuffer.h:387
grk_buffer_2d< T > * getBandWindow(uint8_t resno, eBandOrientation orientation) const
If resno is > 0, return LL,HL,LH or HH band window, otherwise return LL resolution window.
Definition: TileComponentWindowBuffer.h:432
const grk_buffer_2d< T > * getSplitWindow(uint8_t resno, eSplitOrientation orientation) const
Definition: TileComponentWindowBuffer.h:348
bool alloc()
Definition: TileComponentWindowBuffer.h:373
void attach(T *buffer, uint32_t stride)
Definition: TileComponentWindowBuffer.h:400
grk_buffer_2d< T > * getTileBuf() const
Definition: TileComponentWindowBuffer.h:439
Definition: util.h:311
T y0
Definition: util.h:84
bool is_valid(void) const
Definition: util.h:99
grk_rectangle< T > rectceildivpow2(uint32_t power) const
Definition: util.h:133
grk_rectangle< T > intersection(const grk_rectangle< T > rhs) const
Definition: util.h:151
T height() const
Definition: util.h:186
T width() const
Definition: util.h:183
grk_rectangle< T > & grow(T boundary)
Definition: util.h:206