OLD | NEW |
| (Empty) |
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 "core/src/fxcodec/jbig2/JBig2_SddProc.h" | |
8 | |
9 #include <memory> | |
10 #include <vector> | |
11 | |
12 #include "core/include/fxcrt/fx_basic.h" | |
13 #include "core/src/fxcodec/jbig2/JBig2_ArithIntDecoder.h" | |
14 #include "core/src/fxcodec/jbig2/JBig2_GrdProc.h" | |
15 #include "core/src/fxcodec/jbig2/JBig2_GrrdProc.h" | |
16 #include "core/src/fxcodec/jbig2/JBig2_HuffmanDecoder.h" | |
17 #include "core/src/fxcodec/jbig2/JBig2_HuffmanTable.h" | |
18 #include "core/src/fxcodec/jbig2/JBig2_HuffmanTable_Standard.h" | |
19 #include "core/src/fxcodec/jbig2/JBig2_SymbolDict.h" | |
20 #include "core/src/fxcodec/jbig2/JBig2_TrdProc.h" | |
21 | |
22 CJBig2_SymbolDict* CJBig2_SDDProc::decode_Arith( | |
23 CJBig2_ArithDecoder* pArithDecoder, | |
24 std::vector<JBig2ArithCtx>* gbContext, | |
25 std::vector<JBig2ArithCtx>* grContext) { | |
26 CJBig2_Image** SDNEWSYMS; | |
27 FX_DWORD HCHEIGHT, NSYMSDECODED; | |
28 int32_t HCDH; | |
29 FX_DWORD SYMWIDTH, TOTWIDTH; | |
30 int32_t DW; | |
31 CJBig2_Image* BS; | |
32 FX_DWORD I, J, REFAGGNINST; | |
33 FX_BOOL* EXFLAGS; | |
34 FX_DWORD EXINDEX; | |
35 FX_BOOL CUREXFLAG; | |
36 FX_DWORD EXRUNLENGTH; | |
37 FX_DWORD nTmp; | |
38 FX_DWORD SBNUMSYMS; | |
39 uint8_t SBSYMCODELEN; | |
40 int32_t RDXI, RDYI; | |
41 CJBig2_Image** SBSYMS; | |
42 std::unique_ptr<CJBig2_ArithIaidDecoder> IAID; | |
43 std::unique_ptr<CJBig2_SymbolDict> pDict; | |
44 std::unique_ptr<CJBig2_ArithIntDecoder> IADH(new CJBig2_ArithIntDecoder); | |
45 std::unique_ptr<CJBig2_ArithIntDecoder> IADW(new CJBig2_ArithIntDecoder); | |
46 std::unique_ptr<CJBig2_ArithIntDecoder> IAAI(new CJBig2_ArithIntDecoder); | |
47 std::unique_ptr<CJBig2_ArithIntDecoder> IARDX(new CJBig2_ArithIntDecoder); | |
48 std::unique_ptr<CJBig2_ArithIntDecoder> IARDY(new CJBig2_ArithIntDecoder); | |
49 std::unique_ptr<CJBig2_ArithIntDecoder> IAEX(new CJBig2_ArithIntDecoder); | |
50 std::unique_ptr<CJBig2_ArithIntDecoder> IADT(new CJBig2_ArithIntDecoder); | |
51 std::unique_ptr<CJBig2_ArithIntDecoder> IAFS(new CJBig2_ArithIntDecoder); | |
52 std::unique_ptr<CJBig2_ArithIntDecoder> IADS(new CJBig2_ArithIntDecoder); | |
53 std::unique_ptr<CJBig2_ArithIntDecoder> IAIT(new CJBig2_ArithIntDecoder); | |
54 std::unique_ptr<CJBig2_ArithIntDecoder> IARI(new CJBig2_ArithIntDecoder); | |
55 std::unique_ptr<CJBig2_ArithIntDecoder> IARDW(new CJBig2_ArithIntDecoder); | |
56 std::unique_ptr<CJBig2_ArithIntDecoder> IARDH(new CJBig2_ArithIntDecoder); | |
57 nTmp = 0; | |
58 while ((FX_DWORD)(1 << nTmp) < (SDNUMINSYMS + SDNUMNEWSYMS)) { | |
59 nTmp++; | |
60 } | |
61 IAID.reset(new CJBig2_ArithIaidDecoder((uint8_t)nTmp)); | |
62 SDNEWSYMS = FX_Alloc(CJBig2_Image*, SDNUMNEWSYMS); | |
63 FXSYS_memset(SDNEWSYMS, 0, SDNUMNEWSYMS * sizeof(CJBig2_Image*)); | |
64 | |
65 HCHEIGHT = 0; | |
66 NSYMSDECODED = 0; | |
67 while (NSYMSDECODED < SDNUMNEWSYMS) { | |
68 BS = nullptr; | |
69 IADH->decode(pArithDecoder, &HCDH); | |
70 HCHEIGHT = HCHEIGHT + HCDH; | |
71 if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > JBIG2_MAX_IMAGE_SIZE) { | |
72 goto failed; | |
73 } | |
74 SYMWIDTH = 0; | |
75 TOTWIDTH = 0; | |
76 for (;;) { | |
77 if (!IADW->decode(pArithDecoder, &DW)) | |
78 break; | |
79 | |
80 if (NSYMSDECODED >= SDNUMNEWSYMS) | |
81 goto failed; | |
82 | |
83 SYMWIDTH = SYMWIDTH + DW; | |
84 if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > JBIG2_MAX_IMAGE_SIZE) | |
85 goto failed; | |
86 | |
87 if (HCHEIGHT == 0 || SYMWIDTH == 0) { | |
88 TOTWIDTH = TOTWIDTH + SYMWIDTH; | |
89 SDNEWSYMS[NSYMSDECODED] = nullptr; | |
90 NSYMSDECODED = NSYMSDECODED + 1; | |
91 continue; | |
92 } | |
93 TOTWIDTH = TOTWIDTH + SYMWIDTH; | |
94 if (SDREFAGG == 0) { | |
95 std::unique_ptr<CJBig2_GRDProc> pGRD(new CJBig2_GRDProc()); | |
96 pGRD->MMR = 0; | |
97 pGRD->GBW = SYMWIDTH; | |
98 pGRD->GBH = HCHEIGHT; | |
99 pGRD->GBTEMPLATE = SDTEMPLATE; | |
100 pGRD->TPGDON = 0; | |
101 pGRD->USESKIP = 0; | |
102 pGRD->GBAT[0] = SDAT[0]; | |
103 pGRD->GBAT[1] = SDAT[1]; | |
104 pGRD->GBAT[2] = SDAT[2]; | |
105 pGRD->GBAT[3] = SDAT[3]; | |
106 pGRD->GBAT[4] = SDAT[4]; | |
107 pGRD->GBAT[5] = SDAT[5]; | |
108 pGRD->GBAT[6] = SDAT[6]; | |
109 pGRD->GBAT[7] = SDAT[7]; | |
110 BS = pGRD->decode_Arith(pArithDecoder, gbContext->data()); | |
111 if (!BS) { | |
112 goto failed; | |
113 } | |
114 } else { | |
115 IAAI->decode(pArithDecoder, (int*)&REFAGGNINST); | |
116 if (REFAGGNINST > 1) { | |
117 std::unique_ptr<CJBig2_TRDProc> pDecoder(new CJBig2_TRDProc()); | |
118 pDecoder->SBHUFF = SDHUFF; | |
119 pDecoder->SBREFINE = 1; | |
120 pDecoder->SBW = SYMWIDTH; | |
121 pDecoder->SBH = HCHEIGHT; | |
122 pDecoder->SBNUMINSTANCES = REFAGGNINST; | |
123 pDecoder->SBSTRIPS = 1; | |
124 pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED; | |
125 SBNUMSYMS = pDecoder->SBNUMSYMS; | |
126 nTmp = 0; | |
127 while ((FX_DWORD)(1 << nTmp) < SBNUMSYMS) { | |
128 nTmp++; | |
129 } | |
130 SBSYMCODELEN = (uint8_t)nTmp; | |
131 pDecoder->SBSYMCODELEN = SBSYMCODELEN; | |
132 SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS); | |
133 JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*)); | |
134 JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, | |
135 NSYMSDECODED * sizeof(CJBig2_Image*)); | |
136 pDecoder->SBSYMS = SBSYMS; | |
137 pDecoder->SBDEFPIXEL = 0; | |
138 pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR; | |
139 pDecoder->TRANSPOSED = 0; | |
140 pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT; | |
141 pDecoder->SBDSOFFSET = 0; | |
142 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFFS(new CJBig2_HuffmanTable( | |
143 HuffmanTable_B6, FX_ArraySize(HuffmanTable_B6), | |
144 HuffmanTable_HTOOB_B6)); | |
145 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFDS(new CJBig2_HuffmanTable( | |
146 HuffmanTable_B8, FX_ArraySize(HuffmanTable_B8), | |
147 HuffmanTable_HTOOB_B8)); | |
148 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFDT(new CJBig2_HuffmanTable( | |
149 HuffmanTable_B11, FX_ArraySize(HuffmanTable_B11), | |
150 HuffmanTable_HTOOB_B11)); | |
151 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDW( | |
152 new CJBig2_HuffmanTable(HuffmanTable_B15, | |
153 FX_ArraySize(HuffmanTable_B15), | |
154 HuffmanTable_HTOOB_B15)); | |
155 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDH( | |
156 new CJBig2_HuffmanTable(HuffmanTable_B15, | |
157 FX_ArraySize(HuffmanTable_B15), | |
158 HuffmanTable_HTOOB_B15)); | |
159 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDX( | |
160 new CJBig2_HuffmanTable(HuffmanTable_B15, | |
161 FX_ArraySize(HuffmanTable_B15), | |
162 HuffmanTable_HTOOB_B15)); | |
163 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDY( | |
164 new CJBig2_HuffmanTable(HuffmanTable_B15, | |
165 FX_ArraySize(HuffmanTable_B15), | |
166 HuffmanTable_HTOOB_B15)); | |
167 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRSIZE( | |
168 new CJBig2_HuffmanTable(HuffmanTable_B1, | |
169 FX_ArraySize(HuffmanTable_B1), | |
170 HuffmanTable_HTOOB_B1)); | |
171 pDecoder->SBHUFFFS = SBHUFFFS.get(); | |
172 pDecoder->SBHUFFDS = SBHUFFDS.get(); | |
173 pDecoder->SBHUFFDT = SBHUFFDT.get(); | |
174 pDecoder->SBHUFFRDW = SBHUFFRDW.get(); | |
175 pDecoder->SBHUFFRDH = SBHUFFRDH.get(); | |
176 pDecoder->SBHUFFRDX = SBHUFFRDX.get(); | |
177 pDecoder->SBHUFFRDY = SBHUFFRDY.get(); | |
178 pDecoder->SBHUFFRSIZE = SBHUFFRSIZE.get(); | |
179 pDecoder->SBRTEMPLATE = SDRTEMPLATE; | |
180 pDecoder->SBRAT[0] = SDRAT[0]; | |
181 pDecoder->SBRAT[1] = SDRAT[1]; | |
182 pDecoder->SBRAT[2] = SDRAT[2]; | |
183 pDecoder->SBRAT[3] = SDRAT[3]; | |
184 JBig2IntDecoderState ids; | |
185 ids.IADT = IADT.get(); | |
186 ids.IAFS = IAFS.get(); | |
187 ids.IADS = IADS.get(); | |
188 ids.IAIT = IAIT.get(); | |
189 ids.IARI = IARI.get(); | |
190 ids.IARDW = IARDW.get(); | |
191 ids.IARDH = IARDH.get(); | |
192 ids.IARDX = IARDX.get(); | |
193 ids.IARDY = IARDY.get(); | |
194 ids.IAID = IAID.get(); | |
195 BS = pDecoder->decode_Arith(pArithDecoder, grContext->data(), &ids); | |
196 if (!BS) { | |
197 FX_Free(SBSYMS); | |
198 goto failed; | |
199 } | |
200 FX_Free(SBSYMS); | |
201 } else if (REFAGGNINST == 1) { | |
202 SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED; | |
203 FX_DWORD IDI; | |
204 IAID->decode(pArithDecoder, &IDI); | |
205 IARDX->decode(pArithDecoder, &RDXI); | |
206 IARDY->decode(pArithDecoder, &RDYI); | |
207 if (IDI >= SBNUMSYMS) { | |
208 goto failed; | |
209 } | |
210 SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS); | |
211 JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*)); | |
212 JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, | |
213 NSYMSDECODED * sizeof(CJBig2_Image*)); | |
214 if (!SBSYMS[IDI]) { | |
215 FX_Free(SBSYMS); | |
216 goto failed; | |
217 } | |
218 std::unique_ptr<CJBig2_GRRDProc> pGRRD(new CJBig2_GRRDProc()); | |
219 pGRRD->GRW = SYMWIDTH; | |
220 pGRRD->GRH = HCHEIGHT; | |
221 pGRRD->GRTEMPLATE = SDRTEMPLATE; | |
222 pGRRD->GRREFERENCE = SBSYMS[IDI]; | |
223 pGRRD->GRREFERENCEDX = RDXI; | |
224 pGRRD->GRREFERENCEDY = RDYI; | |
225 pGRRD->TPGRON = 0; | |
226 pGRRD->GRAT[0] = SDRAT[0]; | |
227 pGRRD->GRAT[1] = SDRAT[1]; | |
228 pGRRD->GRAT[2] = SDRAT[2]; | |
229 pGRRD->GRAT[3] = SDRAT[3]; | |
230 BS = pGRRD->decode(pArithDecoder, grContext->data()); | |
231 if (!BS) { | |
232 FX_Free(SBSYMS); | |
233 goto failed; | |
234 } | |
235 FX_Free(SBSYMS); | |
236 } | |
237 } | |
238 SDNEWSYMS[NSYMSDECODED] = BS; | |
239 BS = nullptr; | |
240 NSYMSDECODED = NSYMSDECODED + 1; | |
241 } | |
242 } | |
243 EXINDEX = 0; | |
244 CUREXFLAG = 0; | |
245 EXFLAGS = FX_Alloc(FX_BOOL, SDNUMINSYMS + SDNUMNEWSYMS); | |
246 while (EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) { | |
247 IAEX->decode(pArithDecoder, (int*)&EXRUNLENGTH); | |
248 if (EXINDEX + EXRUNLENGTH > SDNUMINSYMS + SDNUMNEWSYMS) { | |
249 FX_Free(EXFLAGS); | |
250 goto failed; | |
251 } | |
252 if (EXRUNLENGTH != 0) { | |
253 for (I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) { | |
254 EXFLAGS[I] = CUREXFLAG; | |
255 } | |
256 } | |
257 EXINDEX = EXINDEX + EXRUNLENGTH; | |
258 CUREXFLAG = !CUREXFLAG; | |
259 } | |
260 pDict.reset(new CJBig2_SymbolDict); | |
261 I = J = 0; | |
262 for (I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) { | |
263 if (EXFLAGS[I] && J < SDNUMEXSYMS) { | |
264 if (I < SDNUMINSYMS) { | |
265 pDict->AddImage(SDINSYMS[I] ? new CJBig2_Image(*SDINSYMS[I]) : nullptr); | |
266 } else { | |
267 pDict->AddImage(SDNEWSYMS[I - SDNUMINSYMS]); | |
268 } | |
269 ++J; | |
270 } else if (!EXFLAGS[I] && I >= SDNUMINSYMS) { | |
271 delete SDNEWSYMS[I - SDNUMINSYMS]; | |
272 } | |
273 } | |
274 FX_Free(EXFLAGS); | |
275 FX_Free(SDNEWSYMS); | |
276 return pDict.release(); | |
277 failed: | |
278 for (I = 0; I < NSYMSDECODED; I++) { | |
279 if (SDNEWSYMS[I]) { | |
280 delete SDNEWSYMS[I]; | |
281 SDNEWSYMS[I] = nullptr; | |
282 } | |
283 } | |
284 FX_Free(SDNEWSYMS); | |
285 return nullptr; | |
286 } | |
287 | |
288 CJBig2_SymbolDict* CJBig2_SDDProc::decode_Huffman( | |
289 CJBig2_BitStream* pStream, | |
290 std::vector<JBig2ArithCtx>* gbContext, | |
291 std::vector<JBig2ArithCtx>* grContext, | |
292 IFX_Pause* pPause) { | |
293 CJBig2_Image** SDNEWSYMS; | |
294 FX_DWORD* SDNEWSYMWIDTHS; | |
295 FX_DWORD HCHEIGHT, NSYMSDECODED; | |
296 int32_t HCDH; | |
297 FX_DWORD SYMWIDTH, TOTWIDTH, HCFIRSTSYM; | |
298 int32_t DW; | |
299 CJBig2_Image* BS, *BHC; | |
300 FX_DWORD I, J, REFAGGNINST; | |
301 FX_BOOL* EXFLAGS; | |
302 FX_DWORD EXINDEX; | |
303 FX_BOOL CUREXFLAG; | |
304 FX_DWORD EXRUNLENGTH; | |
305 int32_t nVal, nBits; | |
306 FX_DWORD nTmp; | |
307 FX_DWORD SBNUMSYMS; | |
308 uint8_t SBSYMCODELEN; | |
309 JBig2HuffmanCode* SBSYMCODES; | |
310 FX_DWORD IDI; | |
311 int32_t RDXI, RDYI; | |
312 FX_DWORD BMSIZE; | |
313 FX_DWORD stride; | |
314 CJBig2_Image** SBSYMS; | |
315 std::unique_ptr<CJBig2_HuffmanDecoder> pHuffmanDecoder( | |
316 new CJBig2_HuffmanDecoder(pStream)); | |
317 SDNEWSYMS = FX_Alloc(CJBig2_Image*, SDNUMNEWSYMS); | |
318 FXSYS_memset(SDNEWSYMS, 0, SDNUMNEWSYMS * sizeof(CJBig2_Image*)); | |
319 SDNEWSYMWIDTHS = nullptr; | |
320 BHC = nullptr; | |
321 if (SDREFAGG == 0) { | |
322 SDNEWSYMWIDTHS = FX_Alloc(FX_DWORD, SDNUMNEWSYMS); | |
323 FXSYS_memset(SDNEWSYMWIDTHS, 0, SDNUMNEWSYMS * sizeof(FX_DWORD)); | |
324 } | |
325 std::unique_ptr<CJBig2_SymbolDict> pDict(new CJBig2_SymbolDict()); | |
326 std::unique_ptr<CJBig2_HuffmanTable> pTable; | |
327 | |
328 HCHEIGHT = 0; | |
329 NSYMSDECODED = 0; | |
330 BS = nullptr; | |
331 while (NSYMSDECODED < SDNUMNEWSYMS) { | |
332 if (pHuffmanDecoder->decodeAValue(SDHUFFDH, &HCDH) != 0) { | |
333 goto failed; | |
334 } | |
335 HCHEIGHT = HCHEIGHT + HCDH; | |
336 if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > JBIG2_MAX_IMAGE_SIZE) { | |
337 goto failed; | |
338 } | |
339 SYMWIDTH = 0; | |
340 TOTWIDTH = 0; | |
341 HCFIRSTSYM = NSYMSDECODED; | |
342 for (;;) { | |
343 nVal = pHuffmanDecoder->decodeAValue(SDHUFFDW, &DW); | |
344 if (nVal == JBIG2_OOB) { | |
345 break; | |
346 } else if (nVal != 0) { | |
347 goto failed; | |
348 } else { | |
349 if (NSYMSDECODED >= SDNUMNEWSYMS) { | |
350 goto failed; | |
351 } | |
352 SYMWIDTH = SYMWIDTH + DW; | |
353 if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > JBIG2_MAX_IMAGE_SIZE) { | |
354 goto failed; | |
355 } else if (HCHEIGHT == 0 || SYMWIDTH == 0) { | |
356 TOTWIDTH = TOTWIDTH + SYMWIDTH; | |
357 SDNEWSYMS[NSYMSDECODED] = nullptr; | |
358 NSYMSDECODED = NSYMSDECODED + 1; | |
359 continue; | |
360 } | |
361 TOTWIDTH = TOTWIDTH + SYMWIDTH; | |
362 } | |
363 if (SDREFAGG == 1) { | |
364 if (pHuffmanDecoder->decodeAValue(SDHUFFAGGINST, (int*)&REFAGGNINST) != | |
365 0) { | |
366 goto failed; | |
367 } | |
368 BS = nullptr; | |
369 if (REFAGGNINST > 1) { | |
370 std::unique_ptr<CJBig2_TRDProc> pDecoder(new CJBig2_TRDProc()); | |
371 pDecoder->SBHUFF = SDHUFF; | |
372 pDecoder->SBREFINE = 1; | |
373 pDecoder->SBW = SYMWIDTH; | |
374 pDecoder->SBH = HCHEIGHT; | |
375 pDecoder->SBNUMINSTANCES = REFAGGNINST; | |
376 pDecoder->SBSTRIPS = 1; | |
377 pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED; | |
378 SBNUMSYMS = pDecoder->SBNUMSYMS; | |
379 SBSYMCODES = FX_Alloc(JBig2HuffmanCode, SBNUMSYMS); | |
380 nTmp = 1; | |
381 while ((FX_DWORD)(1 << nTmp) < SBNUMSYMS) { | |
382 nTmp++; | |
383 } | |
384 for (I = 0; I < SBNUMSYMS; I++) { | |
385 SBSYMCODES[I].codelen = nTmp; | |
386 SBSYMCODES[I].code = I; | |
387 } | |
388 pDecoder->SBSYMCODES = SBSYMCODES; | |
389 SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS); | |
390 JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*)); | |
391 JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, | |
392 NSYMSDECODED * sizeof(CJBig2_Image*)); | |
393 pDecoder->SBSYMS = SBSYMS; | |
394 pDecoder->SBDEFPIXEL = 0; | |
395 pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR; | |
396 pDecoder->TRANSPOSED = 0; | |
397 pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT; | |
398 pDecoder->SBDSOFFSET = 0; | |
399 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFFS(new CJBig2_HuffmanTable( | |
400 HuffmanTable_B6, FX_ArraySize(HuffmanTable_B6), | |
401 HuffmanTable_HTOOB_B6)); | |
402 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFDS(new CJBig2_HuffmanTable( | |
403 HuffmanTable_B8, FX_ArraySize(HuffmanTable_B8), | |
404 HuffmanTable_HTOOB_B8)); | |
405 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFDT(new CJBig2_HuffmanTable( | |
406 HuffmanTable_B11, FX_ArraySize(HuffmanTable_B11), | |
407 HuffmanTable_HTOOB_B11)); | |
408 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDW( | |
409 new CJBig2_HuffmanTable(HuffmanTable_B15, | |
410 FX_ArraySize(HuffmanTable_B15), | |
411 HuffmanTable_HTOOB_B15)); | |
412 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDH( | |
413 new CJBig2_HuffmanTable(HuffmanTable_B15, | |
414 FX_ArraySize(HuffmanTable_B15), | |
415 HuffmanTable_HTOOB_B15)); | |
416 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDX( | |
417 new CJBig2_HuffmanTable(HuffmanTable_B15, | |
418 FX_ArraySize(HuffmanTable_B15), | |
419 HuffmanTable_HTOOB_B15)); | |
420 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDY( | |
421 new CJBig2_HuffmanTable(HuffmanTable_B15, | |
422 FX_ArraySize(HuffmanTable_B15), | |
423 HuffmanTable_HTOOB_B15)); | |
424 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRSIZE( | |
425 new CJBig2_HuffmanTable(HuffmanTable_B1, | |
426 FX_ArraySize(HuffmanTable_B1), | |
427 HuffmanTable_HTOOB_B1)); | |
428 pDecoder->SBHUFFFS = SBHUFFFS.get(); | |
429 pDecoder->SBHUFFDS = SBHUFFDS.get(); | |
430 pDecoder->SBHUFFDT = SBHUFFDT.get(); | |
431 pDecoder->SBHUFFRDW = SBHUFFRDW.get(); | |
432 pDecoder->SBHUFFRDH = SBHUFFRDH.get(); | |
433 pDecoder->SBHUFFRDX = SBHUFFRDX.get(); | |
434 pDecoder->SBHUFFRDY = SBHUFFRDY.get(); | |
435 pDecoder->SBHUFFRSIZE = SBHUFFRSIZE.get(); | |
436 pDecoder->SBRTEMPLATE = SDRTEMPLATE; | |
437 pDecoder->SBRAT[0] = SDRAT[0]; | |
438 pDecoder->SBRAT[1] = SDRAT[1]; | |
439 pDecoder->SBRAT[2] = SDRAT[2]; | |
440 pDecoder->SBRAT[3] = SDRAT[3]; | |
441 BS = pDecoder->decode_Huffman(pStream, grContext->data()); | |
442 if (!BS) { | |
443 FX_Free(SBSYMCODES); | |
444 FX_Free(SBSYMS); | |
445 goto failed; | |
446 } | |
447 FX_Free(SBSYMCODES); | |
448 FX_Free(SBSYMS); | |
449 } else if (REFAGGNINST == 1) { | |
450 SBNUMSYMS = SDNUMINSYMS + SDNUMNEWSYMS; | |
451 nTmp = 1; | |
452 while ((FX_DWORD)(1 << nTmp) < SBNUMSYMS) { | |
453 nTmp++; | |
454 } | |
455 SBSYMCODELEN = (uint8_t)nTmp; | |
456 SBSYMCODES = FX_Alloc(JBig2HuffmanCode, SBNUMSYMS); | |
457 for (I = 0; I < SBNUMSYMS; I++) { | |
458 SBSYMCODES[I].codelen = SBSYMCODELEN; | |
459 SBSYMCODES[I].code = I; | |
460 } | |
461 nVal = 0; | |
462 nBits = 0; | |
463 for (;;) { | |
464 if (pStream->read1Bit(&nTmp) != 0) { | |
465 FX_Free(SBSYMCODES); | |
466 goto failed; | |
467 } | |
468 nVal = (nVal << 1) | nTmp; | |
469 for (IDI = 0; IDI < SBNUMSYMS; IDI++) { | |
470 if ((nVal == SBSYMCODES[IDI].code) && | |
471 (nBits == SBSYMCODES[IDI].codelen)) { | |
472 break; | |
473 } | |
474 } | |
475 if (IDI < SBNUMSYMS) { | |
476 break; | |
477 } | |
478 } | |
479 FX_Free(SBSYMCODES); | |
480 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDX( | |
481 new CJBig2_HuffmanTable(HuffmanTable_B15, | |
482 FX_ArraySize(HuffmanTable_B15), | |
483 HuffmanTable_HTOOB_B15)); | |
484 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRSIZE( | |
485 new CJBig2_HuffmanTable(HuffmanTable_B1, | |
486 FX_ArraySize(HuffmanTable_B1), | |
487 HuffmanTable_HTOOB_B1)); | |
488 if ((pHuffmanDecoder->decodeAValue(SBHUFFRDX.get(), &RDXI) != 0) || | |
489 (pHuffmanDecoder->decodeAValue(SBHUFFRDX.get(), &RDYI) != 0) || | |
490 (pHuffmanDecoder->decodeAValue(SBHUFFRSIZE.get(), &nVal) != 0)) { | |
491 goto failed; | |
492 } | |
493 pStream->alignByte(); | |
494 nTmp = pStream->getOffset(); | |
495 SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS); | |
496 JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*)); | |
497 JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, | |
498 NSYMSDECODED * sizeof(CJBig2_Image*)); | |
499 std::unique_ptr<CJBig2_GRRDProc> pGRRD(new CJBig2_GRRDProc()); | |
500 pGRRD->GRW = SYMWIDTH; | |
501 pGRRD->GRH = HCHEIGHT; | |
502 pGRRD->GRTEMPLATE = SDRTEMPLATE; | |
503 pGRRD->GRREFERENCE = SBSYMS[IDI]; | |
504 pGRRD->GRREFERENCEDX = RDXI; | |
505 pGRRD->GRREFERENCEDY = RDYI; | |
506 pGRRD->TPGRON = 0; | |
507 pGRRD->GRAT[0] = SDRAT[0]; | |
508 pGRRD->GRAT[1] = SDRAT[1]; | |
509 pGRRD->GRAT[2] = SDRAT[2]; | |
510 pGRRD->GRAT[3] = SDRAT[3]; | |
511 std::unique_ptr<CJBig2_ArithDecoder> pArithDecoder( | |
512 new CJBig2_ArithDecoder(pStream)); | |
513 BS = pGRRD->decode(pArithDecoder.get(), grContext->data()); | |
514 if (!BS) { | |
515 FX_Free(SBSYMS); | |
516 goto failed; | |
517 } | |
518 pStream->alignByte(); | |
519 pStream->offset(2); | |
520 if ((FX_DWORD)nVal != (pStream->getOffset() - nTmp)) { | |
521 delete BS; | |
522 FX_Free(SBSYMS); | |
523 goto failed; | |
524 } | |
525 FX_Free(SBSYMS); | |
526 } | |
527 SDNEWSYMS[NSYMSDECODED] = BS; | |
528 } | |
529 if (SDREFAGG == 0) { | |
530 SDNEWSYMWIDTHS[NSYMSDECODED] = SYMWIDTH; | |
531 } | |
532 NSYMSDECODED = NSYMSDECODED + 1; | |
533 } | |
534 if (SDREFAGG == 0) { | |
535 if (pHuffmanDecoder->decodeAValue(SDHUFFBMSIZE, (int32_t*)&BMSIZE) != 0) { | |
536 goto failed; | |
537 } | |
538 pStream->alignByte(); | |
539 if (BMSIZE == 0) { | |
540 stride = (TOTWIDTH + 7) >> 3; | |
541 if (pStream->getByteLeft() >= stride * HCHEIGHT) { | |
542 BHC = new CJBig2_Image(TOTWIDTH, HCHEIGHT); | |
543 for (I = 0; I < HCHEIGHT; I++) { | |
544 JBIG2_memcpy(BHC->m_pData + I * BHC->m_nStride, | |
545 pStream->getPointer(), stride); | |
546 pStream->offset(stride); | |
547 } | |
548 } else { | |
549 goto failed; | |
550 } | |
551 } else { | |
552 std::unique_ptr<CJBig2_GRDProc> pGRD(new CJBig2_GRDProc()); | |
553 pGRD->MMR = 1; | |
554 pGRD->GBW = TOTWIDTH; | |
555 pGRD->GBH = HCHEIGHT; | |
556 FXCODEC_STATUS status = pGRD->Start_decode_MMR(&BHC, pStream, nullptr); | |
557 while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) { | |
558 pGRD->Continue_decode(pPause); | |
559 } | |
560 pStream->alignByte(); | |
561 } | |
562 nTmp = 0; | |
563 if (!BHC) { | |
564 continue; | |
565 } | |
566 for (I = HCFIRSTSYM; I < NSYMSDECODED; I++) { | |
567 SDNEWSYMS[I] = BHC->subImage(nTmp, 0, SDNEWSYMWIDTHS[I], HCHEIGHT); | |
568 nTmp += SDNEWSYMWIDTHS[I]; | |
569 } | |
570 delete BHC; | |
571 BHC = nullptr; | |
572 } | |
573 } | |
574 EXINDEX = 0; | |
575 CUREXFLAG = 0; | |
576 pTable.reset(new CJBig2_HuffmanTable( | |
577 HuffmanTable_B1, FX_ArraySize(HuffmanTable_B1), HuffmanTable_HTOOB_B1)); | |
578 EXFLAGS = FX_Alloc(FX_BOOL, SDNUMINSYMS + SDNUMNEWSYMS); | |
579 while (EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) { | |
580 if (pHuffmanDecoder->decodeAValue(pTable.get(), (int*)&EXRUNLENGTH) != 0) { | |
581 FX_Free(EXFLAGS); | |
582 goto failed; | |
583 } | |
584 if (EXINDEX + EXRUNLENGTH > SDNUMINSYMS + SDNUMNEWSYMS) { | |
585 FX_Free(EXFLAGS); | |
586 goto failed; | |
587 } | |
588 if (EXRUNLENGTH != 0) { | |
589 for (I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) { | |
590 EXFLAGS[I] = CUREXFLAG; | |
591 } | |
592 } | |
593 EXINDEX = EXINDEX + EXRUNLENGTH; | |
594 CUREXFLAG = !CUREXFLAG; | |
595 } | |
596 I = J = 0; | |
597 for (I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) { | |
598 if (EXFLAGS[I] && J < SDNUMEXSYMS) { | |
599 if (I < SDNUMINSYMS) { | |
600 pDict->AddImage(SDINSYMS[I] ? new CJBig2_Image(*SDINSYMS[I]) : nullptr); | |
601 } else { | |
602 pDict->AddImage(SDNEWSYMS[I - SDNUMINSYMS]); | |
603 } | |
604 ++J; | |
605 } else if (!EXFLAGS[I] && I >= SDNUMINSYMS) { | |
606 delete SDNEWSYMS[I - SDNUMINSYMS]; | |
607 } | |
608 } | |
609 FX_Free(EXFLAGS); | |
610 FX_Free(SDNEWSYMS); | |
611 if (SDREFAGG == 0) { | |
612 FX_Free(SDNEWSYMWIDTHS); | |
613 } | |
614 return pDict.release(); | |
615 failed: | |
616 for (I = 0; I < NSYMSDECODED; I++) { | |
617 delete SDNEWSYMS[I]; | |
618 } | |
619 FX_Free(SDNEWSYMS); | |
620 if (SDREFAGG == 0) { | |
621 FX_Free(SDNEWSYMWIDTHS); | |
622 } | |
623 return nullptr; | |
624 } | |
OLD | NEW |