Grok 20.3.2
BlockCoderMacros.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
20namespace grk::t1
21{
22
23// Decode Cleanup Pass
24
25#define DEC_PASS_CLN_STEP(checkFlags, partial, flags, flagsPtr, flagsStride, data, dataStride, \
26 ciorig, ci, vsc) \
27 do \
28 { \
29 if(!checkFlags || !(flags & ((T1_SIGMA_THIS | T1_PI_THIS) << (ci)))) \
30 { \
31 uint8_t v; \
32 if(!partial) \
33 { \
34 uint8_t ctxt1 = GETCTXNO_ZC(mqc, flags >> (ci)); \
35 SETCURCTX(curctx, ctxt1); \
36 DEC_SYMBOL(v, mqc, curctx, a, c, ct); \
37 if(!v) \
38 { \
39 break; \
40 } \
41 } \
42 uint8_t lu = getctxtno_sc_or_spb_index(flags, flagsPtr[-1], flagsPtr[1], ci); \
43 SETCURCTX(curctx, lut_ctxno_sc[lu]); \
44 DEC_SYMBOL(v, mqc, curctx, a, c, ct); \
45 v = v ^ lut_spb[lu]; \
46 (data)[ciorig * dataStride] = v ? -oneplushalf : oneplushalf; \
47 UPDATE_FLAGS(flags, flagsPtr, ci, v, flagsStride, vsc); \
48 } \
49 } while(0)
50
51#define DEC_PASS_CLN_IMPL(bpno, vsc, w_, h_, flagsStride) \
52 { \
53 DEC_PASS_LOCAL_VARIABLES(flagsStride) \
54 const int32_t half = one >> 1; \
55 const int32_t oneplushalf = one | half; \
56 uint8_t d = 0; \
57 uint8_t runlen = 0; \
58 bool partial = false; \
59 for(k = 0; k < (h_ & ~3u); k += 4, dataPtr += 3 * w_, flagsPtr += 2) \
60 { \
61 for(i = 0; i < w_; ++i, ++dataPtr, ++flagsPtr) \
62 { \
63 _flags = *flagsPtr; \
64 if(_flags == 0) \
65 { \
66 partial = true; \
67 SETCURCTX(curctx, T1_CTXNO_AGG); \
68 DEC_SYMBOL(d, mqc, curctx, a, c, ct); \
69 if(!d) \
70 continue; \
71 SETCURCTX(curctx, T1_CTXNO_UNI); \
72 DEC_SYMBOL(runlen, mqc, curctx, a, c, ct); \
73 DEC_SYMBOL(d, mqc, curctx, a, c, ct); \
74 runlen = (runlen << 1) | d; \
75 switch(runlen) \
76 { \
77 case 0: \
78 DEC_PASS_CLN_STEP(false, true, _flags, flagsPtr, flagsStride, dataPtr, w_, 0, 0, \
79 vsc); \
80 partial = false; \
81 /* FALLTHRU */ \
82 case 1: \
83 DEC_PASS_CLN_STEP(false, partial, _flags, flagsPtr, flagsStride, dataPtr, w_, 1, 3, \
84 false); \
85 partial = false; \
86 /* FALLTHRU */ \
87 case 2: \
88 DEC_PASS_CLN_STEP(false, partial, _flags, flagsPtr, flagsStride, dataPtr, w_, 2, 6, \
89 false); \
90 partial = false; \
91 /* FALLTHRU */ \
92 case 3: \
93 DEC_PASS_CLN_STEP(false, partial, _flags, flagsPtr, flagsStride, dataPtr, w_, 3, 9, \
94 false); \
95 break; \
96 } \
97 } \
98 else \
99 { \
100 DEC_PASS_CLN_STEP(true, false, _flags, flagsPtr, flagsStride, dataPtr, w_, 0, 0, vsc); \
101 DEC_PASS_CLN_STEP(true, false, _flags, flagsPtr, flagsStride, dataPtr, w_, 1, 3, false); \
102 DEC_PASS_CLN_STEP(true, false, _flags, flagsPtr, flagsStride, dataPtr, w_, 2, 6, false); \
103 DEC_PASS_CLN_STEP(true, false, _flags, flagsPtr, flagsStride, dataPtr, w_, 3, 9, false); \
104 } \
105 *flagsPtr = _flags & ~(T1_PI_0 | T1_PI_1 | T1_PI_2 | T1_PI_3); \
106 } \
107 } \
108 if(k < h_) \
109 { \
110 for(i = 0; i < w_; ++i, ++flagsPtr, ++dataPtr) \
111 { \
112 for(j = 0; j < h_ - k; ++j) \
113 { \
114 _flags = *flagsPtr; \
115 DEC_PASS_CLN_STEP(true, false, _flags, flagsPtr, w_ + 2U, dataPtr + j * w_, 0, j, j * 3, \
116 vsc); \
117 *flagsPtr = _flags; \
118 } \
119 *flagsPtr &= ~(T1_PI_0 | T1_PI_1 | T1_PI_2 | T1_PI_3); \
120 } \
121 } \
122 POP_MQC(); \
123 }
124
125#define DEC_PASS_SIG_STEP(flags, flagsPtr, flagsStride, data, dataStride, ciorig, ci, vsc) \
126 do \
127 { \
128 if((flags & ((T1_SIGMA_THIS | T1_PI_THIS) << (ci))) == 0U && \
129 (flags & (T1_SIGMA_NEIGHBOURS << (ci))) != 0U) \
130 { \
131 uint8_t ctxt1 = GETCTXNO_ZC(mqc, flags >> (ci)); \
132 SETCURCTX(curctx, ctxt1); \
133 uint8_t v; \
134 DEC_SYMBOL(v, mqc, curctx, a, c, ct); \
135 if(v) \
136 { \
137 uint8_t lu = getctxtno_sc_or_spb_index(flags, flagsPtr[-1], flagsPtr[1], ci); \
138 uint8_t ctxt2 = lut_ctxno_sc[lu]; \
139 uint8_t spb = lut_spb[lu]; \
140 SETCURCTX(curctx, ctxt2); \
141 DEC_SYMBOL(v, mqc, curctx, a, c, ct); \
142 v = v ^ spb; \
143 (data)[(ciorig) * dataStride] = v ? -oneplushalf : oneplushalf; \
144 UPDATE_FLAGS(flags, flagsPtr, ci, v, flagsStride, vsc); \
145 } \
146 flags |= T1_PI_THIS << (ci); \
147 } \
148 } while(0)
149
150#define DEC_PASS_SIG_IMPL(bpno, vsc, w_, h_, flagsStride) \
151 { \
152 DEC_PASS_LOCAL_VARIABLES(flagsStride) \
153 const int32_t half = one >> 1; \
154 const int32_t oneplushalf = one | half; \
155 for(k = 0; k < (h_ & ~3u); k += 4, dataPtr += 3 * w_, flagsPtr += 2) \
156 { \
157 for(i = 0; i < w_; ++i, ++dataPtr, ++flagsPtr) \
158 { \
159 _flags = *flagsPtr; \
160 if(_flags != 0) \
161 { \
162 DEC_PASS_SIG_STEP(_flags, flagsPtr, flagsStride, dataPtr, w_, 0, 0, vsc); \
163 DEC_PASS_SIG_STEP(_flags, flagsPtr, flagsStride, dataPtr, w_, 1, 3, false); \
164 DEC_PASS_SIG_STEP(_flags, flagsPtr, flagsStride, dataPtr, w_, 2, 6, false); \
165 DEC_PASS_SIG_STEP(_flags, flagsPtr, flagsStride, dataPtr, w_, 3, 9, false); \
166 *flagsPtr = _flags; \
167 } \
168 } \
169 } \
170 if(k < h_) \
171 for(i = 0; i < w_; ++i, ++dataPtr, ++flagsPtr) \
172 for(j = 0; j < h_ - k; ++j) \
173 { \
174 _flags = *flagsPtr; \
175 DEC_PASS_SIG_STEP(_flags, flagsPtr, flagsStride, dataPtr + j * w_, 0, j, 3 * j, vsc); \
176 *flagsPtr = _flags; \
177 } \
178 POP_MQC(); \
179 }
180
181// Decode Magnitude Refinement Pass
182#define DEC_PASS_REF_STEP(flags, data, dataStride, ciorig, ci) \
183 do \
184 { \
185 if((flags & ((T1_SIGMA_THIS | T1_PI_THIS) << (ci))) == (T1_SIGMA_THIS << (ci))) \
186 { \
187 uint8_t ctxno = GETCTXNO_MAG(flags >> (ci)); \
188 SETCURCTX(curctx, ctxno); \
189 uint8_t v; \
190 DEC_SYMBOL(v, mqc, curctx, a, c, ct); \
191 (data)[ciorig * dataStride] += (v ^ ((data)[ciorig * dataStride] < 0)) ? poshalf : -poshalf; \
192 flags |= T1_MU_THIS << (ci); \
193 } \
194 } while(0)
195
196#define DEC_PASS_REF_IMPL(bpno, w_, h_, flagsStride) \
197 { \
198 DEC_PASS_LOCAL_VARIABLES(flagsStride) \
199 const int32_t poshalf = one >> 1; \
200 for(k = 0; k < (h_ & ~3u); k += 4, dataPtr += 3 * w_, flagsPtr += 2) \
201 { \
202 for(i = 0; i < w_; ++i, ++dataPtr, ++flagsPtr) \
203 { \
204 _flags = *flagsPtr; \
205 if(_flags != 0) \
206 { \
207 DEC_PASS_REF_STEP(_flags, dataPtr, w_, 0, 0); \
208 DEC_PASS_REF_STEP(_flags, dataPtr, w_, 1, 3); \
209 DEC_PASS_REF_STEP(_flags, dataPtr, w_, 2, 6); \
210 DEC_PASS_REF_STEP(_flags, dataPtr, w_, 3, 9); \
211 *flagsPtr = _flags; \
212 } \
213 } \
214 } \
215 if(k < h_) \
216 for(i = 0; i < w_; ++i, ++dataPtr, ++flagsPtr) \
217 for(j = 0; j < h_ - k; ++j) \
218 { \
219 _flags = *flagsPtr; \
220 DEC_PASS_REF_STEP(_flags, dataPtr + j * w_, 0, j, j * 3); \
221 *flagsPtr = _flags; \
222 } \
223 POP_MQC(); \
224 }
225
226} // namespace grk::t1
Definition SchedulerFreebyrd.h:36