1 // Copyright 2015 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "JBig2_GrrdProc.h"
8
9 #include <memory>
10
11 #include "JBig2_ArithDecoder.h"
12 #include "JBig2_BitStream.h"
13 #include "JBig2_Image.h"
14
decode(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * grContext)15 CJBig2_Image* CJBig2_GRRDProc::decode(CJBig2_ArithDecoder* pArithDecoder,
16 JBig2ArithCtx* grContext) {
17 if (GRW == 0 || GRH == 0)
18 return new CJBig2_Image(GRW, GRH);
19
20 if (GRTEMPLATE == 0) {
21 if ((GRAT[0] == -1) && (GRAT[1] == -1) && (GRAT[2] == -1) &&
22 (GRAT[3] == -1) && (GRREFERENCEDX == 0) &&
23 (GRW == (FX_DWORD)GRREFERENCE->m_nWidth)) {
24 return decode_Template0_opt(pArithDecoder, grContext);
25 }
26 return decode_Template0_unopt(pArithDecoder, grContext);
27 }
28
29 if ((GRREFERENCEDX == 0) && (GRW == (FX_DWORD)GRREFERENCE->m_nWidth))
30 return decode_Template1_opt(pArithDecoder, grContext);
31 return decode_Template1_unopt(pArithDecoder, grContext);
32 }
33
decode_Template0_unopt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * grContext)34 CJBig2_Image* CJBig2_GRRDProc::decode_Template0_unopt(
35 CJBig2_ArithDecoder* pArithDecoder,
36 JBig2ArithCtx* grContext) {
37 FX_BOOL LTP, SLTP, bVal;
38 FX_DWORD CONTEXT;
39 FX_DWORD line1, line2, line3, line4, line5;
40 LTP = 0;
41 std::unique_ptr<CJBig2_Image> GRREG(new CJBig2_Image(GRW, GRH));
42 GRREG->fill(0);
43 for (FX_DWORD h = 0; h < GRH; h++) {
44 if (TPGRON) {
45 SLTP = pArithDecoder->DECODE(&grContext[0x0010]);
46 LTP = LTP ^ SLTP;
47 }
48 if (LTP == 0) {
49 line1 = GRREG->getPixel(1, h - 1);
50 line1 |= GRREG->getPixel(0, h - 1) << 1;
51 line2 = 0;
52 line3 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY - 1);
53 line3 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1)
54 << 1;
55 line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
56 line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
57 line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY)
58 << 2;
59 line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
60 line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1)
61 << 1;
62 line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY + 1)
63 << 2;
64 for (FX_DWORD w = 0; w < GRW; w++) {
65 CONTEXT = line5;
66 CONTEXT |= line4 << 3;
67 CONTEXT |= line3 << 6;
68 CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2],
69 h - GRREFERENCEDY + GRAT[3])
70 << 8;
71 CONTEXT |= line2 << 9;
72 CONTEXT |= line1 << 10;
73 CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
74 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
75 GRREG->setPixel(w, h, bVal);
76 line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x03;
77 line2 = ((line2 << 1) | bVal) & 0x01;
78 line3 = ((line3 << 1) |
79 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
80 h - GRREFERENCEDY - 1)) &
81 0x03;
82 line4 =
83 ((line4 << 1) |
84 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) &
85 0x07;
86 line5 = ((line5 << 1) |
87 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
88 h - GRREFERENCEDY + 1)) &
89 0x07;
90 }
91 } else {
92 line1 = GRREG->getPixel(1, h - 1);
93 line1 |= GRREG->getPixel(0, h - 1) << 1;
94 line2 = 0;
95 line3 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY - 1);
96 line3 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1)
97 << 1;
98 line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
99 line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
100 line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY)
101 << 2;
102 line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
103 line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1)
104 << 1;
105 line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY + 1)
106 << 2;
107 for (FX_DWORD w = 0; w < GRW; w++) {
108 bVal = GRREFERENCE->getPixel(w, h);
109 if (!(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1)) &&
110 (bVal == GRREFERENCE->getPixel(w, h - 1)) &&
111 (bVal == GRREFERENCE->getPixel(w + 1, h - 1)) &&
112 (bVal == GRREFERENCE->getPixel(w - 1, h)) &&
113 (bVal == GRREFERENCE->getPixel(w + 1, h)) &&
114 (bVal == GRREFERENCE->getPixel(w - 1, h + 1)) &&
115 (bVal == GRREFERENCE->getPixel(w, h + 1)) &&
116 (bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) {
117 CONTEXT = line5;
118 CONTEXT |= line4 << 3;
119 CONTEXT |= line3 << 6;
120 CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2],
121 h - GRREFERENCEDY + GRAT[3])
122 << 8;
123 CONTEXT |= line2 << 9;
124 CONTEXT |= line1 << 10;
125 CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
126 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
127 }
128 GRREG->setPixel(w, h, bVal);
129 line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x03;
130 line2 = ((line2 << 1) | bVal) & 0x01;
131 line3 = ((line3 << 1) |
132 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
133 h - GRREFERENCEDY - 1)) &
134 0x03;
135 line4 =
136 ((line4 << 1) |
137 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) &
138 0x07;
139 line5 = ((line5 << 1) |
140 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
141 h - GRREFERENCEDY + 1)) &
142 0x07;
143 }
144 }
145 }
146 return GRREG.release();
147 }
148
decode_Template0_opt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * grContext)149 CJBig2_Image* CJBig2_GRRDProc::decode_Template0_opt(
150 CJBig2_ArithDecoder* pArithDecoder,
151 JBig2ArithCtx* grContext) {
152 if (!GRREFERENCE->m_pData)
153 return nullptr;
154
155 FX_BOOL LTP, SLTP, bVal;
156 FX_DWORD CONTEXT;
157 FX_DWORD line1, line1_r, line2_r, line3_r;
158 uint8_t* pLine, *pLineR, cVal;
159 intptr_t nStride, nStrideR, nOffset;
160 int32_t k, nBits;
161 int32_t GRWR, GRHR;
162 int32_t GRW, GRH;
163 GRW = (int32_t)CJBig2_GRRDProc::GRW;
164 GRH = (int32_t)CJBig2_GRRDProc::GRH;
165 LTP = 0;
166 std::unique_ptr<CJBig2_Image> GRREG(new CJBig2_Image(GRW, GRH));
167 if (!GRREG->m_pData)
168 return nullptr;
169
170 pLine = GRREG->m_pData;
171 pLineR = GRREFERENCE->m_pData;
172 nStride = GRREG->m_nStride;
173 nStrideR = GRREFERENCE->m_nStride;
174 GRWR = (int32_t)GRREFERENCE->m_nWidth;
175 GRHR = (int32_t)GRREFERENCE->m_nHeight;
176 if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
177 GRREFERENCEDY = 0;
178 }
179 nOffset = -GRREFERENCEDY * nStrideR;
180 for (int32_t h = 0; h < GRH; h++) {
181 if (TPGRON) {
182 SLTP = pArithDecoder->DECODE(&grContext[0x0010]);
183 LTP = LTP ^ SLTP;
184 }
185 line1 = (h > 0) ? pLine[-nStride] << 4 : 0;
186 int32_t reference_h = h - GRREFERENCEDY;
187 FX_BOOL line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1);
188 FX_BOOL line2_r_ok = (reference_h > -1 && reference_h < GRHR);
189 FX_BOOL line3_r_ok = (reference_h > -2 && reference_h < GRHR - 1);
190 line1_r = line1_r_ok ? pLineR[nOffset - nStrideR] : 0;
191 line2_r = line2_r_ok ? pLineR[nOffset] : 0;
192 line3_r = line3_r_ok ? pLineR[nOffset + nStrideR] : 0;
193 if (LTP == 0) {
194 CONTEXT = (line1 & 0x1c00) | (line1_r & 0x01c0) |
195 ((line2_r >> 3) & 0x0038) | ((line3_r >> 6) & 0x0007);
196 for (int32_t w = 0; w < GRW; w += 8) {
197 nBits = GRW - w > 8 ? 8 : GRW - w;
198 if (h > 0)
199 line1 = (line1 << 8) |
200 (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 4 : 0);
201 if (h > GRHR + GRREFERENCEDY + 1) {
202 line1_r = 0;
203 line2_r = 0;
204 line3_r = 0;
205 } else {
206 if (line1_r_ok)
207 line1_r =
208 (line1_r << 8) |
209 (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
210 if (line2_r_ok)
211 line2_r = (line2_r << 8) |
212 (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
213 if (line3_r_ok) {
214 line3_r =
215 (line3_r << 8) |
216 (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
217 } else {
218 line3_r = 0;
219 }
220 }
221 cVal = 0;
222 for (k = 0; k < nBits; k++) {
223 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
224 cVal |= bVal << (7 - k);
225 CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) |
226 ((line1 >> (7 - k)) & 0x0400) |
227 ((line1_r >> (7 - k)) & 0x0040) |
228 ((line2_r >> (10 - k)) & 0x0008) |
229 ((line3_r >> (13 - k)) & 0x0001);
230 }
231 pLine[w >> 3] = cVal;
232 }
233 } else {
234 CONTEXT = (line1 & 0x1c00) | (line1_r & 0x01c0) |
235 ((line2_r >> 3) & 0x0038) | ((line3_r >> 6) & 0x0007);
236 for (int32_t w = 0; w < GRW; w += 8) {
237 nBits = GRW - w > 8 ? 8 : GRW - w;
238 if (h > 0)
239 line1 = (line1 << 8) |
240 (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 4 : 0);
241 if (line1_r_ok)
242 line1_r =
243 (line1_r << 8) |
244 (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
245 if (line2_r_ok)
246 line2_r = (line2_r << 8) |
247 (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
248 if (line3_r_ok) {
249 line3_r =
250 (line3_r << 8) |
251 (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
252 } else {
253 line3_r = 0;
254 }
255 cVal = 0;
256 for (k = 0; k < nBits; k++) {
257 bVal = GRREFERENCE->getPixel(w + k, h);
258 if (!(TPGRON && (bVal == GRREFERENCE->getPixel(w + k - 1, h - 1)) &&
259 (bVal == GRREFERENCE->getPixel(w + k, h - 1)) &&
260 (bVal == GRREFERENCE->getPixel(w + k + 1, h - 1)) &&
261 (bVal == GRREFERENCE->getPixel(w + k - 1, h)) &&
262 (bVal == GRREFERENCE->getPixel(w + k + 1, h)) &&
263 (bVal == GRREFERENCE->getPixel(w + k - 1, h + 1)) &&
264 (bVal == GRREFERENCE->getPixel(w + k, h + 1)) &&
265 (bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) {
266 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
267 }
268 cVal |= bVal << (7 - k);
269 CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) |
270 ((line1 >> (7 - k)) & 0x0400) |
271 ((line1_r >> (7 - k)) & 0x0040) |
272 ((line2_r >> (10 - k)) & 0x0008) |
273 ((line3_r >> (13 - k)) & 0x0001);
274 }
275 pLine[w >> 3] = cVal;
276 }
277 }
278 pLine += nStride;
279 if (h < GRHR + GRREFERENCEDY) {
280 pLineR += nStrideR;
281 }
282 }
283 return GRREG.release();
284 }
285
decode_Template1_unopt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * grContext)286 CJBig2_Image* CJBig2_GRRDProc::decode_Template1_unopt(
287 CJBig2_ArithDecoder* pArithDecoder,
288 JBig2ArithCtx* grContext) {
289 FX_BOOL LTP, SLTP, bVal;
290 FX_DWORD CONTEXT;
291 FX_DWORD line1, line2, line3, line4, line5;
292 LTP = 0;
293 std::unique_ptr<CJBig2_Image> GRREG(new CJBig2_Image(GRW, GRH));
294 GRREG->fill(0);
295 for (FX_DWORD h = 0; h < GRH; h++) {
296 if (TPGRON) {
297 SLTP = pArithDecoder->DECODE(&grContext[0x0008]);
298 LTP = LTP ^ SLTP;
299 }
300 if (LTP == 0) {
301 line1 = GRREG->getPixel(1, h - 1);
302 line1 |= GRREG->getPixel(0, h - 1) << 1;
303 line1 |= GRREG->getPixel(-1, h - 1) << 2;
304 line2 = 0;
305 line3 = GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1);
306 line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
307 line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
308 line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY)
309 << 2;
310 line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
311 line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1)
312 << 1;
313 for (FX_DWORD w = 0; w < GRW; w++) {
314 CONTEXT = line5;
315 CONTEXT |= line4 << 2;
316 CONTEXT |= line3 << 5;
317 CONTEXT |= line2 << 6;
318 CONTEXT |= line1 << 7;
319 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
320 GRREG->setPixel(w, h, bVal);
321 line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07;
322 line2 = ((line2 << 1) | bVal) & 0x01;
323 line3 = ((line3 << 1) |
324 GRREFERENCE->getPixel(w - GRREFERENCEDX + 1,
325 h - GRREFERENCEDY - 1)) &
326 0x01;
327 line4 =
328 ((line4 << 1) |
329 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) &
330 0x07;
331 line5 = ((line5 << 1) |
332 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
333 h - GRREFERENCEDY + 1)) &
334 0x03;
335 }
336 } else {
337 line1 = GRREG->getPixel(1, h - 1);
338 line1 |= GRREG->getPixel(0, h - 1) << 1;
339 line1 |= GRREG->getPixel(-1, h - 1) << 2;
340 line2 = 0;
341 line3 = GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1);
342 line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
343 line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
344 line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY)
345 << 2;
346 line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
347 line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1)
348 << 1;
349 for (FX_DWORD w = 0; w < GRW; w++) {
350 bVal = GRREFERENCE->getPixel(w, h);
351 if (!(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1)) &&
352 (bVal == GRREFERENCE->getPixel(w, h - 1)) &&
353 (bVal == GRREFERENCE->getPixel(w + 1, h - 1)) &&
354 (bVal == GRREFERENCE->getPixel(w - 1, h)) &&
355 (bVal == GRREFERENCE->getPixel(w + 1, h)) &&
356 (bVal == GRREFERENCE->getPixel(w - 1, h + 1)) &&
357 (bVal == GRREFERENCE->getPixel(w, h + 1)) &&
358 (bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) {
359 CONTEXT = line5;
360 CONTEXT |= line4 << 2;
361 CONTEXT |= line3 << 5;
362 CONTEXT |= line2 << 6;
363 CONTEXT |= line1 << 7;
364 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
365 }
366 GRREG->setPixel(w, h, bVal);
367 line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07;
368 line2 = ((line2 << 1) | bVal) & 0x01;
369 line3 = ((line3 << 1) |
370 GRREFERENCE->getPixel(w - GRREFERENCEDX + 1,
371 h - GRREFERENCEDY - 1)) &
372 0x01;
373 line4 =
374 ((line4 << 1) |
375 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) &
376 0x07;
377 line5 = ((line5 << 1) |
378 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
379 h - GRREFERENCEDY + 1)) &
380 0x03;
381 }
382 }
383 }
384 return GRREG.release();
385 }
386
decode_Template1_opt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * grContext)387 CJBig2_Image* CJBig2_GRRDProc::decode_Template1_opt(
388 CJBig2_ArithDecoder* pArithDecoder,
389 JBig2ArithCtx* grContext) {
390 if (!GRREFERENCE->m_pData)
391 return nullptr;
392
393 FX_BOOL LTP, SLTP, bVal;
394 FX_DWORD CONTEXT;
395 FX_DWORD line1, line1_r, line2_r, line3_r;
396 uint8_t* pLine, *pLineR, cVal;
397 intptr_t nStride, nStrideR, nOffset;
398 int32_t k, nBits;
399 int32_t GRWR, GRHR;
400 int32_t GRW, GRH;
401 GRW = (int32_t)CJBig2_GRRDProc::GRW;
402 GRH = (int32_t)CJBig2_GRRDProc::GRH;
403 LTP = 0;
404 std::unique_ptr<CJBig2_Image> GRREG(new CJBig2_Image(GRW, GRH));
405 if (!GRREG->m_pData)
406 return nullptr;
407
408 pLine = GRREG->m_pData;
409 pLineR = GRREFERENCE->m_pData;
410 nStride = GRREG->m_nStride;
411 nStrideR = GRREFERENCE->m_nStride;
412 GRWR = (int32_t)GRREFERENCE->m_nWidth;
413 GRHR = (int32_t)GRREFERENCE->m_nHeight;
414 if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
415 GRREFERENCEDY = 0;
416 }
417 nOffset = -GRREFERENCEDY * nStrideR;
418 for (int32_t h = 0; h < GRH; h++) {
419 if (TPGRON) {
420 SLTP = pArithDecoder->DECODE(&grContext[0x0008]);
421 LTP = LTP ^ SLTP;
422 }
423 line1 = (h > 0) ? pLine[-nStride] << 1 : 0;
424 int32_t reference_h = h - GRREFERENCEDY;
425 FX_BOOL line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1);
426 FX_BOOL line2_r_ok = (reference_h > -1 && reference_h < GRHR);
427 FX_BOOL line3_r_ok = (reference_h > -2 && reference_h < GRHR - 1);
428 line1_r = line1_r_ok ? pLineR[nOffset - nStrideR] : 0;
429 line2_r = line2_r_ok ? pLineR[nOffset] : 0;
430 line3_r = line3_r_ok ? pLineR[nOffset + nStrideR] : 0;
431 if (LTP == 0) {
432 CONTEXT = (line1 & 0x0380) | ((line1_r >> 2) & 0x0020) |
433 ((line2_r >> 4) & 0x001c) | ((line3_r >> 6) & 0x0003);
434 for (int32_t w = 0; w < GRW; w += 8) {
435 nBits = GRW - w > 8 ? 8 : GRW - w;
436 if (h > 0)
437 line1 = (line1 << 8) |
438 (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 1 : 0);
439 if (line1_r_ok)
440 line1_r =
441 (line1_r << 8) |
442 (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
443 if (line2_r_ok)
444 line2_r = (line2_r << 8) |
445 (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
446 if (line3_r_ok) {
447 line3_r =
448 (line3_r << 8) |
449 (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
450 } else {
451 line3_r = 0;
452 }
453 cVal = 0;
454 for (k = 0; k < nBits; k++) {
455 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
456 cVal |= bVal << (7 - k);
457 CONTEXT = ((CONTEXT & 0x018d) << 1) | (bVal << 6) |
458 ((line1 >> (7 - k)) & 0x0080) |
459 ((line1_r >> (9 - k)) & 0x0020) |
460 ((line2_r >> (11 - k)) & 0x0004) |
461 ((line3_r >> (13 - k)) & 0x0001);
462 }
463 pLine[w >> 3] = cVal;
464 }
465 } else {
466 CONTEXT = (line1 & 0x0380) | ((line1_r >> 2) & 0x0020) |
467 ((line2_r >> 4) & 0x001c) | ((line3_r >> 6) & 0x0003);
468 for (int32_t w = 0; w < GRW; w += 8) {
469 nBits = GRW - w > 8 ? 8 : GRW - w;
470 if (h > 0)
471 line1 = (line1 << 8) |
472 (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 1 : 0);
473 if (line1_r_ok)
474 line1_r =
475 (line1_r << 8) |
476 (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
477 if (line2_r_ok)
478 line2_r = (line2_r << 8) |
479 (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
480 if (line3_r_ok) {
481 line3_r =
482 (line3_r << 8) |
483 (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
484 } else {
485 line3_r = 0;
486 }
487 cVal = 0;
488 for (k = 0; k < nBits; k++) {
489 bVal = GRREFERENCE->getPixel(w + k, h);
490 if (!(TPGRON && (bVal == GRREFERENCE->getPixel(w + k - 1, h - 1)) &&
491 (bVal == GRREFERENCE->getPixel(w + k, h - 1)) &&
492 (bVal == GRREFERENCE->getPixel(w + k + 1, h - 1)) &&
493 (bVal == GRREFERENCE->getPixel(w + k - 1, h)) &&
494 (bVal == GRREFERENCE->getPixel(w + k + 1, h)) &&
495 (bVal == GRREFERENCE->getPixel(w + k - 1, h + 1)) &&
496 (bVal == GRREFERENCE->getPixel(w + k, h + 1)) &&
497 (bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) {
498 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
499 }
500 cVal |= bVal << (7 - k);
501 CONTEXT = ((CONTEXT & 0x018d) << 1) | (bVal << 6) |
502 ((line1 >> (7 - k)) & 0x0080) |
503 ((line1_r >> (9 - k)) & 0x0020) |
504 ((line2_r >> (11 - k)) & 0x0004) |
505 ((line3_r >> (13 - k)) & 0x0001);
506 }
507 pLine[w >> 3] = cVal;
508 }
509 }
510 pLine += nStride;
511 if (h < GRHR + GRREFERENCEDY) {
512 pLineR += nStrideR;
513 }
514 }
515 return GRREG.release();
516 }
517