TileComponentWindow.h
Go to the documentation of this file.
#pragma once
#include "grk_includes.h"
#include <stdexcept>
#include <algorithm>
/*
Various coordinate systems are used to describe regions in the tile component buffer.
1) Canvas coordinates: JPEG 2000 global image coordinates.
2) Tile component coordinates: canvas coordinates with sub-sampling applied
3) Band coordinates: coordinates relative to a specified sub-band's origin
4) Buffer coordinates: coordinate system where all resolutions are translated
to common origin (0,0). If each code block is translated relative to the origin of the
resolution that **it belongs to**, the blocks are then all in buffer coordinate system
Note: the name of any method or variable returning non canvas coordinates is appended
with "REL", to signify relative coordinates.
*/
#include "ResWindow.h"
namespace grk
{
template<class T>
constexpr T getFilterPad(bool lossless)
{
return lossless ? 1 : 2;
}
template<typename T>
struct TileComponentWindowBase
{
TileComponentWindowBase(bool isCompressor, bool lossless, bool wholeTileDecompress,
grk_rect32 unreducedTileComp, grk_rect32 reducedTileComp,
grk_rect32 unreducedImageCompWindow, uint8_t numresolutions,
uint8_t reducedNumResolutions)
: unreducedBounds_(unreducedTileComp), bounds_(reducedTileComp), compress_(isCompressor),
wholeTileDecompress_(wholeTileDecompress)
{
assert(reducedNumResolutions > 0);
auto currentRes = unreducedTileComp;
for(uint8_t i = 0; i < numresolutions; ++i)
{
bool finalResolution = i == numresolutions - 1;
ResSimple r(currentRes, finalResolution);
resolution_.push_back(r);
if(!finalResolution)
currentRes = ResSimple::getBandWindow(1, 0, currentRes);
}
std::reverse(resolution_.begin(), resolution_.end());
// generate bounds
unreducedBounds_ = unreducedImageCompWindow.intersection(unreducedBounds_);
assert(unreducedBounds_.valid());
bounds_ = unreducedImageCompWindow.scaleDownCeilPow2(
(uint32_t)(numresolutions - reducedNumResolutions));
bounds_ = bounds_.intersection(reducedTileComp);
assert(bounds_.valid());
// fill resolutions vector
auto tileCompAtRes = resolution_[reducedNumResolutions - 1];
auto tileCompAtLowerRes =
reducedNumResolutions > 1 ? resolution_[reducedNumResolutions - 2] : ResSimple();
// create resolution buffers
auto highestResWindow = new ResWindow<T>(
numresolutions, (uint8_t)(reducedNumResolutions - 1U), nullptr, tileCompAtRes,
tileCompAtLowerRes, bounds_, unreducedBounds_, unreducedTileComp,
wholeTileDecompress ? 0 : getFilterPad<uint32_t>(lossless));
// setting top level prevents allocation of tileCompBandWindows buffers
if(!useBandWindows())
highestResWindow->disableBandWindowAllocation();
// create windows for all resolutions except highest resolution
for(uint8_t resno = 0; resno < reducedNumResolutions - 1; ++resno)
{
// resolution window == LL band window of next highest resolution
auto resWindow = ResSimple::getBandWindow((uint8_t)(numresolutions - 1 - resno), 0,
unreducedBounds_);
resWindows.push_back(new ResWindow<T>(
numresolutions, resno,
useBandWindows() ? nullptr : highestResWindow->getResWindowBufferREL(),
resolution_[resno], resno > 0 ? resolution_[resno - 1] : ResSimple(), resWindow,
unreducedBounds_, unreducedTileComp,
wholeTileDecompress ? 0 : getFilterPad<uint32_t>(lossless)));
}
resWindows.push_back(highestResWindow);
}
virtual ~TileComponentWindowBase()
{
for(auto& b : this->resWindows)
delete b;
}
grk_rect32 bounds() const
{
return bounds_;
}
grk_rect32 unreducedBounds() const
{
return unreducedBounds_;
}
bool alloc()
{
for(auto& b : resWindows)
{
if(!b->alloc(!compress_))
return false;
}
return true;
}
protected:
bool useBandWindows() const
{
return !this->wholeTileDecompress_;
}
// windowed bounds for windowed decompress, otherwise full bounds
std::vector<ResWindow<T>*> resWindows;
/******************************************************/
// decompress: unreduced/reduced image component window
// compress: unreduced/reduced tile component
grk_rect32 unreducedBounds_;
grk_rect32 bounds_;
/******************************************************/
std::vector<ResSimple> resolution_;
bool compress_;
bool wholeTileDecompress_;
};
template<typename T>
struct TileComponentWindow : public TileComponentWindowBase<T>
{
typedef grk_buf2d<T, AllocatorAligned> Buf2dAligned;
TileComponentWindow(bool isCompressor, bool lossless, bool wholeTileDecompress,
grk_rect32 unreducedTileComp, grk_rect32 reducedTileComp,
grk_rect32 unreducedImageCompWindow, uint8_t numresolutions,
uint8_t reducedNumResolutions)
: TileComponentWindowBase<T>(isCompressor, lossless, wholeTileDecompress, unreducedTileComp,
reducedTileComp, unreducedImageCompWindow, numresolutions,
reducedNumResolutions)
{}
~TileComponentWindow() = default;
void toRelativeCoordinates(uint8_t resno, eBandOrientation orientation, uint32_t& offsetx,
uint32_t& offsety) const
{
assert(resno < this->resolution_.size());
auto res = this->resolution_[resno];
auto band = res.tileBand + getBandIndex(resno, orientation);
// get offset relative to band
offsetx -= band->x0;
offsety -= band->y0;
if(useBufferCoordinatesForCodeblock() && resno > 0)
{
auto resLower = this->resolution_[resno - 1U];
if(orientation & 1)
offsetx += resLower.width();
if(orientation & 2)
offsety += resLower.height();
}
}
template<typename F>
void postProcess(Buf2dAligned& src, uint8_t resno, eBandOrientation bandOrientation,
DecompressBlockExec* block)
{
grk_buf2d<int32_t, AllocatorAligned> dst;
dst = getCodeBlockDestWindowREL(resno, bandOrientation);
dst.copyFrom<F>(src, F(block));
}
const Buf2dAligned* getBandWindowBufferPaddedREL(uint8_t resno,
eBandOrientation orientation) const
{
assert(resno < this->resolution_.size());
assert(resno > 0 || orientation == BAND_ORIENT_LL);
if(resno == 0 && (this->compress_ || this->wholeTileDecompress_))
return this->resWindows[0]->getResWindowBufferREL();
return this->resWindows[resno]->getBandWindowBufferPaddedREL(orientation);
}
const grk_buf2d_simple<int32_t>
getBandWindowBufferPaddedSimple(uint8_t resno, eBandOrientation orientation) const
{
assert(resno < this->resolution_.size());
assert(resno > 0 || orientation == BAND_ORIENT_LL);
if(resno == 0 && (this->compress_ || this->wholeTileDecompress_))
return this->resWindows[0]->getResWindowBufferSimple();
return this->resWindows[resno]->getBandWindowBufferPaddedSimple(orientation);
}
const grk_buf2d_simple<float>
getBandWindowBufferPaddedSimpleF(uint8_t resno, eBandOrientation orientation) const
{
assert(resno < this->resolution_.size());
assert(resno > 0 || orientation == BAND_ORIENT_LL);
if(resno == 0 && (this->compress_ || this->wholeTileDecompress_))
return this->resWindows[0]->getResWindowBufferSimpleF();
return this->resWindows[resno]->getBandWindowBufferPaddedSimpleF(orientation);
}
const grk_rect32* getBandWindowPadded(uint8_t resno, eBandOrientation orientation) const
{
return this->resWindows[resno]->getBandWindowPadded(orientation);
}
/*
* Get intermediate split window
*
* @param orientation 0 for upper split window, and 1 for lower split window
*/
const Buf2dAligned* getResWindowBufferSplitREL(uint8_t resno,
eSplitOrientation orientation) const
{
assert(resno > 0 && resno < this->resolution_.size());
return this->resWindows[resno]->getResWindowBufferSplitREL(orientation);
}
/*
* Get intermediate split window simple buffer
*
* @param orientation 0 for upper split window, and 1 for lower split window
*/
const grk_buf2d_simple<int32_t>
getResWindowBufferSplitSimple(uint8_t resno, eSplitOrientation orientation) const
{
return getResWindowBufferSplitREL(resno, orientation)->simple();
}
/*
* Get intermediate split window simpleF buffer
*
* @param orientation 0 for upper split window, and 1 for lower split window
*/
const grk_buf2d_simple<float>
getResWindowBufferSplitSimpleF(uint8_t resno, eSplitOrientation orientation) const
{
return getResWindowBufferSplitREL(resno, orientation)->simpleF();
}
const Buf2dAligned* getResWindowBufferREL(uint32_t resno) const
{
return this->resWindows[resno]->getResWindowBufferREL();
}
const grk_buf2d_simple<int32_t> getResWindowBufferSimple(uint32_t resno) const
{
return getResWindowBufferREL(resno)->simple();
}
const grk_buf2d_simple<float> getResWindowBufferSimpleF(uint32_t resno) const
{
return getResWindowBufferREL(resno)->simpleF();
}
uint32_t getResWindowBufferHighestStride(void) const
{
return getResWindowBufferHighestREL()->stride;
}
grk_buf2d_simple<int32_t> getResWindowBufferHighestSimple(void) const
{
return getResWindowBufferHighestREL()->simple();
}
grk_buf2d_simple<float> getResWindowBufferHighestSimpleF(void) const
{
return getResWindowBufferHighestREL()->simpleF();
}
uint64_t stridedArea(void) const
{
auto win = getResWindowBufferHighestREL();
return win->stride * win->height();
}
// set data to buf without owning it
void attach(T* buffer, uint32_t stride)
{
getResWindowBufferHighestREL()->attach(buffer, stride);
}
// transfer data to buf, and cease owning it
void transfer(T** buffer, uint32_t* stride)
{
getResWindowBufferHighestREL()->transfer(buffer, stride);
}
private:
const Buf2dAligned* getCodeBlockDestWindowREL(uint8_t resno, eBandOrientation orientation) const
{
return (useBufferCoordinatesForCodeblock())
? getResWindowBufferHighestREL()
: getBandWindowBufferPaddedREL(resno, orientation);
}
Buf2dAligned* getResWindowBufferHighestREL(void) const
{
return this->resWindows.back()->getResWindowBufferREL();
}
bool useBufferCoordinatesForCodeblock() const
{
return this->compress_ || !this->wholeTileDecompress_;
}
uint8_t getBandIndex(uint8_t resno, eBandOrientation orientation) const
{
uint8_t index = 0;
if(resno > 0)
index = (uint8_t)orientation - 1;
return index;
}
};
} // namespace grk
ResWindow.h
grk_includes.h
grk
Copyright (C) 2016-2023 Grok Image Compression Inc.
Definition ICacheable.h:20
grk::grk_read
void grk_read(const uint8_t *buffer, TYPE *value, uint32_t numBytes)
Definition BufferedStream.h:239
grk::eSplitOrientation
eSplitOrientation
Definition ResWindow.h:45
grk::getFilterPad
constexpr T getFilterPad(bool lossless)
Definition TileComponentWindow.h:47
grk::eBandOrientation
eBandOrientation
Definition ResSimple.h:23
grk::BAND_ORIENT_LL
@ BAND_ORIENT_LL
Definition ResSimple.h:24
grk::DecompressBlockExec
Definition BlockExec.h:45
grk::ResSimple
Definition ResSimple.h:43
grk::ResSimple::getBandWindow
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
grk::ResWindow
ResWindow.
Definition ResWindow.h:70
grk::TileComponentWindowBase
Definition TileComponentWindow.h:54
grk::TileComponentWindowBase::bounds
grk_rect32 bounds() const
Get bounds of tile component (canvas coordinates) decompress: reduced canvas coordinates of window co...
Definition TileComponentWindow.h:120
grk::TileComponentWindowBase::wholeTileDecompress_
bool wholeTileDecompress_
Definition TileComponentWindow.h:155
grk::TileComponentWindowBase::unreducedBounds_
grk_rect32 unreducedBounds_
Definition TileComponentWindow.h:149
grk::TileComponentWindowBase::unreducedBounds
grk_rect32 unreducedBounds() const
Definition TileComponentWindow.h:124
grk::TileComponentWindowBase::compress_
bool compress_
Definition TileComponentWindow.h:154
grk::TileComponentWindowBase::TileComponentWindowBase
TileComponentWindowBase(bool isCompressor, bool lossless, bool wholeTileDecompress, grk_rect32 unreducedTileComp, grk_rect32 reducedTileComp, grk_rect32 unreducedImageCompWindow, uint8_t numresolutions, uint8_t reducedNumResolutions)
Definition TileComponentWindow.h:55
grk::TileComponentWindowBase::bounds_
grk_rect32 bounds_
Definition TileComponentWindow.h:150
grk::TileComponentWindowBase::~TileComponentWindowBase
virtual ~TileComponentWindowBase()
Definition TileComponentWindow.h:110
grk::TileComponentWindowBase::alloc
bool alloc()
Definition TileComponentWindow.h:128
grk::TileComponentWindowBase::resWindows
std::vector< ResWindow< T > * > resWindows
Definition TileComponentWindow.h:145
grk::TileComponentWindowBase::resolution_
std::vector< ResSimple > resolution_
Definition TileComponentWindow.h:153
grk::TileComponentWindowBase::useBandWindows
bool useBandWindows() const
Definition TileComponentWindow.h:140
grk::TileComponentWindow
Definition TileComponentWindow.h:160
grk::TileComponentWindow::getBandWindowBufferPaddedREL
const Buf2dAligned * getBandWindowBufferPaddedREL(uint8_t resno, eBandOrientation orientation) const
Get padded band window buffer.
Definition TileComponentWindow.h:227
grk::TileComponentWindow::getResWindowBufferSplitSimpleF
const grk_buf2d_simple< float > getResWindowBufferSplitSimpleF(uint8_t resno, eSplitOrientation orientation) const
Definition TileComponentWindow.h:319
grk::TileComponentWindow::getResWindowBufferREL
const Buf2dAligned * getResWindowBufferREL(uint32_t resno) const
Get resolution window.
Definition TileComponentWindow.h:330
grk::TileComponentWindow::getResWindowBufferHighestREL
Buf2dAligned * getResWindowBufferHighestREL(void) const
Get highest resolution window.
Definition TileComponentWindow.h:419
grk::TileComponentWindow::getResWindowBufferHighestSimpleF
grk_buf2d_simple< float > getResWindowBufferHighestSimpleF(void) const
Get highest resolution window.
Definition TileComponentWindow.h:379
grk::TileComponentWindow::getResWindowBufferHighestSimple
grk_buf2d_simple< int32_t > getResWindowBufferHighestSimple(void) const
Get highest resolution window.
Definition TileComponentWindow.h:370
grk::TileComponentWindow::getResWindowBufferSimple
const grk_buf2d_simple< int32_t > getResWindowBufferSimple(uint32_t resno) const
Get resolution window.
Definition TileComponentWindow.h:340
grk::TileComponentWindow::getCodeBlockDestWindowREL
const Buf2dAligned * getCodeBlockDestWindowREL(uint8_t resno, eBandOrientation orientation) const
Get code block destination window.
Definition TileComponentWindow.h:408
grk::TileComponentWindow::getResWindowBufferSimpleF
const grk_buf2d_simple< float > getResWindowBufferSimpleF(uint32_t resno) const
Get resolution window.
Definition TileComponentWindow.h:350
grk::TileComponentWindow::~TileComponentWindow
~TileComponentWindow()=default
grk::TileComponentWindow::getResWindowBufferSplitREL
const Buf2dAligned * getResWindowBufferSplitREL(uint8_t resno, eSplitOrientation orientation) const
Definition TileComponentWindow.h:295
grk::TileComponentWindow::getBandWindowPadded
const grk_rect32 * getBandWindowPadded(uint8_t resno, eBandOrientation orientation) const
Get padded band window.
Definition TileComponentWindow.h:286
grk::TileComponentWindow::getBandIndex
uint8_t getBandIndex(uint8_t resno, eBandOrientation orientation) const
Definition TileComponentWindow.h:427
grk::TileComponentWindow::transfer
void transfer(T **buffer, uint32_t *stride)
Definition TileComponentWindow.h:395
grk::TileComponentWindow::toRelativeCoordinates
void toRelativeCoordinates(uint8_t resno, eBandOrientation orientation, uint32_t &offsetx, uint32_t &offsety) const
Transform code block offsets from canvas coordinates to either band coordinates (relative to sub band...
Definition TileComponentWindow.h:187
grk::TileComponentWindow::getBandWindowBufferPaddedSimple
const grk_buf2d_simple< int32_t > getBandWindowBufferPaddedSimple(uint8_t resno, eBandOrientation orientation) const
Get padded band window buffer.
Definition TileComponentWindow.h:248
grk::TileComponentWindow::postProcess
void postProcess(Buf2dAligned &src, uint8_t resno, eBandOrientation bandOrientation, DecompressBlockExec *block)
Definition TileComponentWindow.h:210
grk::TileComponentWindow::getResWindowBufferHighestStride
uint32_t getResWindowBufferHighestStride(void) const
Get highest resolution window.
Definition TileComponentWindow.h:360
grk::TileComponentWindow::getResWindowBufferSplitSimple
const grk_buf2d_simple< int32_t > getResWindowBufferSplitSimple(uint8_t resno, eSplitOrientation orientation) const
Definition TileComponentWindow.h:308
grk::TileComponentWindow::TileComponentWindow
TileComponentWindow(bool isCompressor, bool lossless, bool wholeTileDecompress, grk_rect32 unreducedTileComp, grk_rect32 reducedTileComp, grk_rect32 unreducedImageCompWindow, uint8_t numresolutions, uint8_t reducedNumResolutions)
Definition TileComponentWindow.h:162
grk::TileComponentWindow::getBandWindowBufferPaddedSimpleF
const grk_buf2d_simple< float > getBandWindowBufferPaddedSimpleF(uint8_t resno, eBandOrientation orientation) const
Get padded band window buffer.
Definition TileComponentWindow.h:268
grk::TileComponentWindow::useBufferCoordinatesForCodeblock
bool useBufferCoordinatesForCodeblock() const
Definition TileComponentWindow.h:423
grk::TileComponentWindow::stridedArea
uint64_t stridedArea(void) const
Definition TileComponentWindow.h:383
grk::TileComponentWindow::attach
void attach(T *buffer, uint32_t stride)
Definition TileComponentWindow.h:390
grk::TileComponentWindow::Buf2dAligned
grk_buf2d< T, AllocatorAligned > Buf2dAligned
Definition TileComponentWindow.h:161
grk::grk_buf2d_simple
Definition buffer.h:206
grk::grk_buf2d
Definition buffer.h:230
grk::grk_buf2d::transfer
void transfer(T **buffer, uint32_t *strd)
Definition buffer.h:327
grk::grk_buf2d::attach
void attach(T *buffer, uint32_t strd)
Definition buffer.h:293
grk::grk_buf2d::simpleF
grk_buf2d_simple< float > simpleF(void) const
Definition buffer.h:252
grk::grk_buf2d::simple
grk_buf2d_simple< T > simple(void) const
Definition buffer.h:248
grk::grk_buf2d::stride
uint32_t stride
Definition buffer.h:392
grk::grk_rect< uint32_t >
grk::grk_rect::intersection
grk_rect< T > intersection(const grk_rect< T > rhs) const
Definition geometry.h:281
grk::grk_rect::valid
bool valid(void) const
Definition geometry.h:185
grk::grk_rect::scaleDownCeilPow2
grk_rect< T > scaleDownCeilPow2(uint32_t power) const
Definition geometry.h:268