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