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