Grok 20.3.2
PostDecodeFilters.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016-2026 Grok Image Compression Inc.
3 *
4 * This source code is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License, version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This source code is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Affero General Public License for more details.
12 *
13 * You should have received a copy of the GNU Affero General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18#pragma once
19
20#include <cstdint>
21#include "BlockExec.h"
22
23namespace grk::t1
24{
25template<typename T>
27{
28public:
29 RoiShiftFilter(DecompressBlockExec* block) : roiShift(block->roishift) {}
30 inline void copy(T* dest, const T* src, uint32_t len)
31 {
32 T thresh = 1 << roiShift;
33 for(uint32_t i = 0; i < len; ++i)
34 {
35 T val = src[i];
36 T mag = abs(val);
37 if(mag >= thresh)
38 {
39 mag >>= roiShift;
40 val = val < 0 ? -mag : mag;
41 }
42 dest[i] = val / 2;
43 }
44 }
45
46private:
47 uint32_t roiShift;
48};
49template<typename T>
51{
52public:
53 ShiftFilter([[maybe_unused]] DecompressBlockExec* block) {}
54 inline void copy(T* dest, const T* src, uint32_t len)
55 {
56 for(uint32_t i = 0; i < len; ++i)
57 dest[i] = src[i] / 2;
58 }
59};
60
61template<typename T>
63{
64public:
65 RoiScaleFilter(DecompressBlockExec* block) : roiShift(block->roishift), scale(block->stepsize / 2)
66 {}
67 inline void copy(T* dest, const T* src, uint32_t len)
68 {
69 T thresh = 1 << roiShift;
70 for(uint32_t i = 0; i < len; ++i)
71 {
72 T val = src[i];
73 T mag = abs(val);
74 if(mag >= thresh)
75 {
76 mag >>= roiShift;
77 val = val < 0 ? -mag : mag;
78 }
79 ((float*)dest)[i] = (float)val * scale;
80 }
81 }
82
83private:
84 uint32_t roiShift;
85 float scale;
86};
87
88template<typename T>
90{
91public:
92 ScaleFilter(DecompressBlockExec* block) : scale(block->stepsize / 2) {}
93 inline void copy(T* dest, const T* src, uint32_t len)
94 {
95 for(uint32_t i = 0; i < len; ++i)
96 ((float*)dest)[i] = (float)src[i] * scale;
97 }
98
99private:
100 float scale;
101};
102
103// Narrowing filters for 16-bit DWT path: int32_t T1 output → int16_t band buffers
105{
106public:
107 NarrowShiftFilter([[maybe_unused]] DecompressBlockExec* block) {}
108 inline void copy(int16_t* dest, const int32_t* src, uint32_t len)
109 {
110 for(uint32_t i = 0; i < len; ++i)
111 dest[i] = (int16_t)(src[i] / 2);
112 }
113};
114
116{
117public:
119 inline void copy(int16_t* dest, const int32_t* src, uint32_t len)
120 {
121 int32_t thresh = 1 << roiShift;
122 for(uint32_t i = 0; i < len; ++i)
123 {
124 int32_t val = src[i];
125 int32_t mag = abs(val);
126 if(mag >= thresh)
127 {
128 mag >>= roiShift;
129 val = val < 0 ? -mag : mag;
130 }
131 dest[i] = (int16_t)(val / 2);
132 }
133 }
134
135private:
136 uint32_t roiShift;
137};
138
139// Narrowing dequantization filter for 16-bit fixed-point 9/7 DWT path.
140// Converts Part 1 block coder int32 two's-complement output to int16 by
141// applying the quantization step size (dequantization) and clamping.
142//
143// The block coder stores coefficients with an implicit T1_NMSEDEC_FRACBITS=1
144// scaling, so the effective step is stepsize/2 — identical to ScaleFilter,
145// but the result is rounded to int16 instead of converted to float.
146//
147// For images up to 12-bit precision with typical step sizes, the dequantized
148// coefficient magnitudes are well within the int16 range (see BIBO analysis
149// in doc/16BitDWT.md and wavelet/WaveletReverse97_16.cpp).
151{
152public:
153 NarrowScaleFilter16(DecompressBlockExec* block) : scale_(block->stepsize / 2) {}
154 inline void copy(int16_t* dest, const int32_t* src, uint32_t len)
155 {
156 for(uint32_t i = 0; i < len; ++i)
157 {
158 float val = (float)src[i] * scale_;
159 // Round to nearest and clamp to int16 range
160 int32_t rounded = (int32_t)(val >= 0 ? val + 0.5f : val - 0.5f);
161 if(rounded > 32767)
162 rounded = 32767;
163 else if(rounded < -32768)
164 rounded = -32768;
165 dest[i] = (int16_t)rounded;
166 }
167 }
168
169private:
170 float scale_;
171};
172
173// Same as NarrowScaleFilter16 but with ROI shift applied first.
175{
176public:
178 : roiShift_(block->roishift), scale_(block->stepsize / 2)
179 {}
180 inline void copy(int16_t* dest, const int32_t* src, uint32_t len)
181 {
182 int32_t thresh = 1 << roiShift_;
183 for(uint32_t i = 0; i < len; ++i)
184 {
185 int32_t val = src[i];
186 int32_t mag = abs(val);
187 if(mag >= thresh)
188 {
189 mag >>= roiShift_;
190 val = val < 0 ? -mag : mag;
191 }
192 float fval = (float)val * scale_;
193 int32_t rounded = (int32_t)(fval >= 0 ? fval + 0.5f : fval - 0.5f);
194 if(rounded > 32767)
195 rounded = 32767;
196 else if(rounded < -32768)
197 rounded = -32768;
198 dest[i] = (int16_t)rounded;
199 }
200 }
201
202private:
203 uint32_t roiShift_;
204 float scale_;
205};
206
207} // namespace grk::t1
void copy(int16_t *dest, const int32_t *src, uint32_t len)
Definition PostDecodeFilters.h:180
uint32_t roiShift_
Definition PostDecodeFilters.h:203
float scale_
Definition PostDecodeFilters.h:204
NarrowRoiScaleFilter16(DecompressBlockExec *block)
Definition PostDecodeFilters.h:177
NarrowRoiShiftFilter(DecompressBlockExec *block)
Definition PostDecodeFilters.h:118
uint32_t roiShift
Definition PostDecodeFilters.h:136
void copy(int16_t *dest, const int32_t *src, uint32_t len)
Definition PostDecodeFilters.h:119
NarrowScaleFilter16(DecompressBlockExec *block)
Definition PostDecodeFilters.h:153
void copy(int16_t *dest, const int32_t *src, uint32_t len)
Definition PostDecodeFilters.h:154
float scale_
Definition PostDecodeFilters.h:170
NarrowShiftFilter(DecompressBlockExec *block)
Definition PostDecodeFilters.h:107
void copy(int16_t *dest, const int32_t *src, uint32_t len)
Definition PostDecodeFilters.h:108
void copy(T *dest, const T *src, uint32_t len)
Definition PostDecodeFilters.h:67
uint32_t roiShift
Definition PostDecodeFilters.h:84
float scale
Definition PostDecodeFilters.h:85
RoiScaleFilter(DecompressBlockExec *block)
Definition PostDecodeFilters.h:65
uint32_t roiShift
Definition PostDecodeFilters.h:47
RoiShiftFilter(DecompressBlockExec *block)
Definition PostDecodeFilters.h:29
void copy(T *dest, const T *src, uint32_t len)
Definition PostDecodeFilters.h:30
void copy(T *dest, const T *src, uint32_t len)
Definition PostDecodeFilters.h:93
ScaleFilter(DecompressBlockExec *block)
Definition PostDecodeFilters.h:92
float scale
Definition PostDecodeFilters.h:100
ShiftFilter(DecompressBlockExec *block)
Definition PostDecodeFilters.h:53
void copy(T *dest, const T *src, uint32_t len)
Definition PostDecodeFilters.h:54
Definition SchedulerFreebyrd.h:36
Definition BlockExec.h:64