Skip to content

Commit 5523c0d

Browse files
author
Grok Compression
committed
TileComponentWindow: type-erasure refactor to reduce 16vs32 switching
1 parent 5b2c512 commit 5523c0d

3 files changed

Lines changed: 266 additions & 161 deletions

File tree

src/lib/core/canvas/tile/TileComponent.h

Lines changed: 25 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919

2020
#include "geometry.h"
2121
#include "PacketProgressionState.h"
22-
#include "PostDecodeFilters.h"
23-
#include "PostDecodeFiltersOJPH.h"
2422
#include "htconfig.h"
2523
#include "SparseCanvas.h"
2624
#include "TileComponentWindow.h"
@@ -236,7 +234,7 @@ struct TileComponent : public Rect32
236234
dealloc();
237235
if(use16BitDwt_)
238236
{
239-
window16_ = new TileComponentWindow<int16_t>(
237+
window_ = new TileComponentWindow<int16_t>(
240238
isCompressor_, tccp_->qmfbid_ == 1, wholeTileDecompress_,
241239
Rect32(resolutions_ + num_resolutions_ - 1), Rect32(this),
242240
Rect32(unreducedTileCompOrImageCompWindow), num_resolutions_,
@@ -262,8 +260,6 @@ struct TileComponent : public Rect32
262260
regionWindow_ = nullptr;
263261
delete window_;
264262
window_ = nullptr;
265-
delete window16_;
266-
window16_ = nullptr;
267263
}
268264

269265
/**
@@ -311,17 +307,20 @@ struct TileComponent : public Rect32
311307
}
312308

313309
/**
314-
* @brief Gets window
315-
*
316-
* @return TileComponentWindow<int32_t>*
310+
* @brief Gets typed window (static_cast from type-erased pointer)
317311
*/
312+
template<typename T>
313+
TileComponentWindow<T>* typedWindow() const
314+
{
315+
return static_cast<TileComponentWindow<T>*>(window_);
316+
}
318317
TileComponentWindow<int32_t>* getWindow() const
319318
{
320-
return window_;
319+
return typedWindow<int32_t>();
321320
}
322321
TileComponentWindow<int16_t>* getWindow16() const
323322
{
324-
return window16_;
323+
return typedWindow<int16_t>();
325324
}
326325
bool is16BitDwt() const
327326
{
@@ -331,23 +330,22 @@ struct TileComponent : public Rect32
331330
{
332331
use16BitDwt_ = use16Bit;
333332
}
334-
// Type-independent operations that dispatch to the correct window
333+
// Type-independent operations through ITileComponentWindow interface
335334
bool allocWindow()
336335
{
337-
return use16BitDwt_ ? window16_->alloc() : window_->alloc();
336+
return window_->alloc();
338337
}
339338
Rect32 windowBounds() const
340339
{
341-
return use16BitDwt_ ? window16_->bounds() : window_->bounds();
340+
return window_->bounds();
342341
}
343342
Rect32 windowUnreducedBounds() const
344343
{
345-
return use16BitDwt_ ? window16_->unreducedBounds() : window_->unreducedBounds();
344+
return window_->unreducedBounds();
346345
}
347346
const Rect32* getBandWindowPadded(uint8_t resno, t1::eBandOrientation orientation) const
348347
{
349-
return use16BitDwt_ ? window16_->getBandWindowPadded(resno, orientation)
350-
: window_->getBandWindowPadded(resno, orientation);
348+
return window_->getBandWindowPadded(resno, orientation);
351349
}
352350
/**
353351
* @brief Checks if whole tile will be decoded
@@ -368,74 +366,26 @@ struct TileComponent : public Rect32
368366
return regionWindow_;
369367
}
370368
/**
371-
* @brief Post processes code block
369+
* @brief Post processes code block via virtual dispatch on window
372370
*
373-
* @param srcData source data
371+
* @param srcData source data (always int32_t from T1 decoder)
374372
* @param block @ref DecompressBlockExec
375373
*/
376-
template<typename T>
377-
void postProcess(T* srcData, t1::DecompressBlockExec* block)
374+
void postProcessBlock(int32_t* srcData, t1::DecompressBlockExec* block)
378375
{
379-
if(block->roishift)
380-
{
381-
if(block->qmfbid == 1)
382-
postDecompressImpl<T, t1::RoiShiftFilter<T>>(srcData, block,
383-
(uint16_t)block->cblk->width());
384-
else
385-
postDecompressImpl<T, t1::RoiScaleFilter<T>>(srcData, block,
386-
(uint16_t)block->cblk->width());
387-
}
388-
else
389-
{
390-
if(block->qmfbid == 1)
391-
postDecompressImpl<T, t1::ShiftFilter<T>>(srcData, block, (uint16_t)block->cblk->width());
392-
else
393-
postDecompressImpl<T, t1::ScaleFilter<T>>(srcData, block, (uint16_t)block->cblk->width());
394-
}
376+
window_->postProcessBlock(srcData, block, regionWindow_);
395377
}
396378

397379
/**
398-
* @brief Post processes HTJ2K code block
380+
* @brief Post processes HTJ2K code block via virtual dispatch on window
399381
*
400-
* @param srcData source data
382+
* @param srcData source data (always int32_t from T1 decoder)
401383
* @param block @ref DecompressBlockExec
402384
* @param stride source data stride
403385
*/
404-
template<typename T>
405-
void postProcessHT(T* srcData, t1::DecompressBlockExec* block, uint16_t stride)
406-
{
407-
if(block->roishift)
408-
{
409-
if(block->qmfbid == 1)
410-
postDecompressImpl<T, t1::ojph::RoiShiftOJPHFilter<T>>(srcData, block, stride);
411-
else
412-
postDecompressImpl<T, t1::ojph::RoiScaleOJPHFilter<T>>(srcData, block, stride);
413-
}
414-
else
415-
{
416-
if(block->qmfbid == 1)
417-
postDecompressImpl<T, t1::ojph::ShiftOJPHFilter<T>>(srcData, block, stride);
418-
else
419-
postDecompressImpl<T, t1::ojph::ScaleOJPHFilter<T>>(srcData, block, stride);
420-
}
421-
}
422-
423-
// 16-bit narrowing post-process: T1 outputs int32_t, band buffers are int16_t
424-
void postProcess16(int32_t* srcData, t1::DecompressBlockExec* block)
425-
{
426-
if(block->roishift)
427-
postDecompressImpl16<t1::NarrowRoiShiftFilter>(srcData, block,
428-
(uint16_t)block->cblk->width());
429-
else
430-
postDecompressImpl16<t1::NarrowShiftFilter>(srcData, block, (uint16_t)block->cblk->width());
431-
}
432-
// 16-bit narrowing post-process for HTJ2K: T1 outputs int32_t, band buffers are int16_t
433-
void postProcessHT16(int32_t* srcData, t1::DecompressBlockExec* block, uint16_t stride)
386+
void postProcessBlockHT(int32_t* srcData, t1::DecompressBlockExec* block, uint16_t stride)
434387
{
435-
if(block->roishift)
436-
postDecompressImpl16<t1::ojph::NarrowRoiShiftOJPHFilter>(srcData, block, stride);
437-
else
438-
postDecompressImpl16<t1::ojph::NarrowShiftOJPHFilter>(srcData, block, stride);
388+
window_->postProcessBlockHT(srcData, block, stride, regionWindow_);
439389
}
440390

441391
/**
@@ -465,61 +415,6 @@ struct TileComponent : public Rect32
465415
PacketProgressionState nextPacketProgressionState_;
466416

467417
private:
468-
/**
469-
* @brief Implements post decompress filter
470-
*
471-
* @tparam F filter
472-
* @param srcData source data
473-
* @param block @DecompressBlockExec
474-
* @param stride source data stride
475-
*/
476-
template<typename T, typename F>
477-
void postDecompressImpl(T* srcData, t1::DecompressBlockExec* block, uint16_t stride)
478-
{
479-
auto cblk = block->cblk;
480-
bool empty = cblk->dataChunksEmpty();
481-
482-
uint32_t x = block->x;
483-
uint32_t y = block->y;
484-
window_->toRelativeCoordinates(block->resno, block->bandOrientation, x, y);
485-
auto src = Buffer2d<T, AllocatorAligned>(srcData, false, cblk->width(), stride, cblk->height());
486-
auto blockBounds = Rect32(x, y, x + cblk->width(), y + cblk->height());
487-
if(!empty)
488-
{
489-
if(regionWindow_)
490-
{
491-
src.template copyFrom<F>(src, F{block}); // Create functor with block
492-
}
493-
else
494-
{
495-
src.setRect(blockBounds);
496-
window_->postProcess<F>(src, block->resno, block->bandOrientation, block);
497-
}
498-
}
499-
if(regionWindow_)
500-
regionWindow_->write(block->resno, blockBounds, empty ? nullptr : srcData, 1,
501-
blockBounds.width());
502-
}
503-
// 16-bit narrowing variant: int32_t source → int16_t band buffers
504-
template<typename F>
505-
void postDecompressImpl16(int32_t* srcData, t1::DecompressBlockExec* block, uint16_t stride)
506-
{
507-
auto cblk = block->cblk;
508-
bool empty = cblk->dataChunksEmpty();
509-
510-
uint32_t x = block->x;
511-
uint32_t y = block->y;
512-
window16_->toRelativeCoordinates(block->resno, block->bandOrientation, x, y);
513-
auto src =
514-
Buffer2d<int32_t, AllocatorAligned>(srcData, false, cblk->width(), stride, cblk->height());
515-
auto blockBounds = Rect32(x, y, x + cblk->width(), y + cblk->height());
516-
if(!empty && !regionWindow_)
517-
{
518-
src.setRect(blockBounds);
519-
window16_->template postProcessNarrow<int32_t, AllocatorAligned, F>(
520-
src, block->resno, block->bandOrientation, block);
521-
}
522-
}
523418
/**
524419
* @brief @ISparseCanvas for region window
525420
*
@@ -536,11 +431,11 @@ struct TileComponent : public Rect32
536431
*/
537432
bool isCompressor_;
538433
/**
539-
* @brief @ref TileComponentWindow
434+
* @brief @ref ITileComponentWindow (type-erased, points to TileComponentWindow<int32_t> or
435+
* <int16_t>)
540436
*
541437
*/
542-
TileComponentWindow<int32_t>* window_;
543-
TileComponentWindow<int16_t>* window16_ = nullptr;
438+
ITileComponentWindow* window_;
544439
bool use16BitDwt_ = false;
545440
/**
546441
* @brief @ref TileComponentCodingParams

0 commit comments

Comments
 (0)