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_TrdProc.h" 8 9#include <memory> 10 11#include "JBig2_ArithDecoder.h" 12#include "JBig2_ArithIntDecoder.h" 13#include "JBig2_GrrdProc.h" 14#include "JBig2_HuffmanDecoder.h" 15 16CJBig2_Image* CJBig2_TRDProc::decode_Huffman(CJBig2_BitStream* pStream, 17 JBig2ArithCtx* grContext) { 18 int32_t STRIPT, FIRSTS; 19 FX_DWORD NINSTANCES; 20 int32_t DT, DFS, CURS; 21 int32_t SI, TI; 22 CJBig2_Image* IBI; 23 FX_DWORD WI, HI; 24 int32_t IDS; 25 FX_BOOL RI; 26 int32_t RDWI, RDHI, RDXI, RDYI; 27 CJBig2_Image* IBOI; 28 FX_DWORD WOI, HOI; 29 FX_BOOL bFirst; 30 FX_DWORD nTmp; 31 int32_t nVal, nBits; 32 std::unique_ptr<CJBig2_HuffmanDecoder> pHuffmanDecoder( 33 new CJBig2_HuffmanDecoder(pStream)); 34 std::unique_ptr<CJBig2_Image> SBREG(new CJBig2_Image(SBW, SBH)); 35 SBREG->fill(SBDEFPIXEL); 36 if (pHuffmanDecoder->decodeAValue(SBHUFFDT, &STRIPT) != 0) 37 return nullptr; 38 39 STRIPT *= SBSTRIPS; 40 STRIPT = -STRIPT; 41 FIRSTS = 0; 42 NINSTANCES = 0; 43 while (NINSTANCES < SBNUMINSTANCES) { 44 if (pHuffmanDecoder->decodeAValue(SBHUFFDT, &DT) != 0) 45 return nullptr; 46 47 DT *= SBSTRIPS; 48 STRIPT = STRIPT + DT; 49 bFirst = TRUE; 50 for (;;) { 51 if (bFirst) { 52 if (pHuffmanDecoder->decodeAValue(SBHUFFFS, &DFS) != 0) 53 return nullptr; 54 55 FIRSTS = FIRSTS + DFS; 56 CURS = FIRSTS; 57 bFirst = FALSE; 58 } else { 59 nVal = pHuffmanDecoder->decodeAValue(SBHUFFDS, &IDS); 60 if (nVal == JBIG2_OOB) { 61 break; 62 } else if (nVal != 0) { 63 return nullptr; 64 } else { 65 CURS = CURS + IDS + SBDSOFFSET; 66 } 67 } 68 uint8_t CURT = 0; 69 if (SBSTRIPS != 1) { 70 nTmp = 1; 71 while ((FX_DWORD)(1 << nTmp) < SBSTRIPS) { 72 nTmp++; 73 } 74 if (pStream->readNBits(nTmp, &nVal) != 0) 75 return nullptr; 76 77 CURT = nVal; 78 } 79 TI = STRIPT + CURT; 80 nVal = 0; 81 nBits = 0; 82 FX_DWORD IDI; 83 for (;;) { 84 if (pStream->read1Bit(&nTmp) != 0) 85 return nullptr; 86 87 nVal = (nVal << 1) | nTmp; 88 nBits++; 89 for (IDI = 0; IDI < SBNUMSYMS; IDI++) { 90 if ((nBits == SBSYMCODES[IDI].codelen) && 91 (nVal == SBSYMCODES[IDI].code)) { 92 break; 93 } 94 } 95 if (IDI < SBNUMSYMS) { 96 break; 97 } 98 } 99 if (SBREFINE == 0) { 100 RI = 0; 101 } else { 102 if (pStream->read1Bit(&RI) != 0) { 103 return nullptr; 104 } 105 } 106 if (RI == 0) { 107 IBI = SBSYMS[IDI]; 108 } else { 109 if ((pHuffmanDecoder->decodeAValue(SBHUFFRDW, &RDWI) != 0) || 110 (pHuffmanDecoder->decodeAValue(SBHUFFRDH, &RDHI) != 0) || 111 (pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDXI) != 0) || 112 (pHuffmanDecoder->decodeAValue(SBHUFFRDY, &RDYI) != 0) || 113 (pHuffmanDecoder->decodeAValue(SBHUFFRSIZE, &nVal) != 0)) { 114 return nullptr; 115 } 116 pStream->alignByte(); 117 nTmp = pStream->getOffset(); 118 IBOI = SBSYMS[IDI]; 119 if (!IBOI) 120 return nullptr; 121 122 WOI = IBOI->m_nWidth; 123 HOI = IBOI->m_nHeight; 124 if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) 125 return nullptr; 126 127 std::unique_ptr<CJBig2_GRRDProc> pGRRD(new CJBig2_GRRDProc()); 128 pGRRD->GRW = WOI + RDWI; 129 pGRRD->GRH = HOI + RDHI; 130 pGRRD->GRTEMPLATE = SBRTEMPLATE; 131 pGRRD->GRREFERENCE = IBOI; 132 pGRRD->GRREFERENCEDX = (RDWI >> 2) + RDXI; 133 pGRRD->GRREFERENCEDY = (RDHI >> 2) + RDYI; 134 pGRRD->TPGRON = 0; 135 pGRRD->GRAT[0] = SBRAT[0]; 136 pGRRD->GRAT[1] = SBRAT[1]; 137 pGRRD->GRAT[2] = SBRAT[2]; 138 pGRRD->GRAT[3] = SBRAT[3]; 139 140 { 141 std::unique_ptr<CJBig2_ArithDecoder> pArithDecoder( 142 new CJBig2_ArithDecoder(pStream)); 143 IBI = pGRRD->decode(pArithDecoder.get(), grContext); 144 if (!IBI) 145 return nullptr; 146 } 147 148 pStream->alignByte(); 149 pStream->offset(2); 150 if ((FX_DWORD)nVal != (pStream->getOffset() - nTmp)) { 151 delete IBI; 152 return nullptr; 153 } 154 } 155 if (!IBI) { 156 continue; 157 } 158 WI = IBI->m_nWidth; 159 HI = IBI->m_nHeight; 160 if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) || 161 (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) { 162 CURS = CURS + WI - 1; 163 } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT) || 164 (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) { 165 CURS = CURS + HI - 1; 166 } 167 SI = CURS; 168 if (TRANSPOSED == 0) { 169 switch (REFCORNER) { 170 case JBIG2_CORNER_TOPLEFT: 171 SBREG->composeFrom(SI, TI, IBI, SBCOMBOP); 172 break; 173 case JBIG2_CORNER_TOPRIGHT: 174 SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP); 175 break; 176 case JBIG2_CORNER_BOTTOMLEFT: 177 SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP); 178 break; 179 case JBIG2_CORNER_BOTTOMRIGHT: 180 SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP); 181 break; 182 } 183 } else { 184 switch (REFCORNER) { 185 case JBIG2_CORNER_TOPLEFT: 186 SBREG->composeFrom(TI, SI, IBI, SBCOMBOP); 187 break; 188 case JBIG2_CORNER_TOPRIGHT: 189 SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP); 190 break; 191 case JBIG2_CORNER_BOTTOMLEFT: 192 SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP); 193 break; 194 case JBIG2_CORNER_BOTTOMRIGHT: 195 SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP); 196 break; 197 } 198 } 199 if (RI != 0) { 200 delete IBI; 201 } 202 if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) || 203 (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) { 204 CURS = CURS + WI - 1; 205 } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) || 206 (REFCORNER == JBIG2_CORNER_TOPRIGHT))) { 207 CURS = CURS + HI - 1; 208 } 209 NINSTANCES = NINSTANCES + 1; 210 } 211 } 212 return SBREG.release(); 213} 214 215CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder, 216 JBig2ArithCtx* grContext, 217 JBig2IntDecoderState* pIDS) { 218 int32_t STRIPT, FIRSTS; 219 FX_DWORD NINSTANCES; 220 int32_t DT, DFS, CURS; 221 int32_t SI, TI; 222 CJBig2_Image* IBI; 223 FX_DWORD WI, HI; 224 int32_t IDS; 225 int RI; 226 int32_t RDWI, RDHI, RDXI, RDYI; 227 CJBig2_Image* IBOI; 228 FX_DWORD WOI, HOI; 229 FX_BOOL bFirst; 230 int32_t bRetained; 231 CJBig2_ArithIntDecoder* IADT, *IAFS, *IADS, *IAIT, *IARI, *IARDW, *IARDH, 232 *IARDX, *IARDY; 233 CJBig2_ArithIaidDecoder* IAID; 234 if (pIDS) { 235 IADT = pIDS->IADT; 236 IAFS = pIDS->IAFS; 237 IADS = pIDS->IADS; 238 IAIT = pIDS->IAIT; 239 IARI = pIDS->IARI; 240 IARDW = pIDS->IARDW; 241 IARDH = pIDS->IARDH; 242 IARDX = pIDS->IARDX; 243 IARDY = pIDS->IARDY; 244 IAID = pIDS->IAID; 245 bRetained = TRUE; 246 } else { 247 IADT = new CJBig2_ArithIntDecoder(); 248 IAFS = new CJBig2_ArithIntDecoder(); 249 IADS = new CJBig2_ArithIntDecoder(); 250 IAIT = new CJBig2_ArithIntDecoder(); 251 IARI = new CJBig2_ArithIntDecoder(); 252 IARDW = new CJBig2_ArithIntDecoder(); 253 IARDH = new CJBig2_ArithIntDecoder(); 254 IARDX = new CJBig2_ArithIntDecoder(); 255 IARDY = new CJBig2_ArithIntDecoder(); 256 IAID = new CJBig2_ArithIaidDecoder(SBSYMCODELEN); 257 bRetained = FALSE; 258 } 259 std::unique_ptr<CJBig2_Image> SBREG(new CJBig2_Image(SBW, SBH)); 260 SBREG->fill(SBDEFPIXEL); 261 IADT->decode(pArithDecoder, &STRIPT); 262 STRIPT *= SBSTRIPS; 263 STRIPT = -STRIPT; 264 FIRSTS = 0; 265 NINSTANCES = 0; 266 while (NINSTANCES < SBNUMINSTANCES) { 267 IADT->decode(pArithDecoder, &DT); 268 DT *= SBSTRIPS; 269 STRIPT = STRIPT + DT; 270 bFirst = TRUE; 271 for (;;) { 272 if (bFirst) { 273 IAFS->decode(pArithDecoder, &DFS); 274 FIRSTS = FIRSTS + DFS; 275 CURS = FIRSTS; 276 bFirst = FALSE; 277 } else { 278 if (!IADS->decode(pArithDecoder, &IDS)) 279 break; 280 CURS = CURS + IDS + SBDSOFFSET; 281 } 282 if (NINSTANCES >= SBNUMINSTANCES) { 283 break; 284 } 285 int CURT = 0; 286 if (SBSTRIPS != 1) 287 IAIT->decode(pArithDecoder, &CURT); 288 289 TI = STRIPT + CURT; 290 FX_DWORD IDI; 291 IAID->decode(pArithDecoder, &IDI); 292 if (IDI >= SBNUMSYMS) 293 goto failed; 294 295 if (SBREFINE == 0) 296 RI = 0; 297 else 298 IARI->decode(pArithDecoder, &RI); 299 300 if (!SBSYMS[IDI]) 301 goto failed; 302 303 if (RI == 0) { 304 IBI = SBSYMS[IDI]; 305 } else { 306 IARDW->decode(pArithDecoder, &RDWI); 307 IARDH->decode(pArithDecoder, &RDHI); 308 IARDX->decode(pArithDecoder, &RDXI); 309 IARDY->decode(pArithDecoder, &RDYI); 310 IBOI = SBSYMS[IDI]; 311 WOI = IBOI->m_nWidth; 312 HOI = IBOI->m_nHeight; 313 if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) { 314 goto failed; 315 } 316 std::unique_ptr<CJBig2_GRRDProc> pGRRD(new CJBig2_GRRDProc()); 317 pGRRD->GRW = WOI + RDWI; 318 pGRRD->GRH = HOI + RDHI; 319 pGRRD->GRTEMPLATE = SBRTEMPLATE; 320 pGRRD->GRREFERENCE = IBOI; 321 pGRRD->GRREFERENCEDX = (RDWI >> 1) + RDXI; 322 pGRRD->GRREFERENCEDY = (RDHI >> 1) + RDYI; 323 pGRRD->TPGRON = 0; 324 pGRRD->GRAT[0] = SBRAT[0]; 325 pGRRD->GRAT[1] = SBRAT[1]; 326 pGRRD->GRAT[2] = SBRAT[2]; 327 pGRRD->GRAT[3] = SBRAT[3]; 328 IBI = pGRRD->decode(pArithDecoder, grContext); 329 if (!IBI) 330 goto failed; 331 } 332 WI = IBI->m_nWidth; 333 HI = IBI->m_nHeight; 334 if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) || 335 (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) { 336 CURS = CURS + WI - 1; 337 } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT) || 338 (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) { 339 CURS = CURS + HI - 1; 340 } 341 SI = CURS; 342 if (TRANSPOSED == 0) { 343 switch (REFCORNER) { 344 case JBIG2_CORNER_TOPLEFT: 345 SBREG->composeFrom(SI, TI, IBI, SBCOMBOP); 346 break; 347 case JBIG2_CORNER_TOPRIGHT: 348 SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP); 349 break; 350 case JBIG2_CORNER_BOTTOMLEFT: 351 SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP); 352 break; 353 case JBIG2_CORNER_BOTTOMRIGHT: 354 SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP); 355 break; 356 } 357 } else { 358 switch (REFCORNER) { 359 case JBIG2_CORNER_TOPLEFT: 360 SBREG->composeFrom(TI, SI, IBI, SBCOMBOP); 361 break; 362 case JBIG2_CORNER_TOPRIGHT: 363 SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP); 364 break; 365 case JBIG2_CORNER_BOTTOMLEFT: 366 SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP); 367 break; 368 case JBIG2_CORNER_BOTTOMRIGHT: 369 SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP); 370 break; 371 } 372 } 373 if (RI != 0) { 374 delete IBI; 375 } 376 if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) || 377 (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) { 378 CURS = CURS + WI - 1; 379 } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) || 380 (REFCORNER == JBIG2_CORNER_TOPRIGHT))) { 381 CURS = CURS + HI - 1; 382 } 383 NINSTANCES = NINSTANCES + 1; 384 } 385 } 386 if (bRetained == FALSE) { 387 delete IADT; 388 delete IAFS; 389 delete IADS; 390 delete IAIT; 391 delete IARI; 392 delete IARDW; 393 delete IARDH; 394 delete IARDX; 395 delete IARDY; 396 delete IAID; 397 } 398 return SBREG.release(); 399failed: 400 if (bRetained == FALSE) { 401 delete IADT; 402 delete IAFS; 403 delete IADS; 404 delete IAIT; 405 delete IARI; 406 delete IARDW; 407 delete IARDH; 408 delete IARDX; 409 delete IARDY; 410 delete IAID; 411 } 412 return nullptr; 413} 414