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