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 } 625