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