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_TrdProc.h"
8
9 #include <memory>
10
11 #include "JBig2_ArithDecoder.h"
12 #include "JBig2_ArithIntDecoder.h"
13 #include "JBig2_GrrdProc.h"
14 #include "JBig2_HuffmanDecoder.h"
15
decode_Huffman(CJBig2_BitStream * pStream,JBig2ArithCtx * grContext)16 CJBig2_Image* CJBig2_TRDProc::decode_Huffman(CJBig2_BitStream* pStream,
17 JBig2ArithCtx* grContext) {
18 int32_t STRIPT, FIRSTS;
19 FX_DWORD NINSTANCES;
20 int32_t DT, DFS, CURS;
21 int32_t SI, TI;
22 CJBig2_Image* IBI;
23 FX_DWORD WI, HI;
24 int32_t IDS;
25 FX_BOOL RI;
26 int32_t RDWI, RDHI, RDXI, RDYI;
27 CJBig2_Image* IBOI;
28 FX_DWORD WOI, HOI;
29 FX_BOOL bFirst;
30 FX_DWORD nTmp;
31 int32_t nVal, nBits;
32 std::unique_ptr<CJBig2_HuffmanDecoder> pHuffmanDecoder(
33 new CJBig2_HuffmanDecoder(pStream));
34 std::unique_ptr<CJBig2_Image> SBREG(new CJBig2_Image(SBW, SBH));
35 SBREG->fill(SBDEFPIXEL);
36 if (pHuffmanDecoder->decodeAValue(SBHUFFDT, &STRIPT) != 0)
37 return nullptr;
38
39 STRIPT *= SBSTRIPS;
40 STRIPT = -STRIPT;
41 FIRSTS = 0;
42 NINSTANCES = 0;
43 while (NINSTANCES < SBNUMINSTANCES) {
44 if (pHuffmanDecoder->decodeAValue(SBHUFFDT, &DT) != 0)
45 return nullptr;
46
47 DT *= SBSTRIPS;
48 STRIPT = STRIPT + DT;
49 bFirst = TRUE;
50 for (;;) {
51 if (bFirst) {
52 if (pHuffmanDecoder->decodeAValue(SBHUFFFS, &DFS) != 0)
53 return nullptr;
54
55 FIRSTS = FIRSTS + DFS;
56 CURS = FIRSTS;
57 bFirst = FALSE;
58 } else {
59 nVal = pHuffmanDecoder->decodeAValue(SBHUFFDS, &IDS);
60 if (nVal == JBIG2_OOB) {
61 break;
62 } else if (nVal != 0) {
63 return nullptr;
64 } else {
65 CURS = CURS + IDS + SBDSOFFSET;
66 }
67 }
68 uint8_t CURT = 0;
69 if (SBSTRIPS != 1) {
70 nTmp = 1;
71 while ((FX_DWORD)(1 << nTmp) < SBSTRIPS) {
72 nTmp++;
73 }
74 if (pStream->readNBits(nTmp, &nVal) != 0)
75 return nullptr;
76
77 CURT = nVal;
78 }
79 TI = STRIPT + CURT;
80 nVal = 0;
81 nBits = 0;
82 FX_DWORD IDI;
83 for (;;) {
84 if (pStream->read1Bit(&nTmp) != 0)
85 return nullptr;
86
87 nVal = (nVal << 1) | nTmp;
88 nBits++;
89 for (IDI = 0; IDI < SBNUMSYMS; IDI++) {
90 if ((nBits == SBSYMCODES[IDI].codelen) &&
91 (nVal == SBSYMCODES[IDI].code)) {
92 break;
93 }
94 }
95 if (IDI < SBNUMSYMS) {
96 break;
97 }
98 }
99 if (SBREFINE == 0) {
100 RI = 0;
101 } else {
102 if (pStream->read1Bit(&RI) != 0) {
103 return nullptr;
104 }
105 }
106 if (RI == 0) {
107 IBI = SBSYMS[IDI];
108 } else {
109 if ((pHuffmanDecoder->decodeAValue(SBHUFFRDW, &RDWI) != 0) ||
110 (pHuffmanDecoder->decodeAValue(SBHUFFRDH, &RDHI) != 0) ||
111 (pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDXI) != 0) ||
112 (pHuffmanDecoder->decodeAValue(SBHUFFRDY, &RDYI) != 0) ||
113 (pHuffmanDecoder->decodeAValue(SBHUFFRSIZE, &nVal) != 0)) {
114 return nullptr;
115 }
116 pStream->alignByte();
117 nTmp = pStream->getOffset();
118 IBOI = SBSYMS[IDI];
119 if (!IBOI)
120 return nullptr;
121
122 WOI = IBOI->m_nWidth;
123 HOI = IBOI->m_nHeight;
124 if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0)
125 return nullptr;
126
127 std::unique_ptr<CJBig2_GRRDProc> pGRRD(new CJBig2_GRRDProc());
128 pGRRD->GRW = WOI + RDWI;
129 pGRRD->GRH = HOI + RDHI;
130 pGRRD->GRTEMPLATE = SBRTEMPLATE;
131 pGRRD->GRREFERENCE = IBOI;
132 pGRRD->GRREFERENCEDX = (RDWI >> 2) + RDXI;
133 pGRRD->GRREFERENCEDY = (RDHI >> 2) + RDYI;
134 pGRRD->TPGRON = 0;
135 pGRRD->GRAT[0] = SBRAT[0];
136 pGRRD->GRAT[1] = SBRAT[1];
137 pGRRD->GRAT[2] = SBRAT[2];
138 pGRRD->GRAT[3] = SBRAT[3];
139
140 {
141 std::unique_ptr<CJBig2_ArithDecoder> pArithDecoder(
142 new CJBig2_ArithDecoder(pStream));
143 IBI = pGRRD->decode(pArithDecoder.get(), grContext);
144 if (!IBI)
145 return nullptr;
146 }
147
148 pStream->alignByte();
149 pStream->offset(2);
150 if ((FX_DWORD)nVal != (pStream->getOffset() - nTmp)) {
151 delete IBI;
152 return nullptr;
153 }
154 }
155 if (!IBI) {
156 continue;
157 }
158 WI = IBI->m_nWidth;
159 HI = IBI->m_nHeight;
160 if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) ||
161 (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
162 CURS = CURS + WI - 1;
163 } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT) ||
164 (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
165 CURS = CURS + HI - 1;
166 }
167 SI = CURS;
168 if (TRANSPOSED == 0) {
169 switch (REFCORNER) {
170 case JBIG2_CORNER_TOPLEFT:
171 SBREG->composeFrom(SI, TI, IBI, SBCOMBOP);
172 break;
173 case JBIG2_CORNER_TOPRIGHT:
174 SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP);
175 break;
176 case JBIG2_CORNER_BOTTOMLEFT:
177 SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP);
178 break;
179 case JBIG2_CORNER_BOTTOMRIGHT:
180 SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP);
181 break;
182 }
183 } else {
184 switch (REFCORNER) {
185 case JBIG2_CORNER_TOPLEFT:
186 SBREG->composeFrom(TI, SI, IBI, SBCOMBOP);
187 break;
188 case JBIG2_CORNER_TOPRIGHT:
189 SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP);
190 break;
191 case JBIG2_CORNER_BOTTOMLEFT:
192 SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP);
193 break;
194 case JBIG2_CORNER_BOTTOMRIGHT:
195 SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP);
196 break;
197 }
198 }
199 if (RI != 0) {
200 delete IBI;
201 }
202 if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
203 (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) {
204 CURS = CURS + WI - 1;
205 } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
206 (REFCORNER == JBIG2_CORNER_TOPRIGHT))) {
207 CURS = CURS + HI - 1;
208 }
209 NINSTANCES = NINSTANCES + 1;
210 }
211 }
212 return SBREG.release();
213 }
214
decode_Arith(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * grContext,JBig2IntDecoderState * pIDS)215 CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
216 JBig2ArithCtx* grContext,
217 JBig2IntDecoderState* pIDS) {
218 int32_t STRIPT, FIRSTS;
219 FX_DWORD NINSTANCES;
220 int32_t DT, DFS, CURS;
221 int32_t SI, TI;
222 CJBig2_Image* IBI;
223 FX_DWORD WI, HI;
224 int32_t IDS;
225 int RI;
226 int32_t RDWI, RDHI, RDXI, RDYI;
227 CJBig2_Image* IBOI;
228 FX_DWORD WOI, HOI;
229 FX_BOOL bFirst;
230 int32_t bRetained;
231 CJBig2_ArithIntDecoder* IADT, *IAFS, *IADS, *IAIT, *IARI, *IARDW, *IARDH,
232 *IARDX, *IARDY;
233 CJBig2_ArithIaidDecoder* IAID;
234 if (pIDS) {
235 IADT = pIDS->IADT;
236 IAFS = pIDS->IAFS;
237 IADS = pIDS->IADS;
238 IAIT = pIDS->IAIT;
239 IARI = pIDS->IARI;
240 IARDW = pIDS->IARDW;
241 IARDH = pIDS->IARDH;
242 IARDX = pIDS->IARDX;
243 IARDY = pIDS->IARDY;
244 IAID = pIDS->IAID;
245 bRetained = TRUE;
246 } else {
247 IADT = new CJBig2_ArithIntDecoder();
248 IAFS = new CJBig2_ArithIntDecoder();
249 IADS = new CJBig2_ArithIntDecoder();
250 IAIT = new CJBig2_ArithIntDecoder();
251 IARI = new CJBig2_ArithIntDecoder();
252 IARDW = new CJBig2_ArithIntDecoder();
253 IARDH = new CJBig2_ArithIntDecoder();
254 IARDX = new CJBig2_ArithIntDecoder();
255 IARDY = new CJBig2_ArithIntDecoder();
256 IAID = new CJBig2_ArithIaidDecoder(SBSYMCODELEN);
257 bRetained = FALSE;
258 }
259 std::unique_ptr<CJBig2_Image> SBREG(new CJBig2_Image(SBW, SBH));
260 SBREG->fill(SBDEFPIXEL);
261 IADT->decode(pArithDecoder, &STRIPT);
262 STRIPT *= SBSTRIPS;
263 STRIPT = -STRIPT;
264 FIRSTS = 0;
265 NINSTANCES = 0;
266 while (NINSTANCES < SBNUMINSTANCES) {
267 IADT->decode(pArithDecoder, &DT);
268 DT *= SBSTRIPS;
269 STRIPT = STRIPT + DT;
270 bFirst = TRUE;
271 for (;;) {
272 if (bFirst) {
273 IAFS->decode(pArithDecoder, &DFS);
274 FIRSTS = FIRSTS + DFS;
275 CURS = FIRSTS;
276 bFirst = FALSE;
277 } else {
278 if (!IADS->decode(pArithDecoder, &IDS))
279 break;
280 CURS = CURS + IDS + SBDSOFFSET;
281 }
282 if (NINSTANCES >= SBNUMINSTANCES) {
283 break;
284 }
285 int CURT = 0;
286 if (SBSTRIPS != 1)
287 IAIT->decode(pArithDecoder, &CURT);
288
289 TI = STRIPT + CURT;
290 FX_DWORD IDI;
291 IAID->decode(pArithDecoder, &IDI);
292 if (IDI >= SBNUMSYMS)
293 goto failed;
294
295 if (SBREFINE == 0)
296 RI = 0;
297 else
298 IARI->decode(pArithDecoder, &RI);
299
300 if (!SBSYMS[IDI])
301 goto failed;
302
303 if (RI == 0) {
304 IBI = SBSYMS[IDI];
305 } else {
306 IARDW->decode(pArithDecoder, &RDWI);
307 IARDH->decode(pArithDecoder, &RDHI);
308 IARDX->decode(pArithDecoder, &RDXI);
309 IARDY->decode(pArithDecoder, &RDYI);
310 IBOI = SBSYMS[IDI];
311 WOI = IBOI->m_nWidth;
312 HOI = IBOI->m_nHeight;
313 if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) {
314 goto failed;
315 }
316 std::unique_ptr<CJBig2_GRRDProc> pGRRD(new CJBig2_GRRDProc());
317 pGRRD->GRW = WOI + RDWI;
318 pGRRD->GRH = HOI + RDHI;
319 pGRRD->GRTEMPLATE = SBRTEMPLATE;
320 pGRRD->GRREFERENCE = IBOI;
321 pGRRD->GRREFERENCEDX = (RDWI >> 1) + RDXI;
322 pGRRD->GRREFERENCEDY = (RDHI >> 1) + RDYI;
323 pGRRD->TPGRON = 0;
324 pGRRD->GRAT[0] = SBRAT[0];
325 pGRRD->GRAT[1] = SBRAT[1];
326 pGRRD->GRAT[2] = SBRAT[2];
327 pGRRD->GRAT[3] = SBRAT[3];
328 IBI = pGRRD->decode(pArithDecoder, grContext);
329 if (!IBI)
330 goto failed;
331 }
332 WI = IBI->m_nWidth;
333 HI = IBI->m_nHeight;
334 if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) ||
335 (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
336 CURS = CURS + WI - 1;
337 } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT) ||
338 (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
339 CURS = CURS + HI - 1;
340 }
341 SI = CURS;
342 if (TRANSPOSED == 0) {
343 switch (REFCORNER) {
344 case JBIG2_CORNER_TOPLEFT:
345 SBREG->composeFrom(SI, TI, IBI, SBCOMBOP);
346 break;
347 case JBIG2_CORNER_TOPRIGHT:
348 SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP);
349 break;
350 case JBIG2_CORNER_BOTTOMLEFT:
351 SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP);
352 break;
353 case JBIG2_CORNER_BOTTOMRIGHT:
354 SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP);
355 break;
356 }
357 } else {
358 switch (REFCORNER) {
359 case JBIG2_CORNER_TOPLEFT:
360 SBREG->composeFrom(TI, SI, IBI, SBCOMBOP);
361 break;
362 case JBIG2_CORNER_TOPRIGHT:
363 SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP);
364 break;
365 case JBIG2_CORNER_BOTTOMLEFT:
366 SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP);
367 break;
368 case JBIG2_CORNER_BOTTOMRIGHT:
369 SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP);
370 break;
371 }
372 }
373 if (RI != 0) {
374 delete IBI;
375 }
376 if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
377 (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) {
378 CURS = CURS + WI - 1;
379 } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
380 (REFCORNER == JBIG2_CORNER_TOPRIGHT))) {
381 CURS = CURS + HI - 1;
382 }
383 NINSTANCES = NINSTANCES + 1;
384 }
385 }
386 if (bRetained == FALSE) {
387 delete IADT;
388 delete IAFS;
389 delete IADS;
390 delete IAIT;
391 delete IARI;
392 delete IARDW;
393 delete IARDH;
394 delete IARDX;
395 delete IARDY;
396 delete IAID;
397 }
398 return SBREG.release();
399 failed:
400 if (bRetained == FALSE) {
401 delete IADT;
402 delete IAFS;
403 delete IADS;
404 delete IAIT;
405 delete IARI;
406 delete IARDW;
407 delete IARDH;
408 delete IARDX;
409 delete IARDY;
410 delete IAID;
411 }
412 return nullptr;
413 }
414