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