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