| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "JBig2_Context.h" | 7 #include "JBig2_Context.h" |
| 8 void OutputBitmap(CJBig2_Image* pImage) | 8 void OutputBitmap(CJBig2_Image* pImage) { |
| 9 { | 9 if (!pImage) { |
| 10 if(!pImage) { | 10 return; |
| 11 return; | 11 } |
| 12 } | 12 } |
| 13 } | 13 CJBig2_Context* CJBig2_Context::CreateContext(CJBig2_Module* pModule, |
| 14 CJBig2_Context *CJBig2_Context::CreateContext(CJBig2_Module *pModule, FX_BYTE *p
GlobalData, FX_DWORD dwGlobalLength, | 14 FX_BYTE* pGlobalData, |
| 15 FX_BYTE *pData, FX_DWORD dwLength, FX_INT32 nStreamType, IFX_Pause* pPau
se) | 15 FX_DWORD dwGlobalLength, |
| 16 { | 16 FX_BYTE* pData, |
| 17 return new(pModule) CJBig2_Context(pGlobalData, dwGlobalLength, pData, dwLen
gth, nStreamType, pPause); | 17 FX_DWORD dwLength, |
| 18 } | 18 FX_INT32 nStreamType, |
| 19 void CJBig2_Context::DestroyContext(CJBig2_Context *pContext) | 19 IFX_Pause* pPause) { |
| 20 { | 20 return new (pModule) CJBig2_Context( |
| 21 if(pContext) { | 21 pGlobalData, dwGlobalLength, pData, dwLength, nStreamType, pPause); |
| 22 delete pContext; | 22 } |
| 23 } | 23 void CJBig2_Context::DestroyContext(CJBig2_Context* pContext) { |
| 24 } | 24 if (pContext) { |
| 25 CJBig2_Context::CJBig2_Context(FX_BYTE *pGlobalData, FX_DWORD dwGlobalLength, | 25 delete pContext; |
| 26 FX_BYTE *pData, FX_DWORD dwLength, FX_INT32 nStre
amType, IFX_Pause* pPause) | 26 } |
| 27 { | 27 } |
| 28 if(pGlobalData && (dwGlobalLength > 0)) { | 28 CJBig2_Context::CJBig2_Context(FX_BYTE* pGlobalData, |
| 29 JBIG2_ALLOC(m_pGlobalContext, CJBig2_Context(NULL, 0, pGlobalData, dwGlo
balLength, | 29 FX_DWORD dwGlobalLength, |
| 30 JBIG2_EMBED_STREAM, pPause)); | 30 FX_BYTE* pData, |
| 31 FX_DWORD dwLength, |
| 32 FX_INT32 nStreamType, |
| 33 IFX_Pause* pPause) { |
| 34 if (pGlobalData && (dwGlobalLength > 0)) { |
| 35 JBIG2_ALLOC( |
| 36 m_pGlobalContext, |
| 37 CJBig2_Context( |
| 38 NULL, 0, pGlobalData, dwGlobalLength, JBIG2_EMBED_STREAM, pPause)); |
| 39 } else { |
| 40 m_pGlobalContext = NULL; |
| 41 } |
| 42 JBIG2_ALLOC(m_pStream, CJBig2_BitStream(pData, dwLength)); |
| 43 m_nStreamType = nStreamType; |
| 44 m_nState = JBIG2_OUT_OF_PAGE; |
| 45 JBIG2_ALLOC(m_pSegmentList, CJBig2_List<CJBig2_Segment>); |
| 46 JBIG2_ALLOC(m_pPageInfoList, CJBig2_List<JBig2PageInfo>(1)); |
| 47 m_pPage = NULL; |
| 48 m_bBufSpecified = FALSE; |
| 49 m_pPause = pPause; |
| 50 m_nSegmentDecoded = 0; |
| 51 m_PauseStep = 10; |
| 52 m_pArithDecoder = NULL; |
| 53 m_pGRD = NULL; |
| 54 m_gbContext = NULL; |
| 55 m_pSegment = NULL; |
| 56 m_dwOffset = 0; |
| 57 m_ProcessiveStatus = FXCODEC_STATUS_FRAME_READY; |
| 58 } |
| 59 CJBig2_Context::~CJBig2_Context() { |
| 60 if (m_pArithDecoder) { |
| 61 delete m_pArithDecoder; |
| 62 } |
| 63 m_pArithDecoder = NULL; |
| 64 if (m_pGRD) { |
| 65 delete m_pGRD; |
| 66 } |
| 67 m_pGRD = NULL; |
| 68 if (m_gbContext) { |
| 69 m_pModule->JBig2_Free(m_gbContext); |
| 70 } |
| 71 m_gbContext = NULL; |
| 72 if (m_pGlobalContext) { |
| 73 delete m_pGlobalContext; |
| 74 } |
| 75 m_pGlobalContext = NULL; |
| 76 if (m_pPageInfoList) { |
| 77 delete m_pPageInfoList; |
| 78 } |
| 79 m_pPageInfoList = NULL; |
| 80 if (m_bBufSpecified && m_pPage) { |
| 81 delete m_pPage; |
| 82 } |
| 83 m_pPage = NULL; |
| 84 if (m_pStream) { |
| 85 delete m_pStream; |
| 86 } |
| 87 m_pStream = NULL; |
| 88 if (m_pSegmentList) { |
| 89 delete m_pSegmentList; |
| 90 } |
| 91 m_pSegmentList = NULL; |
| 92 } |
| 93 FX_INT32 CJBig2_Context::decodeFile(IFX_Pause* pPause) { |
| 94 FX_BYTE cFlags; |
| 95 FX_DWORD dwTemp; |
| 96 const FX_BYTE fileID[] = { 0x97, 0x4A, 0x42, 0x32, 0x0D, 0x0A, 0x1A, 0x0A }; |
| 97 FX_INT32 nRet; |
| 98 if (m_pStream->getByteLeft() < 8) { |
| 99 m_pModule->JBig2_Error("file header too short."); |
| 100 nRet = JBIG2_ERROR_TOO_SHORT; |
| 101 goto failed; |
| 102 } |
| 103 if (JBIG2_memcmp(m_pStream->getPointer(), fileID, 8) != 0) { |
| 104 m_pModule->JBig2_Error("not jbig2 file"); |
| 105 nRet = JBIG2_ERROR_FILE_FORMAT; |
| 106 goto failed; |
| 107 } |
| 108 m_pStream->offset(8); |
| 109 if (m_pStream->read1Byte(&cFlags) != 0) { |
| 110 m_pModule->JBig2_Error("file header too short."); |
| 111 nRet = JBIG2_ERROR_TOO_SHORT; |
| 112 goto failed; |
| 113 } |
| 114 if (!(cFlags & 0x02)) { |
| 115 if (m_pStream->readInteger(&dwTemp) != 0) { |
| 116 m_pModule->JBig2_Error("file header too short."); |
| 117 nRet = JBIG2_ERROR_TOO_SHORT; |
| 118 goto failed; |
| 119 } |
| 120 if (dwTemp > 0) { |
| 121 delete m_pPageInfoList; |
| 122 JBIG2_ALLOC(m_pPageInfoList, CJBig2_List<JBig2PageInfo>(dwTemp)); |
| 123 } |
| 124 } |
| 125 if (cFlags & 0x01) { |
| 126 m_nStreamType = JBIG2_SQUENTIAL_STREAM; |
| 127 return decode_SquentialOrgnazation(pPause); |
| 128 } else { |
| 129 m_nStreamType = JBIG2_RANDOM_STREAM; |
| 130 return decode_RandomOrgnazation_FirstPage(pPause); |
| 131 } |
| 132 failed: |
| 133 return nRet; |
| 134 } |
| 135 FX_INT32 CJBig2_Context::decode_SquentialOrgnazation(IFX_Pause* pPause) { |
| 136 FX_INT32 nRet; |
| 137 if (m_pStream->getByteLeft() > 0) { |
| 138 while (m_pStream->getByteLeft() >= JBIG2_MIN_SEGMENT_SIZE) { |
| 139 if (m_pSegment == NULL) { |
| 140 JBIG2_ALLOC(m_pSegment, CJBig2_Segment()); |
| 141 nRet = parseSegmentHeader(m_pSegment); |
| 142 if (nRet != JBIG2_SUCCESS) { |
| 143 delete m_pSegment; |
| 144 m_pSegment = NULL; |
| 145 return nRet; |
| 146 } |
| 147 m_dwOffset = m_pStream->getOffset(); |
| 148 } |
| 149 nRet = parseSegmentData(m_pSegment, pPause); |
| 150 if (m_ProcessiveStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) { |
| 151 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
| 152 m_PauseStep = 2; |
| 153 return JBIG2_SUCCESS; |
| 154 } |
| 155 if ((nRet == JBIG2_END_OF_PAGE) || (nRet == JBIG2_END_OF_FILE)) { |
| 156 delete m_pSegment; |
| 157 m_pSegment = NULL; |
| 158 break; |
| 159 } else if (nRet != JBIG2_SUCCESS) { |
| 160 delete m_pSegment; |
| 161 m_pSegment = NULL; |
| 162 return nRet; |
| 163 } |
| 164 m_pSegmentList->addItem(m_pSegment); |
| 165 if (m_pSegment->m_dwData_length != 0xffffffff) { |
| 166 m_dwOffset = m_dwOffset + m_pSegment->m_dwData_length; |
| 167 m_pStream->setOffset(m_dwOffset); |
| 168 } else { |
| 169 m_pStream->offset(4); |
| 170 } |
| 171 OutputBitmap(m_pPage); |
| 172 m_pSegment = NULL; |
| 173 if (m_pStream->getByteLeft() > 0 && m_pPage && pPause && |
| 174 pPause->NeedToPauseNow()) { |
| 175 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
| 176 m_PauseStep = 2; |
| 177 return JBIG2_SUCCESS; |
| 178 } |
| 179 } |
| 180 } else { |
| 181 return JBIG2_END_OF_FILE; |
| 182 } |
| 183 return JBIG2_SUCCESS; |
| 184 } |
| 185 FX_INT32 CJBig2_Context::decode_EmbedOrgnazation(IFX_Pause* pPause) { |
| 186 return decode_SquentialOrgnazation(pPause); |
| 187 } |
| 188 FX_INT32 CJBig2_Context::decode_RandomOrgnazation_FirstPage(IFX_Pause* pPause) { |
| 189 CJBig2_Segment* pSegment; |
| 190 FX_INT32 nRet; |
| 191 while (m_pStream->getByteLeft() > JBIG2_MIN_SEGMENT_SIZE) { |
| 192 JBIG2_ALLOC(pSegment, CJBig2_Segment()); |
| 193 nRet = parseSegmentHeader(pSegment); |
| 194 if (nRet != JBIG2_SUCCESS) { |
| 195 delete pSegment; |
| 196 return nRet; |
| 197 } else if (pSegment->m_cFlags.s.type == 51) { |
| 198 delete pSegment; |
| 199 break; |
| 200 } |
| 201 m_pSegmentList->addItem(pSegment); |
| 202 if (pPause && m_pPause && pPause->NeedToPauseNow()) { |
| 203 m_PauseStep = 3; |
| 204 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
| 205 return JBIG2_SUCCESS; |
| 206 } |
| 207 } |
| 208 m_nSegmentDecoded = 0; |
| 209 return decode_RandomOrgnazation(pPause); |
| 210 } |
| 211 FX_INT32 CJBig2_Context::decode_RandomOrgnazation(IFX_Pause* pPause) { |
| 212 FX_INT32 nRet; |
| 213 for (; m_nSegmentDecoded < m_pSegmentList->getLength(); m_nSegmentDecoded++) { |
| 214 nRet = parseSegmentData(m_pSegmentList->getAt(m_nSegmentDecoded), pPause); |
| 215 if ((nRet == JBIG2_END_OF_PAGE) || (nRet == JBIG2_END_OF_FILE)) { |
| 216 break; |
| 217 } else if (nRet != JBIG2_SUCCESS) { |
| 218 return nRet; |
| 219 } |
| 220 if (m_pPage && pPause && pPause->NeedToPauseNow()) { |
| 221 m_PauseStep = 4; |
| 222 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
| 223 return JBIG2_SUCCESS; |
| 224 } |
| 225 } |
| 226 return JBIG2_SUCCESS; |
| 227 } |
| 228 FX_INT32 CJBig2_Context::getFirstPage(FX_BYTE* pBuf, |
| 229 FX_INT32 width, |
| 230 FX_INT32 height, |
| 231 FX_INT32 stride, |
| 232 IFX_Pause* pPause) { |
| 233 FX_INT32 nRet = 0; |
| 234 if (m_pGlobalContext) { |
| 235 nRet = m_pGlobalContext->decode_EmbedOrgnazation(pPause); |
| 236 if (nRet != JBIG2_SUCCESS) { |
| 237 m_ProcessiveStatus = FXCODEC_STATUS_ERROR; |
| 238 return nRet; |
| 239 } |
| 240 } |
| 241 m_bFirstPage = TRUE; |
| 242 m_PauseStep = 0; |
| 243 if (m_pPage) { |
| 244 delete m_pPage; |
| 245 } |
| 246 JBIG2_ALLOC(m_pPage, CJBig2_Image(width, height, stride, pBuf)); |
| 247 m_bBufSpecified = TRUE; |
| 248 if (m_pPage && pPause && pPause->NeedToPauseNow()) { |
| 249 m_PauseStep = 1; |
| 250 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
| 251 return nRet; |
| 252 } |
| 253 int ret = Continue(pPause); |
| 254 return ret; |
| 255 } |
| 256 FX_INT32 CJBig2_Context::Continue(IFX_Pause* pPause) { |
| 257 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_READY; |
| 258 FX_INT32 nRet; |
| 259 if (m_PauseStep <= 1) { |
| 260 switch (m_nStreamType) { |
| 261 case JBIG2_FILE_STREAM: |
| 262 nRet = decodeFile(pPause); |
| 263 break; |
| 264 case JBIG2_SQUENTIAL_STREAM: |
| 265 nRet = decode_SquentialOrgnazation(pPause); |
| 266 break; |
| 267 case JBIG2_RANDOM_STREAM: |
| 268 if (m_bFirstPage) { |
| 269 nRet = decode_RandomOrgnazation_FirstPage(pPause); |
| 270 } else { |
| 271 nRet = decode_RandomOrgnazation(pPause); |
| 272 } |
| 273 break; |
| 274 case JBIG2_EMBED_STREAM: |
| 275 nRet = decode_EmbedOrgnazation(pPause); |
| 276 break; |
| 277 default: |
| 278 m_ProcessiveStatus = FXCODEC_STATUS_ERROR; |
| 279 return JBIG2_ERROR_STREAM_TYPE; |
| 280 } |
| 281 } else if (m_PauseStep == 2) { |
| 282 nRet = decode_SquentialOrgnazation(pPause); |
| 283 } else if (m_PauseStep == 3) { |
| 284 nRet = decode_RandomOrgnazation_FirstPage(pPause); |
| 285 } else if (m_PauseStep == 4) { |
| 286 nRet = decode_RandomOrgnazation(pPause); |
| 287 } else if (m_PauseStep == 5) { |
| 288 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_FINISH; |
| 289 return JBIG2_SUCCESS; |
| 290 } |
| 291 if (m_ProcessiveStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) { |
| 292 return nRet; |
| 293 } |
| 294 m_PauseStep = 5; |
| 295 if (!m_bBufSpecified && nRet == JBIG2_SUCCESS) { |
| 296 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_FINISH; |
| 297 return JBIG2_SUCCESS; |
| 298 } |
| 299 if (nRet == JBIG2_SUCCESS) { |
| 300 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_FINISH; |
| 301 } else { |
| 302 m_ProcessiveStatus = FXCODEC_STATUS_ERROR; |
| 303 } |
| 304 return nRet; |
| 305 } |
| 306 FX_INT32 CJBig2_Context::getNextPage(FX_BYTE* pBuf, |
| 307 FX_INT32 width, |
| 308 FX_INT32 height, |
| 309 FX_INT32 stride, |
| 310 IFX_Pause* pPause) { |
| 311 FX_INT32 nRet = JBIG2_ERROR_STREAM_TYPE; |
| 312 m_bFirstPage = FALSE; |
| 313 m_PauseStep = 0; |
| 314 if (m_pPage) { |
| 315 delete m_pPage; |
| 316 } |
| 317 JBIG2_ALLOC(m_pPage, CJBig2_Image(width, height, stride, pBuf)); |
| 318 m_bBufSpecified = TRUE; |
| 319 if (m_pPage && pPause && pPause->NeedToPauseNow()) { |
| 320 m_PauseStep = 1; |
| 321 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
| 322 return nRet; |
| 323 } |
| 324 return Continue(pPause); |
| 325 switch (m_nStreamType) { |
| 326 case JBIG2_FILE_STREAM: |
| 327 nRet = decodeFile(pPause); |
| 328 break; |
| 329 case JBIG2_SQUENTIAL_STREAM: |
| 330 nRet = decode_SquentialOrgnazation(pPause); |
| 331 break; |
| 332 case JBIG2_RANDOM_STREAM: |
| 333 nRet = decode_RandomOrgnazation(pPause); |
| 334 break; |
| 335 case JBIG2_EMBED_STREAM: |
| 336 nRet = decode_EmbedOrgnazation(pPause); |
| 337 break; |
| 338 default: |
| 339 return JBIG2_ERROR_STREAM_TYPE; |
| 340 } |
| 341 return nRet; |
| 342 } |
| 343 FX_INT32 CJBig2_Context::getFirstPage(CJBig2_Image** image, IFX_Pause* pPause) { |
| 344 FX_INT32 nRet; |
| 345 m_bFirstPage = TRUE; |
| 346 m_PauseStep = 0; |
| 347 if (m_pGlobalContext) { |
| 348 nRet = m_pGlobalContext->decode_EmbedOrgnazation(pPause); |
| 349 if (nRet != JBIG2_SUCCESS) { |
| 350 return nRet; |
| 351 } |
| 352 } |
| 353 m_bBufSpecified = FALSE; |
| 354 return Continue(pPause); |
| 355 } |
| 356 FX_INT32 CJBig2_Context::getNextPage(CJBig2_Image** image, IFX_Pause* pPause) { |
| 357 FX_INT32 nRet; |
| 358 m_bBufSpecified = FALSE; |
| 359 m_bFirstPage = FALSE; |
| 360 m_PauseStep = 0; |
| 361 switch (m_nStreamType) { |
| 362 case JBIG2_FILE_STREAM: |
| 363 nRet = decodeFile(pPause); |
| 364 break; |
| 365 case JBIG2_SQUENTIAL_STREAM: |
| 366 nRet = decode_SquentialOrgnazation(pPause); |
| 367 break; |
| 368 case JBIG2_RANDOM_STREAM: |
| 369 nRet = decode_RandomOrgnazation(pPause); |
| 370 break; |
| 371 case JBIG2_EMBED_STREAM: |
| 372 nRet = decode_EmbedOrgnazation(pPause); |
| 373 break; |
| 374 default: |
| 375 return JBIG2_ERROR_STREAM_TYPE; |
| 376 } |
| 377 if (nRet == JBIG2_SUCCESS) { |
| 378 *image = m_pPage; |
| 379 m_pPage = NULL; |
| 380 return JBIG2_SUCCESS; |
| 381 } |
| 382 return nRet; |
| 383 } |
| 384 CJBig2_Segment* CJBig2_Context::findSegmentByNumber(FX_DWORD dwNumber) { |
| 385 CJBig2_Segment* pSeg; |
| 386 FX_INT32 i; |
| 387 if (m_pGlobalContext) { |
| 388 pSeg = m_pGlobalContext->findSegmentByNumber(dwNumber); |
| 389 if (pSeg) { |
| 390 return pSeg; |
| 391 } |
| 392 } |
| 393 for (i = 0; i < m_pSegmentList->getLength(); i++) { |
| 394 pSeg = m_pSegmentList->getAt(i); |
| 395 if (pSeg->m_dwNumber == dwNumber) { |
| 396 return pSeg; |
| 397 } |
| 398 } |
| 399 return NULL; |
| 400 } |
| 401 CJBig2_Segment* CJBig2_Context::findReferredSegmentByTypeAndIndex( |
| 402 CJBig2_Segment* pSegment, |
| 403 FX_BYTE cType, |
| 404 FX_INT32 nIndex) { |
| 405 CJBig2_Segment* pSeg; |
| 406 FX_INT32 i, count; |
| 407 count = 0; |
| 408 for (i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { |
| 409 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); |
| 410 if (pSeg && pSeg->m_cFlags.s.type == cType) { |
| 411 if (count == nIndex) { |
| 412 return pSeg; |
| 413 } else { |
| 414 count++; |
| 415 } |
| 416 } |
| 417 } |
| 418 return NULL; |
| 419 } |
| 420 FX_INT32 CJBig2_Context::parseSegmentHeader(CJBig2_Segment* pSegment) { |
| 421 FX_BYTE cSSize, cPSize; |
| 422 FX_BYTE cTemp; |
| 423 FX_WORD wTemp; |
| 424 FX_DWORD dwTemp; |
| 425 if ((m_pStream->readInteger(&pSegment->m_dwNumber) != 0) || |
| 426 (m_pStream->read1Byte(&pSegment->m_cFlags.c) != 0)) { |
| 427 goto failed; |
| 428 } |
| 429 cTemp = m_pStream->getCurByte(); |
| 430 if ((cTemp >> 5) == 7) { |
| 431 if (m_pStream->readInteger( |
| 432 (FX_DWORD*)&pSegment->m_nReferred_to_segment_count) != 0) { |
| 433 goto failed; |
| 434 } |
| 435 pSegment->m_nReferred_to_segment_count &= 0x1fffffff; |
| 436 if (pSegment->m_nReferred_to_segment_count > |
| 437 JBIG2_MAX_REFERRED_SEGMENT_COUNT) { |
| 438 m_pModule->JBig2_Error("Too many referred segments."); |
| 439 return JBIG2_ERROR_LIMIT; |
| 440 } |
| 441 dwTemp = 5 + 4 + (pSegment->m_nReferred_to_segment_count + 1) / 8; |
| 442 } else { |
| 443 if (m_pStream->read1Byte(&cTemp) != 0) { |
| 444 goto failed; |
| 445 } |
| 446 pSegment->m_nReferred_to_segment_count = cTemp >> 5; |
| 447 dwTemp = 5 + 1; |
| 448 } |
| 449 cSSize = |
| 450 pSegment->m_dwNumber > 65536 ? 4 : pSegment->m_dwNumber > 256 ? 2 : 1; |
| 451 cPSize = pSegment->m_cFlags.s.page_association_size ? 4 : 1; |
| 452 if (pSegment->m_nReferred_to_segment_count) { |
| 453 pSegment->m_pReferred_to_segment_numbers = |
| 454 (FX_DWORD*)m_pModule->JBig2_Malloc2( |
| 455 sizeof(FX_DWORD), pSegment->m_nReferred_to_segment_count); |
| 456 for (FX_INT32 i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { |
| 457 switch (cSSize) { |
| 458 case 1: |
| 459 if (m_pStream->read1Byte(&cTemp) != 0) { |
| 460 goto failed; |
| 461 } |
| 462 pSegment->m_pReferred_to_segment_numbers[i] = cTemp; |
| 463 break; |
| 464 case 2: |
| 465 if (m_pStream->readShortInteger(&wTemp) != 0) { |
| 466 goto failed; |
| 467 } |
| 468 pSegment->m_pReferred_to_segment_numbers[i] = wTemp; |
| 469 break; |
| 470 case 4: |
| 471 if (m_pStream->readInteger(&dwTemp) != 0) { |
| 472 goto failed; |
| 473 } |
| 474 pSegment->m_pReferred_to_segment_numbers[i] = dwTemp; |
| 475 break; |
| 476 } |
| 477 if (pSegment->m_pReferred_to_segment_numbers[i] >= pSegment->m_dwNumber) { |
| 478 m_pModule->JBig2_Error( |
| 479 "The referred segment number is greater than this segment number."); |
| 480 goto failed; |
| 481 } |
| 482 } |
| 483 } |
| 484 if (cPSize == 1) { |
| 485 if (m_pStream->read1Byte(&cTemp) != 0) { |
| 486 goto failed; |
| 487 } |
| 488 pSegment->m_dwPage_association = cTemp; |
| 489 } else { |
| 490 if (m_pStream->readInteger(&pSegment->m_dwPage_association) != 0) { |
| 491 goto failed; |
| 492 } |
| 493 } |
| 494 if (m_pStream->readInteger(&pSegment->m_dwData_length) != 0) { |
| 495 goto failed; |
| 496 } |
| 497 pSegment->m_pData = m_pStream->getPointer(); |
| 498 pSegment->m_State = JBIG2_SEGMENT_DATA_UNPARSED; |
| 499 return JBIG2_SUCCESS; |
| 500 failed: |
| 501 m_pModule->JBig2_Error("header too short."); |
| 502 return JBIG2_ERROR_TOO_SHORT; |
| 503 } |
| 504 FX_INT32 CJBig2_Context::parseSegmentData(CJBig2_Segment* pSegment, |
| 505 IFX_Pause* pPause) { |
| 506 FX_INT32 ret = ProcessiveParseSegmentData(pSegment, pPause); |
| 507 while (m_ProcessiveStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE && |
| 508 m_pStream->getByteLeft() > 0) { |
| 509 ret = ProcessiveParseSegmentData(pSegment, pPause); |
| 510 } |
| 511 return ret; |
| 512 } |
| 513 FX_INT32 CJBig2_Context::ProcessiveParseSegmentData(CJBig2_Segment* pSegment, |
| 514 IFX_Pause* pPause) { |
| 515 switch (pSegment->m_cFlags.s.type) { |
| 516 case 0: |
| 517 return parseSymbolDict(pSegment, pPause); |
| 518 case 4: |
| 519 case 6: |
| 520 case 7: |
| 521 if (m_nState == JBIG2_OUT_OF_PAGE) { |
| 522 goto failed2; |
| 523 } else { |
| 524 return parseTextRegion(pSegment); |
| 525 } |
| 526 case 16: |
| 527 return parsePatternDict(pSegment, pPause); |
| 528 case 20: |
| 529 case 22: |
| 530 case 23: |
| 531 if (m_nState == JBIG2_OUT_OF_PAGE) { |
| 532 goto failed2; |
| 533 } else { |
| 534 return parseHalftoneRegion(pSegment, pPause); |
| 535 } |
| 536 case 36: |
| 537 case 38: |
| 538 case 39: |
| 539 if (m_nState == JBIG2_OUT_OF_PAGE) { |
| 540 goto failed2; |
| 541 } else { |
| 542 return parseGenericRegion(pSegment, pPause); |
| 543 } |
| 544 case 40: |
| 545 case 42: |
| 546 case 43: |
| 547 if (m_nState == JBIG2_OUT_OF_PAGE) { |
| 548 goto failed2; |
| 549 } else { |
| 550 return parseGenericRefinementRegion(pSegment); |
| 551 } |
| 552 case 48: { |
| 553 FX_WORD wTemp; |
| 554 JBig2PageInfo* pPageInfo; |
| 555 JBIG2_ALLOC(pPageInfo, JBig2PageInfo); |
| 556 if ((m_pStream->readInteger(&pPageInfo->m_dwWidth) != 0) || |
| 557 (m_pStream->readInteger(&pPageInfo->m_dwHeight) != 0) || |
| 558 (m_pStream->readInteger(&pPageInfo->m_dwResolutionX) != 0) || |
| 559 (m_pStream->readInteger(&pPageInfo->m_dwResolutionY) != 0) || |
| 560 (m_pStream->read1Byte(&pPageInfo->m_cFlags) != 0) || |
| 561 (m_pStream->readShortInteger(&wTemp) != 0)) { |
| 562 delete pPageInfo; |
| 563 goto failed1; |
| 564 } |
| 565 pPageInfo->m_bIsStriped = ((wTemp >> 15) & 1) ? 1 : 0; |
| 566 pPageInfo->m_wMaxStripeSize = wTemp & 0x7fff; |
| 567 if ((pPageInfo->m_dwHeight == 0xffffffff) && |
| 568 (pPageInfo->m_bIsStriped != 1)) { |
| 569 m_pModule->JBig2_Warn("page height = 0xffffffff buf stripe field is 0"); |
| 570 pPageInfo->m_bIsStriped = 1; |
| 571 } |
| 572 if (!m_bBufSpecified) { |
| 573 if (m_pPage) { |
| 574 delete m_pPage; |
| 575 } |
| 576 if (pPageInfo->m_dwHeight == 0xffffffff) { |
| 577 JBIG2_ALLOC( |
| 578 m_pPage, |
| 579 CJBig2_Image(pPageInfo->m_dwWidth, pPageInfo->m_wMaxStripeSize)); |
| 580 } else { |
| 581 JBIG2_ALLOC( |
| 582 m_pPage, |
| 583 CJBig2_Image(pPageInfo->m_dwWidth, pPageInfo->m_dwHeight)); |
| 584 } |
| 585 } |
| 586 m_pPage->fill((pPageInfo->m_cFlags & 4) ? 1 : 0); |
| 587 m_pPageInfoList->addItem(pPageInfo); |
| 588 m_nState = JBIG2_IN_PAGE; |
| 589 } break; |
| 590 case 49: |
| 591 m_nState = JBIG2_OUT_OF_PAGE; |
| 592 return JBIG2_END_OF_PAGE; |
| 593 break; |
| 594 case 50: |
| 595 m_pStream->offset(pSegment->m_dwData_length); |
| 596 break; |
| 597 case 51: |
| 598 return JBIG2_END_OF_FILE; |
| 599 case 52: |
| 600 m_pStream->offset(pSegment->m_dwData_length); |
| 601 break; |
| 602 case 53: |
| 603 return parseTable(pSegment); |
| 604 case 62: |
| 605 m_pStream->offset(pSegment->m_dwData_length); |
| 606 break; |
| 607 default: |
| 608 break; |
| 609 } |
| 610 return JBIG2_SUCCESS; |
| 611 failed1: |
| 612 m_pModule->JBig2_Error("segment data too short."); |
| 613 return JBIG2_ERROR_TOO_SHORT; |
| 614 failed2: |
| 615 m_pModule->JBig2_Error("segment syntax error."); |
| 616 return JBIG2_ERROR_FETAL; |
| 617 } |
| 618 FX_INT32 CJBig2_Context::parseSymbolDict(CJBig2_Segment* pSegment, |
| 619 IFX_Pause* pPause) { |
| 620 FX_DWORD dwTemp; |
| 621 FX_WORD wFlags; |
| 622 FX_BYTE cSDHUFFDH, cSDHUFFDW, cSDHUFFBMSIZE, cSDHUFFAGGINST; |
| 623 CJBig2_HuffmanTable* Table_B1 = NULL, * Table_B2 = NULL, * Table_B3 = NULL, |
| 624 * Table_B4 = NULL, * Table_B5 = NULL; |
| 625 FX_INT32 i, nIndex, nRet; |
| 626 CJBig2_Segment* pSeg = NULL, * pLRSeg = NULL; |
| 627 FX_BOOL bUsed; |
| 628 CJBig2_Image** SDINSYMS = NULL; |
| 629 CJBig2_SDDProc* pSymbolDictDecoder; |
| 630 JBig2ArithCtx* gbContext = NULL, * grContext = NULL; |
| 631 CJBig2_ArithDecoder* pArithDecoder; |
| 632 JBIG2_ALLOC(pSymbolDictDecoder, CJBig2_SDDProc()); |
| 633 if (m_pStream->readShortInteger(&wFlags) != 0) { |
| 634 m_pModule->JBig2_Error( |
| 635 "symbol dictionary segment : data header too short."); |
| 636 nRet = JBIG2_ERROR_TOO_SHORT; |
| 637 goto failed; |
| 638 } |
| 639 pSymbolDictDecoder->SDHUFF = wFlags & 0x0001; |
| 640 pSymbolDictDecoder->SDREFAGG = (wFlags >> 1) & 0x0001; |
| 641 pSymbolDictDecoder->SDTEMPLATE = (wFlags >> 10) & 0x0003; |
| 642 pSymbolDictDecoder->SDRTEMPLATE = (wFlags >> 12) & 0x0003; |
| 643 cSDHUFFDH = (wFlags >> 2) & 0x0003; |
| 644 cSDHUFFDW = (wFlags >> 4) & 0x0003; |
| 645 cSDHUFFBMSIZE = (wFlags >> 6) & 0x0001; |
| 646 cSDHUFFAGGINST = (wFlags >> 7) & 0x0001; |
| 647 if (pSymbolDictDecoder->SDHUFF == 0) { |
| 648 if (pSymbolDictDecoder->SDTEMPLATE == 0) { |
| 649 dwTemp = 8; |
| 31 } else { | 650 } else { |
| 32 m_pGlobalContext = NULL; | 651 dwTemp = 2; |
| 33 } | 652 } |
| 34 JBIG2_ALLOC(m_pStream, CJBig2_BitStream(pData, dwLength)); | 653 for (i = 0; i < (FX_INT32)dwTemp; i++) { |
| 35 m_nStreamType = nStreamType; | 654 if (m_pStream->read1Byte((FX_BYTE*)&pSymbolDictDecoder->SDAT[i]) != 0) { |
| 36 m_nState = JBIG2_OUT_OF_PAGE; | 655 m_pModule->JBig2_Error( |
| 37 JBIG2_ALLOC(m_pSegmentList, CJBig2_List<CJBig2_Segment>); | 656 "symbol dictionary segment : data header too short."); |
| 38 JBIG2_ALLOC(m_pPageInfoList, CJBig2_List<JBig2PageInfo>(1)); | |
| 39 m_pPage = NULL; | |
| 40 m_bBufSpecified = FALSE; | |
| 41 m_pPause = pPause; | |
| 42 m_nSegmentDecoded = 0; | |
| 43 m_PauseStep = 10; | |
| 44 m_pArithDecoder = NULL; | |
| 45 m_pGRD = NULL; | |
| 46 m_gbContext = NULL; | |
| 47 m_pSegment = NULL; | |
| 48 m_dwOffset = 0; | |
| 49 m_ProcessiveStatus = FXCODEC_STATUS_FRAME_READY; | |
| 50 } | |
| 51 CJBig2_Context::~CJBig2_Context() | |
| 52 { | |
| 53 if(m_pArithDecoder) { | |
| 54 delete m_pArithDecoder; | |
| 55 } | |
| 56 m_pArithDecoder = NULL; | |
| 57 if(m_pGRD) { | |
| 58 delete m_pGRD; | |
| 59 } | |
| 60 m_pGRD = NULL; | |
| 61 if(m_gbContext) { | |
| 62 m_pModule->JBig2_Free(m_gbContext); | |
| 63 } | |
| 64 m_gbContext = NULL; | |
| 65 if(m_pGlobalContext) { | |
| 66 delete m_pGlobalContext; | |
| 67 } | |
| 68 m_pGlobalContext = NULL; | |
| 69 if(m_pPageInfoList) { | |
| 70 delete m_pPageInfoList; | |
| 71 } | |
| 72 m_pPageInfoList = NULL; | |
| 73 if(m_bBufSpecified && m_pPage) { | |
| 74 delete m_pPage; | |
| 75 } | |
| 76 m_pPage = NULL; | |
| 77 if(m_pStream) { | |
| 78 delete m_pStream; | |
| 79 } | |
| 80 m_pStream = NULL; | |
| 81 if(m_pSegmentList) { | |
| 82 delete m_pSegmentList; | |
| 83 } | |
| 84 m_pSegmentList = NULL; | |
| 85 } | |
| 86 FX_INT32 CJBig2_Context::decodeFile(IFX_Pause* pPause) | |
| 87 { | |
| 88 FX_BYTE cFlags; | |
| 89 FX_DWORD dwTemp; | |
| 90 const FX_BYTE fileID[] = {0x97, 0x4A, 0x42, 0x32, 0x0D, 0x0A, 0x1A, 0x0A}; | |
| 91 FX_INT32 nRet; | |
| 92 if(m_pStream->getByteLeft() < 8) { | |
| 93 m_pModule->JBig2_Error("file header too short."); | |
| 94 nRet = JBIG2_ERROR_TOO_SHORT; | 657 nRet = JBIG2_ERROR_TOO_SHORT; |
| 95 goto failed; | 658 goto failed; |
| 96 } | 659 } |
| 97 if(JBIG2_memcmp(m_pStream->getPointer(), fileID, 8) != 0) { | 660 } |
| 98 m_pModule->JBig2_Error("not jbig2 file"); | 661 } |
| 99 nRet = JBIG2_ERROR_FILE_FORMAT; | 662 if ((pSymbolDictDecoder->SDREFAGG == 1) && |
| 100 goto failed; | 663 (pSymbolDictDecoder->SDRTEMPLATE == 0)) { |
| 101 } | 664 for (i = 0; i < 4; i++) { |
| 102 m_pStream->offset(8); | 665 if (m_pStream->read1Byte((FX_BYTE*)&pSymbolDictDecoder->SDRAT[i]) != 0) { |
| 103 if(m_pStream->read1Byte(&cFlags) != 0) { | 666 m_pModule->JBig2_Error( |
| 104 m_pModule->JBig2_Error("file header too short."); | 667 "symbol dictionary segment : data header too short."); |
| 105 nRet = JBIG2_ERROR_TOO_SHORT; | 668 nRet = JBIG2_ERROR_TOO_SHORT; |
| 106 goto failed; | 669 goto failed; |
| 107 } | 670 } |
| 108 if(!(cFlags & 0x02)) { | 671 } |
| 109 if(m_pStream->readInteger(&dwTemp) != 0) { | 672 } |
| 110 m_pModule->JBig2_Error("file header too short."); | 673 if ((m_pStream->readInteger(&pSymbolDictDecoder->SDNUMEXSYMS) != 0) || |
| 674 (m_pStream->readInteger(&pSymbolDictDecoder->SDNUMNEWSYMS) != 0)) { |
| 675 m_pModule->JBig2_Error( |
| 676 "symbol dictionary segment : data header too short."); |
| 677 nRet = JBIG2_ERROR_TOO_SHORT; |
| 678 goto failed; |
| 679 } |
| 680 if (pSymbolDictDecoder->SDNUMEXSYMS > JBIG2_MAX_EXPORT_SYSMBOLS || |
| 681 pSymbolDictDecoder->SDNUMNEWSYMS > JBIG2_MAX_NEW_SYSMBOLS) { |
| 682 m_pModule->JBig2_Error( |
| 683 "symbol dictionary segment : too many export/new symbols."); |
| 684 nRet = JBIG2_ERROR_LIMIT; |
| 685 goto failed; |
| 686 } |
| 687 for (i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { |
| 688 if (!findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i])) { |
| 689 m_pModule->JBig2_Error( |
| 690 "symbol dictionary segment : can't find refered to segments"); |
| 691 nRet = JBIG2_ERROR_FETAL; |
| 692 goto failed; |
| 693 } |
| 694 } |
| 695 pSymbolDictDecoder->SDNUMINSYMS = 0; |
| 696 for (i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { |
| 697 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); |
| 698 if (pSeg->m_cFlags.s.type == 0) { |
| 699 pSymbolDictDecoder->SDNUMINSYMS += pSeg->m_Result.sd->SDNUMEXSYMS; |
| 700 pLRSeg = pSeg; |
| 701 } |
| 702 } |
| 703 if (pSymbolDictDecoder->SDNUMINSYMS == 0) { |
| 704 SDINSYMS = NULL; |
| 705 } else { |
| 706 SDINSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2( |
| 707 sizeof(CJBig2_Image*), pSymbolDictDecoder->SDNUMINSYMS); |
| 708 dwTemp = 0; |
| 709 for (i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { |
| 710 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); |
| 711 if (pSeg->m_cFlags.s.type == 0) { |
| 712 JBIG2_memcpy(SDINSYMS + dwTemp, |
| 713 pSeg->m_Result.sd->SDEXSYMS, |
| 714 pSeg->m_Result.sd->SDNUMEXSYMS * sizeof(CJBig2_Image*)); |
| 715 dwTemp += pSeg->m_Result.sd->SDNUMEXSYMS; |
| 716 } |
| 717 } |
| 718 } |
| 719 pSymbolDictDecoder->SDINSYMS = SDINSYMS; |
| 720 if (pSymbolDictDecoder->SDHUFF == 1) { |
| 721 if ((cSDHUFFDH == 2) || (cSDHUFFDW == 2)) { |
| 722 m_pModule->JBig2_Error( |
| 723 "symbol dictionary segment : SDHUFFDH=2 or SDHUFFDW=2 is not " |
| 724 "permitted."); |
| 725 nRet = JBIG2_ERROR_FETAL; |
| 726 goto failed; |
| 727 } |
| 728 nIndex = 0; |
| 729 if (cSDHUFFDH == 0) { |
| 730 JBIG2_ALLOC( |
| 731 Table_B4, |
| 732 CJBig2_HuffmanTable(HuffmanTable_B4, |
| 733 sizeof(HuffmanTable_B4) / sizeof(JBig2TableLine), |
| 734 HuffmanTable_HTOOB_B4)); |
| 735 pSymbolDictDecoder->SDHUFFDH = Table_B4; |
| 736 } else if (cSDHUFFDH == 1) { |
| 737 JBIG2_ALLOC( |
| 738 Table_B5, |
| 739 CJBig2_HuffmanTable(HuffmanTable_B5, |
| 740 sizeof(HuffmanTable_B5) / sizeof(JBig2TableLine), |
| 741 HuffmanTable_HTOOB_B5)); |
| 742 pSymbolDictDecoder->SDHUFFDH = Table_B5; |
| 743 } else { |
| 744 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
| 745 if (!pSeg) { |
| 746 m_pModule->JBig2_Error( |
| 747 "symbol dictionary segment : SDHUFFDH can't find user supplied " |
| 748 "table."); |
| 749 nRet = JBIG2_ERROR_FETAL; |
| 750 goto failed; |
| 751 } |
| 752 pSymbolDictDecoder->SDHUFFDH = pSeg->m_Result.ht; |
| 753 } |
| 754 if (cSDHUFFDW == 0) { |
| 755 JBIG2_ALLOC( |
| 756 Table_B2, |
| 757 CJBig2_HuffmanTable(HuffmanTable_B2, |
| 758 sizeof(HuffmanTable_B2) / sizeof(JBig2TableLine), |
| 759 HuffmanTable_HTOOB_B2)); |
| 760 pSymbolDictDecoder->SDHUFFDW = Table_B2; |
| 761 } else if (cSDHUFFDW == 1) { |
| 762 JBIG2_ALLOC( |
| 763 Table_B3, |
| 764 CJBig2_HuffmanTable(HuffmanTable_B3, |
| 765 sizeof(HuffmanTable_B3) / sizeof(JBig2TableLine), |
| 766 HuffmanTable_HTOOB_B3)); |
| 767 pSymbolDictDecoder->SDHUFFDW = Table_B3; |
| 768 } else { |
| 769 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
| 770 if (!pSeg) { |
| 771 m_pModule->JBig2_Error( |
| 772 "symbol dictionary segment : SDHUFFDW can't find user supplied " |
| 773 "table."); |
| 774 nRet = JBIG2_ERROR_FETAL; |
| 775 goto failed; |
| 776 } |
| 777 pSymbolDictDecoder->SDHUFFDW = pSeg->m_Result.ht; |
| 778 } |
| 779 if (cSDHUFFBMSIZE == 0) { |
| 780 JBIG2_ALLOC( |
| 781 Table_B1, |
| 782 CJBig2_HuffmanTable(HuffmanTable_B1, |
| 783 sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), |
| 784 HuffmanTable_HTOOB_B1)); |
| 785 pSymbolDictDecoder->SDHUFFBMSIZE = Table_B1; |
| 786 } else { |
| 787 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
| 788 if (!pSeg) { |
| 789 m_pModule->JBig2_Error( |
| 790 "symbol dictionary segment : SDHUFFBMSIZE can't find user supplied " |
| 791 "table."); |
| 792 nRet = JBIG2_ERROR_FETAL; |
| 793 goto failed; |
| 794 } |
| 795 pSymbolDictDecoder->SDHUFFBMSIZE = pSeg->m_Result.ht; |
| 796 } |
| 797 if (pSymbolDictDecoder->SDREFAGG == 1) { |
| 798 if (cSDHUFFAGGINST == 0) { |
| 799 if (!Table_B1) { |
| 800 JBIG2_ALLOC(Table_B1, |
| 801 CJBig2_HuffmanTable( |
| 802 HuffmanTable_B1, |
| 803 sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), |
| 804 HuffmanTable_HTOOB_B1)); |
| 805 } |
| 806 pSymbolDictDecoder->SDHUFFAGGINST = Table_B1; |
| 807 } else { |
| 808 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
| 809 if (!pSeg) { |
| 810 m_pModule->JBig2_Error( |
| 811 "symbol dictionary segment : SDHUFFAGGINST can't find user " |
| 812 "supplied table."); |
| 813 nRet = JBIG2_ERROR_FETAL; |
| 814 goto failed; |
| 815 } |
| 816 pSymbolDictDecoder->SDHUFFAGGINST = pSeg->m_Result.ht; |
| 817 } |
| 818 } |
| 819 } |
| 820 if ((wFlags & 0x0100) && pLRSeg && pLRSeg->m_Result.sd->m_bContextRetained) { |
| 821 if (pSymbolDictDecoder->SDHUFF == 0) { |
| 822 dwTemp = pSymbolDictDecoder->SDTEMPLATE == 0 |
| 823 ? 65536 |
| 824 : pSymbolDictDecoder->SDTEMPLATE == 1 ? 8192 : 1024; |
| 825 gbContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2( |
| 826 sizeof(JBig2ArithCtx), dwTemp); |
| 827 JBIG2_memcpy(gbContext, |
| 828 pLRSeg->m_Result.sd->m_gbContext, |
| 829 sizeof(JBig2ArithCtx) * dwTemp); |
| 830 } |
| 831 if (pSymbolDictDecoder->SDREFAGG == 1) { |
| 832 dwTemp = pSymbolDictDecoder->SDRTEMPLATE ? 1 << 10 : 1 << 13; |
| 833 grContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2( |
| 834 sizeof(JBig2ArithCtx), dwTemp); |
| 835 JBIG2_memcpy(grContext, |
| 836 pLRSeg->m_Result.sd->m_grContext, |
| 837 sizeof(JBig2ArithCtx) * dwTemp); |
| 838 } |
| 839 } else { |
| 840 if (pSymbolDictDecoder->SDHUFF == 0) { |
| 841 dwTemp = pSymbolDictDecoder->SDTEMPLATE == 0 |
| 842 ? 65536 |
| 843 : pSymbolDictDecoder->SDTEMPLATE == 1 ? 8192 : 1024; |
| 844 gbContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2( |
| 845 sizeof(JBig2ArithCtx), dwTemp); |
| 846 JBIG2_memset(gbContext, 0, sizeof(JBig2ArithCtx) * dwTemp); |
| 847 } |
| 848 if (pSymbolDictDecoder->SDREFAGG == 1) { |
| 849 dwTemp = pSymbolDictDecoder->SDRTEMPLATE ? 1 << 10 : 1 << 13; |
| 850 grContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2( |
| 851 sizeof(JBig2ArithCtx), dwTemp); |
| 852 JBIG2_memset(grContext, 0, sizeof(JBig2ArithCtx) * dwTemp); |
| 853 } |
| 854 } |
| 855 pSegment->m_nResultType = JBIG2_SYMBOL_DICT_POINTER; |
| 856 if (pSymbolDictDecoder->SDHUFF == 0) { |
| 857 JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(m_pStream)); |
| 858 pSegment->m_Result.sd = |
| 859 pSymbolDictDecoder->decode_Arith(pArithDecoder, gbContext, grContext); |
| 860 delete pArithDecoder; |
| 861 if (pSegment->m_Result.sd == NULL) { |
| 862 nRet = JBIG2_ERROR_FETAL; |
| 863 goto failed; |
| 864 } |
| 865 m_pStream->alignByte(); |
| 866 m_pStream->offset(2); |
| 867 } else { |
| 868 pSegment->m_Result.sd = pSymbolDictDecoder->decode_Huffman( |
| 869 m_pStream, gbContext, grContext, pPause); |
| 870 if (pSegment->m_Result.sd == NULL) { |
| 871 nRet = JBIG2_ERROR_FETAL; |
| 872 goto failed; |
| 873 } |
| 874 m_pStream->alignByte(); |
| 875 } |
| 876 if (wFlags & 0x0200) { |
| 877 pSegment->m_Result.sd->m_bContextRetained = TRUE; |
| 878 if (pSymbolDictDecoder->SDHUFF == 0) { |
| 879 pSegment->m_Result.sd->m_gbContext = gbContext; |
| 880 } |
| 881 if (pSymbolDictDecoder->SDREFAGG == 1) { |
| 882 pSegment->m_Result.sd->m_grContext = grContext; |
| 883 } |
| 884 bUsed = TRUE; |
| 885 } else { |
| 886 bUsed = FALSE; |
| 887 } |
| 888 delete pSymbolDictDecoder; |
| 889 if (SDINSYMS) { |
| 890 m_pModule->JBig2_Free(SDINSYMS); |
| 891 } |
| 892 if (Table_B1) { |
| 893 delete Table_B1; |
| 894 } |
| 895 if (Table_B2) { |
| 896 delete Table_B2; |
| 897 } |
| 898 if (Table_B3) { |
| 899 delete Table_B3; |
| 900 } |
| 901 if (Table_B4) { |
| 902 delete Table_B4; |
| 903 } |
| 904 if (Table_B5) { |
| 905 delete Table_B5; |
| 906 } |
| 907 if (bUsed == FALSE) { |
| 908 if (gbContext) { |
| 909 m_pModule->JBig2_Free(gbContext); |
| 910 } |
| 911 if (grContext) { |
| 912 m_pModule->JBig2_Free(grContext); |
| 913 } |
| 914 } |
| 915 return JBIG2_SUCCESS; |
| 916 failed: |
| 917 delete pSymbolDictDecoder; |
| 918 if (SDINSYMS) { |
| 919 m_pModule->JBig2_Free(SDINSYMS); |
| 920 } |
| 921 if (Table_B1) { |
| 922 delete Table_B1; |
| 923 } |
| 924 if (Table_B2) { |
| 925 delete Table_B2; |
| 926 } |
| 927 if (Table_B3) { |
| 928 delete Table_B3; |
| 929 } |
| 930 if (Table_B4) { |
| 931 delete Table_B4; |
| 932 } |
| 933 if (Table_B5) { |
| 934 delete Table_B5; |
| 935 } |
| 936 if (gbContext) { |
| 937 m_pModule->JBig2_Free(gbContext); |
| 938 } |
| 939 if (grContext) { |
| 940 m_pModule->JBig2_Free(grContext); |
| 941 } |
| 942 return nRet; |
| 943 } |
| 944 |
| 945 FX_BOOL CJBig2_Context::parseTextRegion(CJBig2_Segment* pSegment) { |
| 946 FX_DWORD dwTemp; |
| 947 FX_WORD wFlags; |
| 948 FX_INT32 i, nIndex, nRet; |
| 949 JBig2RegionInfo ri; |
| 950 CJBig2_Segment* pSeg; |
| 951 CJBig2_Image** SBSYMS = NULL; |
| 952 JBig2HuffmanCode* SBSYMCODES = NULL; |
| 953 FX_BYTE cSBHUFFFS, cSBHUFFDS, cSBHUFFDT, cSBHUFFRDW, cSBHUFFRDH, cSBHUFFRDX, |
| 954 cSBHUFFRDY, cSBHUFFRSIZE; |
| 955 CJBig2_HuffmanTable* Table_B1 = NULL, * Table_B6 = NULL, * Table_B7 = NULL, |
| 956 * Table_B8 = NULL, * Table_B9 = NULL, * Table_B10 = NULL, |
| 957 * Table_B11 = NULL, * Table_B12 = NULL, |
| 958 * Table_B13 = NULL, * Table_B14 = NULL, |
| 959 * Table_B15 = NULL; |
| 960 JBig2ArithCtx* grContext = NULL; |
| 961 CJBig2_ArithDecoder* pArithDecoder; |
| 962 CJBig2_TRDProc* pTRD; |
| 963 JBIG2_ALLOC(pTRD, CJBig2_TRDProc()); |
| 964 if ((parseRegionInfo(&ri) != JBIG2_SUCCESS) || |
| 965 (m_pStream->readShortInteger(&wFlags) != 0)) { |
| 966 m_pModule->JBig2_Error("text region segment : data header too short."); |
| 967 nRet = JBIG2_ERROR_TOO_SHORT; |
| 968 goto failed; |
| 969 } |
| 970 pTRD->SBW = ri.width; |
| 971 pTRD->SBH = ri.height; |
| 972 pTRD->SBHUFF = wFlags & 0x0001; |
| 973 pTRD->SBREFINE = (wFlags >> 1) & 0x0001; |
| 974 dwTemp = (wFlags >> 2) & 0x0003; |
| 975 pTRD->SBSTRIPS = 1 << dwTemp; |
| 976 pTRD->REFCORNER = (JBig2Corner)((wFlags >> 4) & 0x0003); |
| 977 pTRD->TRANSPOSED = (wFlags >> 6) & 0x0001; |
| 978 pTRD->SBCOMBOP = (JBig2ComposeOp)((wFlags >> 7) & 0x0003); |
| 979 pTRD->SBDEFPIXEL = (wFlags >> 9) & 0x0001; |
| 980 pTRD->SBDSOFFSET = (wFlags >> 10) & 0x001f; |
| 981 if (pTRD->SBDSOFFSET >= 0x0010) { |
| 982 pTRD->SBDSOFFSET = pTRD->SBDSOFFSET - 0x0020; |
| 983 } |
| 984 pTRD->SBRTEMPLATE = (wFlags >> 15) & 0x0001; |
| 985 if (pTRD->SBHUFF == 1) { |
| 986 if (m_pStream->readShortInteger(&wFlags) != 0) { |
| 987 m_pModule->JBig2_Error("text region segment : data header too short."); |
| 988 nRet = JBIG2_ERROR_TOO_SHORT; |
| 989 goto failed; |
| 990 } |
| 991 cSBHUFFFS = wFlags & 0x0003; |
| 992 cSBHUFFDS = (wFlags >> 2) & 0x0003; |
| 993 cSBHUFFDT = (wFlags >> 4) & 0x0003; |
| 994 cSBHUFFRDW = (wFlags >> 6) & 0x0003; |
| 995 cSBHUFFRDH = (wFlags >> 8) & 0x0003; |
| 996 cSBHUFFRDX = (wFlags >> 10) & 0x0003; |
| 997 cSBHUFFRDY = (wFlags >> 12) & 0x0003; |
| 998 cSBHUFFRSIZE = (wFlags >> 14) & 0x0001; |
| 999 } |
| 1000 if ((pTRD->SBREFINE == 1) && (pTRD->SBRTEMPLATE == 0)) { |
| 1001 for (i = 0; i < 4; i++) { |
| 1002 if (m_pStream->read1Byte((FX_BYTE*)&pTRD->SBRAT[i]) != 0) { |
| 1003 m_pModule->JBig2_Error("text region segment : data header too short."); |
| 1004 nRet = JBIG2_ERROR_TOO_SHORT; |
| 1005 goto failed; |
| 1006 } |
| 1007 } |
| 1008 } |
| 1009 if (m_pStream->readInteger(&pTRD->SBNUMINSTANCES) != 0) { |
| 1010 m_pModule->JBig2_Error("text region segment : data header too short."); |
| 1011 nRet = JBIG2_ERROR_TOO_SHORT; |
| 1012 goto failed; |
| 1013 } |
| 1014 for (i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { |
| 1015 if (!findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i])) { |
| 1016 m_pModule->JBig2_Error( |
| 1017 "text region segment : can't find refered to segments"); |
| 1018 nRet = JBIG2_ERROR_FETAL; |
| 1019 goto failed; |
| 1020 } |
| 1021 } |
| 1022 pTRD->SBNUMSYMS = 0; |
| 1023 for (i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { |
| 1024 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); |
| 1025 if (pSeg->m_cFlags.s.type == 0) { |
| 1026 pTRD->SBNUMSYMS += pSeg->m_Result.sd->SDNUMEXSYMS; |
| 1027 } |
| 1028 } |
| 1029 if (pTRD->SBNUMSYMS > 0) { |
| 1030 SBSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(sizeof(CJBig2_Image*), |
| 1031 pTRD->SBNUMSYMS); |
| 1032 dwTemp = 0; |
| 1033 for (i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { |
| 1034 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); |
| 1035 if (pSeg->m_cFlags.s.type == 0) { |
| 1036 JBIG2_memcpy(SBSYMS + dwTemp, |
| 1037 pSeg->m_Result.sd->SDEXSYMS, |
| 1038 pSeg->m_Result.sd->SDNUMEXSYMS * sizeof(CJBig2_Image*)); |
| 1039 dwTemp += pSeg->m_Result.sd->SDNUMEXSYMS; |
| 1040 } |
| 1041 } |
| 1042 pTRD->SBSYMS = SBSYMS; |
| 1043 } else { |
| 1044 pTRD->SBSYMS = NULL; |
| 1045 } |
| 1046 if (pTRD->SBHUFF == 1) { |
| 1047 SBSYMCODES = decodeSymbolIDHuffmanTable(m_pStream, pTRD->SBNUMSYMS); |
| 1048 if (SBSYMCODES == NULL) { |
| 1049 m_pModule->JBig2_Error( |
| 1050 "text region segment: symbol ID huffman table decode failure!"); |
| 1051 nRet = JBIG2_ERROR_FETAL; |
| 1052 goto failed; |
| 1053 } |
| 1054 m_pStream->alignByte(); |
| 1055 pTRD->SBSYMCODES = SBSYMCODES; |
| 1056 } else { |
| 1057 dwTemp = 0; |
| 1058 while ((FX_DWORD)(1 << dwTemp) < pTRD->SBNUMSYMS) { |
| 1059 dwTemp++; |
| 1060 } |
| 1061 pTRD->SBSYMCODELEN = (FX_BYTE)dwTemp; |
| 1062 } |
| 1063 if (pTRD->SBHUFF == 1) { |
| 1064 if ((cSBHUFFFS == 2) || (cSBHUFFRDW == 2) || (cSBHUFFRDH == 2) || |
| 1065 (cSBHUFFRDX == 2) || (cSBHUFFRDY == 2)) { |
| 1066 m_pModule->JBig2_Error( |
| 1067 "text region segment : SBHUFFFS=2 or SBHUFFRDW=2 or " |
| 1068 "SBHUFFRDH=2 or SBHUFFRDX=2 or SBHUFFRDY=2 is not permitted"); |
| 1069 nRet = JBIG2_ERROR_FETAL; |
| 1070 goto failed; |
| 1071 } |
| 1072 nIndex = 0; |
| 1073 if (cSBHUFFFS == 0) { |
| 1074 JBIG2_ALLOC( |
| 1075 Table_B6, |
| 1076 CJBig2_HuffmanTable(HuffmanTable_B6, |
| 1077 sizeof(HuffmanTable_B6) / sizeof(JBig2TableLine), |
| 1078 HuffmanTable_HTOOB_B6)); |
| 1079 pTRD->SBHUFFFS = Table_B6; |
| 1080 } else if (cSBHUFFFS == 1) { |
| 1081 JBIG2_ALLOC( |
| 1082 Table_B7, |
| 1083 CJBig2_HuffmanTable(HuffmanTable_B7, |
| 1084 sizeof(HuffmanTable_B7) / sizeof(JBig2TableLine), |
| 1085 HuffmanTable_HTOOB_B7)); |
| 1086 pTRD->SBHUFFFS = Table_B7; |
| 1087 } else { |
| 1088 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
| 1089 if (!pSeg) { |
| 1090 m_pModule->JBig2_Error( |
| 1091 "text region segment : SBHUFFFS can't find user supplied table"); |
| 1092 nRet = JBIG2_ERROR_FETAL; |
| 1093 goto failed; |
| 1094 } |
| 1095 pTRD->SBHUFFFS = pSeg->m_Result.ht; |
| 1096 } |
| 1097 if (cSBHUFFDS == 0) { |
| 1098 JBIG2_ALLOC( |
| 1099 Table_B8, |
| 1100 CJBig2_HuffmanTable(HuffmanTable_B8, |
| 1101 sizeof(HuffmanTable_B8) / sizeof(JBig2TableLine), |
| 1102 HuffmanTable_HTOOB_B8)); |
| 1103 pTRD->SBHUFFDS = Table_B8; |
| 1104 } else if (cSBHUFFDS == 1) { |
| 1105 JBIG2_ALLOC( |
| 1106 Table_B9, |
| 1107 CJBig2_HuffmanTable(HuffmanTable_B9, |
| 1108 sizeof(HuffmanTable_B9) / sizeof(JBig2TableLine), |
| 1109 HuffmanTable_HTOOB_B9)); |
| 1110 pTRD->SBHUFFDS = Table_B9; |
| 1111 } else if (cSBHUFFDS == 2) { |
| 1112 JBIG2_ALLOC( |
| 1113 Table_B10, |
| 1114 CJBig2_HuffmanTable(HuffmanTable_B10, |
| 1115 sizeof(HuffmanTable_B10) / sizeof(JBig2TableLine), |
| 1116 HuffmanTable_HTOOB_B10)); |
| 1117 pTRD->SBHUFFDS = Table_B10; |
| 1118 } else { |
| 1119 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
| 1120 if (!pSeg) { |
| 1121 m_pModule->JBig2_Error( |
| 1122 "text region segment : SBHUFFDS can't find user supplied table"); |
| 1123 nRet = JBIG2_ERROR_FETAL; |
| 1124 goto failed; |
| 1125 } |
| 1126 pTRD->SBHUFFDS = pSeg->m_Result.ht; |
| 1127 } |
| 1128 if (cSBHUFFDT == 0) { |
| 1129 JBIG2_ALLOC( |
| 1130 Table_B11, |
| 1131 CJBig2_HuffmanTable(HuffmanTable_B11, |
| 1132 sizeof(HuffmanTable_B11) / sizeof(JBig2TableLine), |
| 1133 HuffmanTable_HTOOB_B11)); |
| 1134 pTRD->SBHUFFDT = Table_B11; |
| 1135 } else if (cSBHUFFDT == 1) { |
| 1136 JBIG2_ALLOC( |
| 1137 Table_B12, |
| 1138 CJBig2_HuffmanTable(HuffmanTable_B12, |
| 1139 sizeof(HuffmanTable_B12) / sizeof(JBig2TableLine), |
| 1140 HuffmanTable_HTOOB_B12)); |
| 1141 pTRD->SBHUFFDT = Table_B12; |
| 1142 } else if (cSBHUFFDT == 2) { |
| 1143 JBIG2_ALLOC( |
| 1144 Table_B13, |
| 1145 CJBig2_HuffmanTable(HuffmanTable_B13, |
| 1146 sizeof(HuffmanTable_B13) / sizeof(JBig2TableLine), |
| 1147 HuffmanTable_HTOOB_B13)); |
| 1148 pTRD->SBHUFFDT = Table_B13; |
| 1149 } else { |
| 1150 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
| 1151 if (!pSeg) { |
| 1152 m_pModule->JBig2_Error( |
| 1153 "text region segment : SBHUFFDT can't find user supplied table"); |
| 1154 nRet = JBIG2_ERROR_FETAL; |
| 1155 goto failed; |
| 1156 } |
| 1157 pTRD->SBHUFFDT = pSeg->m_Result.ht; |
| 1158 } |
| 1159 if (cSBHUFFRDW == 0) { |
| 1160 JBIG2_ALLOC( |
| 1161 Table_B14, |
| 1162 CJBig2_HuffmanTable(HuffmanTable_B14, |
| 1163 sizeof(HuffmanTable_B14) / sizeof(JBig2TableLine), |
| 1164 HuffmanTable_HTOOB_B14)); |
| 1165 pTRD->SBHUFFRDW = Table_B14; |
| 1166 } else if (cSBHUFFRDW == 1) { |
| 1167 JBIG2_ALLOC( |
| 1168 Table_B15, |
| 1169 CJBig2_HuffmanTable(HuffmanTable_B15, |
| 1170 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), |
| 1171 HuffmanTable_HTOOB_B15)); |
| 1172 pTRD->SBHUFFRDW = Table_B15; |
| 1173 } else { |
| 1174 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
| 1175 if (!pSeg) { |
| 1176 m_pModule->JBig2_Error( |
| 1177 "text region segment : SBHUFFRDW can't find user supplied table"); |
| 1178 nRet = JBIG2_ERROR_FETAL; |
| 1179 goto failed; |
| 1180 } |
| 1181 pTRD->SBHUFFRDW = pSeg->m_Result.ht; |
| 1182 } |
| 1183 if (cSBHUFFRDH == 0) { |
| 1184 if (!Table_B14) { |
| 1185 JBIG2_ALLOC(Table_B14, |
| 1186 CJBig2_HuffmanTable( |
| 1187 HuffmanTable_B14, |
| 1188 sizeof(HuffmanTable_B14) / sizeof(JBig2TableLine), |
| 1189 HuffmanTable_HTOOB_B14)); |
| 1190 } |
| 1191 pTRD->SBHUFFRDH = Table_B14; |
| 1192 } else if (cSBHUFFRDH == 1) { |
| 1193 if (!Table_B15) { |
| 1194 JBIG2_ALLOC(Table_B15, |
| 1195 CJBig2_HuffmanTable( |
| 1196 HuffmanTable_B15, |
| 1197 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), |
| 1198 HuffmanTable_HTOOB_B15)); |
| 1199 } |
| 1200 pTRD->SBHUFFRDH = Table_B15; |
| 1201 } else { |
| 1202 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
| 1203 if (!pSeg) { |
| 1204 m_pModule->JBig2_Error( |
| 1205 "text region segment : SBHUFFRDH can't find user supplied table"); |
| 1206 nRet = JBIG2_ERROR_FETAL; |
| 1207 goto failed; |
| 1208 } |
| 1209 pTRD->SBHUFFRDH = pSeg->m_Result.ht; |
| 1210 } |
| 1211 if (cSBHUFFRDX == 0) { |
| 1212 if (!Table_B14) { |
| 1213 JBIG2_ALLOC(Table_B14, |
| 1214 CJBig2_HuffmanTable( |
| 1215 HuffmanTable_B14, |
| 1216 sizeof(HuffmanTable_B14) / sizeof(JBig2TableLine), |
| 1217 HuffmanTable_HTOOB_B14)); |
| 1218 } |
| 1219 pTRD->SBHUFFRDX = Table_B14; |
| 1220 } else if (cSBHUFFRDX == 1) { |
| 1221 if (!Table_B15) { |
| 1222 JBIG2_ALLOC(Table_B15, |
| 1223 CJBig2_HuffmanTable( |
| 1224 HuffmanTable_B15, |
| 1225 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), |
| 1226 HuffmanTable_HTOOB_B15)); |
| 1227 } |
| 1228 pTRD->SBHUFFRDX = Table_B15; |
| 1229 } else { |
| 1230 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
| 1231 if (!pSeg) { |
| 1232 m_pModule->JBig2_Error( |
| 1233 "text region segment : SBHUFFRDX can't find user supplied table"); |
| 1234 nRet = JBIG2_ERROR_FETAL; |
| 1235 goto failed; |
| 1236 } |
| 1237 pTRD->SBHUFFRDX = pSeg->m_Result.ht; |
| 1238 } |
| 1239 if (cSBHUFFRDY == 0) { |
| 1240 if (!Table_B14) { |
| 1241 JBIG2_ALLOC(Table_B14, |
| 1242 CJBig2_HuffmanTable( |
| 1243 HuffmanTable_B14, |
| 1244 sizeof(HuffmanTable_B14) / sizeof(JBig2TableLine), |
| 1245 HuffmanTable_HTOOB_B14)); |
| 1246 } |
| 1247 pTRD->SBHUFFRDY = Table_B14; |
| 1248 } else if (cSBHUFFRDY == 1) { |
| 1249 if (!Table_B15) { |
| 1250 JBIG2_ALLOC(Table_B15, |
| 1251 CJBig2_HuffmanTable( |
| 1252 HuffmanTable_B15, |
| 1253 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), |
| 1254 HuffmanTable_HTOOB_B15)); |
| 1255 } |
| 1256 pTRD->SBHUFFRDY = Table_B15; |
| 1257 } else { |
| 1258 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
| 1259 if (!pSeg) { |
| 1260 m_pModule->JBig2_Error( |
| 1261 "text region segment : SBHUFFRDY can't find user supplied table"); |
| 1262 nRet = JBIG2_ERROR_FETAL; |
| 1263 goto failed; |
| 1264 } |
| 1265 pTRD->SBHUFFRDY = pSeg->m_Result.ht; |
| 1266 } |
| 1267 if (cSBHUFFRSIZE == 0) { |
| 1268 JBIG2_ALLOC( |
| 1269 Table_B1, |
| 1270 CJBig2_HuffmanTable(HuffmanTable_B1, |
| 1271 sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), |
| 1272 HuffmanTable_HTOOB_B1)); |
| 1273 pTRD->SBHUFFRSIZE = Table_B1; |
| 1274 } else { |
| 1275 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
| 1276 if (!pSeg) { |
| 1277 m_pModule->JBig2_Error( |
| 1278 "text region segment : SBHUFFRSIZE can't find user supplied table"); |
| 1279 nRet = JBIG2_ERROR_FETAL; |
| 1280 goto failed; |
| 1281 } |
| 1282 pTRD->SBHUFFRSIZE = pSeg->m_Result.ht; |
| 1283 } |
| 1284 } |
| 1285 if (pTRD->SBREFINE == 1) { |
| 1286 dwTemp = pTRD->SBRTEMPLATE ? 1 << 10 : 1 << 13; |
| 1287 grContext = |
| 1288 (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2ArithCtx), dwTemp); |
| 1289 JBIG2_memset(grContext, 0, sizeof(JBig2ArithCtx) * dwTemp); |
| 1290 } |
| 1291 if (pTRD->SBHUFF == 0) { |
| 1292 JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(m_pStream)); |
| 1293 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; |
| 1294 pSegment->m_Result.im = pTRD->decode_Arith(pArithDecoder, grContext); |
| 1295 delete pArithDecoder; |
| 1296 if (pSegment->m_Result.im == NULL) { |
| 1297 nRet = JBIG2_ERROR_FETAL; |
| 1298 goto failed; |
| 1299 } |
| 1300 m_pStream->alignByte(); |
| 1301 m_pStream->offset(2); |
| 1302 } else { |
| 1303 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; |
| 1304 pSegment->m_Result.im = pTRD->decode_Huffman(m_pStream, grContext); |
| 1305 if (pSegment->m_Result.im == NULL) { |
| 1306 nRet = JBIG2_ERROR_FETAL; |
| 1307 goto failed; |
| 1308 } |
| 1309 m_pStream->alignByte(); |
| 1310 } |
| 1311 if (pSegment->m_cFlags.s.type != 4) { |
| 1312 if (!m_bBufSpecified) { |
| 1313 JBig2PageInfo* pPageInfo = m_pPageInfoList->getLast(); |
| 1314 if ((pPageInfo->m_bIsStriped == 1) && |
| 1315 (ri.y + ri.height > m_pPage->m_nHeight)) { |
| 1316 m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0); |
| 1317 } |
| 1318 } |
| 1319 m_pPage->composeFrom( |
| 1320 ri.x, ri.y, pSegment->m_Result.im, (JBig2ComposeOp)(ri.flags & 0x03)); |
| 1321 delete pSegment->m_Result.im; |
| 1322 pSegment->m_Result.im = NULL; |
| 1323 } |
| 1324 delete pTRD; |
| 1325 if (SBSYMS) { |
| 1326 m_pModule->JBig2_Free(SBSYMS); |
| 1327 } |
| 1328 if (SBSYMCODES) { |
| 1329 m_pModule->JBig2_Free(SBSYMCODES); |
| 1330 } |
| 1331 if (grContext) { |
| 1332 m_pModule->JBig2_Free(grContext); |
| 1333 } |
| 1334 if (Table_B1) { |
| 1335 delete Table_B1; |
| 1336 } |
| 1337 if (Table_B6) { |
| 1338 delete Table_B6; |
| 1339 } |
| 1340 if (Table_B7) { |
| 1341 delete Table_B7; |
| 1342 } |
| 1343 if (Table_B8) { |
| 1344 delete Table_B8; |
| 1345 } |
| 1346 if (Table_B9) { |
| 1347 delete Table_B9; |
| 1348 } |
| 1349 if (Table_B10) { |
| 1350 delete Table_B10; |
| 1351 } |
| 1352 if (Table_B11) { |
| 1353 delete Table_B11; |
| 1354 } |
| 1355 if (Table_B12) { |
| 1356 delete Table_B12; |
| 1357 } |
| 1358 if (Table_B13) { |
| 1359 delete Table_B13; |
| 1360 } |
| 1361 if (Table_B14) { |
| 1362 delete Table_B14; |
| 1363 } |
| 1364 if (Table_B15) { |
| 1365 delete Table_B15; |
| 1366 } |
| 1367 return JBIG2_SUCCESS; |
| 1368 failed: |
| 1369 delete pTRD; |
| 1370 if (SBSYMS) { |
| 1371 m_pModule->JBig2_Free(SBSYMS); |
| 1372 } |
| 1373 if (SBSYMCODES) { |
| 1374 m_pModule->JBig2_Free(SBSYMCODES); |
| 1375 } |
| 1376 if (grContext) { |
| 1377 m_pModule->JBig2_Free(grContext); |
| 1378 } |
| 1379 if (Table_B1) { |
| 1380 delete Table_B1; |
| 1381 } |
| 1382 if (Table_B6) { |
| 1383 delete Table_B6; |
| 1384 } |
| 1385 if (Table_B7) { |
| 1386 delete Table_B7; |
| 1387 } |
| 1388 if (Table_B8) { |
| 1389 delete Table_B8; |
| 1390 } |
| 1391 if (Table_B9) { |
| 1392 delete Table_B9; |
| 1393 } |
| 1394 if (Table_B10) { |
| 1395 delete Table_B10; |
| 1396 } |
| 1397 if (Table_B11) { |
| 1398 delete Table_B11; |
| 1399 } |
| 1400 if (Table_B12) { |
| 1401 delete Table_B12; |
| 1402 } |
| 1403 if (Table_B13) { |
| 1404 delete Table_B13; |
| 1405 } |
| 1406 if (Table_B14) { |
| 1407 delete Table_B14; |
| 1408 } |
| 1409 if (Table_B15) { |
| 1410 delete Table_B15; |
| 1411 } |
| 1412 return nRet; |
| 1413 } |
| 1414 |
| 1415 FX_BOOL CJBig2_Context::parsePatternDict(CJBig2_Segment* pSegment, |
| 1416 IFX_Pause* pPause) { |
| 1417 FX_DWORD dwTemp; |
| 1418 FX_BYTE cFlags; |
| 1419 JBig2ArithCtx* gbContext; |
| 1420 CJBig2_ArithDecoder* pArithDecoder; |
| 1421 CJBig2_PDDProc* pPDD; |
| 1422 FX_INT32 nRet; |
| 1423 JBIG2_ALLOC(pPDD, CJBig2_PDDProc()); |
| 1424 if ((m_pStream->read1Byte(&cFlags) != 0) || |
| 1425 (m_pStream->read1Byte(&pPDD->HDPW) != 0) || |
| 1426 (m_pStream->read1Byte(&pPDD->HDPH) != 0) || |
| 1427 (m_pStream->readInteger(&pPDD->GRAYMAX) != 0)) { |
| 1428 m_pModule->JBig2_Error( |
| 1429 "pattern dictionary segment : data header too short."); |
| 1430 nRet = JBIG2_ERROR_TOO_SHORT; |
| 1431 goto failed; |
| 1432 } |
| 1433 if (pPDD->GRAYMAX > JBIG2_MAX_PATTERN_INDEX) { |
| 1434 m_pModule->JBig2_Error("pattern dictionary segment : too max gray max."); |
| 1435 nRet = JBIG2_ERROR_LIMIT; |
| 1436 goto failed; |
| 1437 } |
| 1438 pPDD->HDMMR = cFlags & 0x01; |
| 1439 pPDD->HDTEMPLATE = (cFlags >> 1) & 0x03; |
| 1440 pSegment->m_nResultType = JBIG2_PATTERN_DICT_POINTER; |
| 1441 if (pPDD->HDMMR == 0) { |
| 1442 dwTemp = |
| 1443 pPDD->HDTEMPLATE == 0 ? 65536 : pPDD->HDTEMPLATE == 1 ? 8192 : 1024; |
| 1444 gbContext = |
| 1445 (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2ArithCtx), dwTemp); |
| 1446 JBIG2_memset(gbContext, 0, sizeof(JBig2ArithCtx) * dwTemp); |
| 1447 JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(m_pStream)); |
| 1448 pSegment->m_Result.pd = |
| 1449 pPDD->decode_Arith(pArithDecoder, gbContext, pPause); |
| 1450 delete pArithDecoder; |
| 1451 if (pSegment->m_Result.pd == NULL) { |
| 1452 m_pModule->JBig2_Free(gbContext); |
| 1453 nRet = JBIG2_ERROR_FETAL; |
| 1454 goto failed; |
| 1455 } |
| 1456 m_pModule->JBig2_Free(gbContext); |
| 1457 m_pStream->alignByte(); |
| 1458 m_pStream->offset(2); |
| 1459 } else { |
| 1460 pSegment->m_Result.pd = pPDD->decode_MMR(m_pStream, pPause); |
| 1461 if (pSegment->m_Result.pd == NULL) { |
| 1462 nRet = JBIG2_ERROR_FETAL; |
| 1463 goto failed; |
| 1464 } |
| 1465 m_pStream->alignByte(); |
| 1466 } |
| 1467 delete pPDD; |
| 1468 return JBIG2_SUCCESS; |
| 1469 failed: |
| 1470 delete pPDD; |
| 1471 return nRet; |
| 1472 } |
| 1473 FX_BOOL CJBig2_Context::parseHalftoneRegion(CJBig2_Segment* pSegment, |
| 1474 IFX_Pause* pPause) { |
| 1475 FX_DWORD dwTemp; |
| 1476 FX_BYTE cFlags; |
| 1477 JBig2RegionInfo ri; |
| 1478 CJBig2_Segment* pSeg; |
| 1479 CJBig2_PatternDict* pPatternDict; |
| 1480 JBig2ArithCtx* gbContext; |
| 1481 CJBig2_ArithDecoder* pArithDecoder; |
| 1482 CJBig2_HTRDProc* pHRD; |
| 1483 FX_INT32 nRet; |
| 1484 JBIG2_ALLOC(pHRD, CJBig2_HTRDProc()); |
| 1485 if ((parseRegionInfo(&ri) != JBIG2_SUCCESS) || |
| 1486 (m_pStream->read1Byte(&cFlags) != 0) || |
| 1487 (m_pStream->readInteger(&pHRD->HGW) != 0) || |
| 1488 (m_pStream->readInteger(&pHRD->HGH) != 0) || |
| 1489 (m_pStream->readInteger((FX_DWORD*)&pHRD->HGX) != 0) || |
| 1490 (m_pStream->readInteger((FX_DWORD*)&pHRD->HGY) != 0) || |
| 1491 (m_pStream->readShortInteger(&pHRD->HRX) != 0) || |
| 1492 (m_pStream->readShortInteger(&pHRD->HRY) != 0)) { |
| 1493 m_pModule->JBig2_Error("halftone region segment : data header too short."); |
| 1494 nRet = JBIG2_ERROR_TOO_SHORT; |
| 1495 goto failed; |
| 1496 } |
| 1497 pHRD->HBW = ri.width; |
| 1498 pHRD->HBH = ri.height; |
| 1499 pHRD->HMMR = cFlags & 0x01; |
| 1500 pHRD->HTEMPLATE = (cFlags >> 1) & 0x03; |
| 1501 pHRD->HENABLESKIP = (cFlags >> 3) & 0x01; |
| 1502 pHRD->HCOMBOP = (JBig2ComposeOp)((cFlags >> 4) & 0x07); |
| 1503 pHRD->HDEFPIXEL = (cFlags >> 7) & 0x01; |
| 1504 if (pSegment->m_nReferred_to_segment_count != 1) { |
| 1505 m_pModule->JBig2_Error( |
| 1506 "halftone region segment : refered to segment count not equals 1"); |
| 1507 nRet = JBIG2_ERROR_FETAL; |
| 1508 goto failed; |
| 1509 } |
| 1510 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[0]); |
| 1511 if ((pSeg == NULL) || (pSeg->m_cFlags.s.type != 16)) { |
| 1512 m_pModule->JBig2_Error( |
| 1513 "halftone region segment : refered to segment is not pattern dict"); |
| 1514 nRet = JBIG2_ERROR_FETAL; |
| 1515 goto failed; |
| 1516 } |
| 1517 pPatternDict = pSeg->m_Result.pd; |
| 1518 if ((pPatternDict == NULL) || (pPatternDict->NUMPATS == 0)) { |
| 1519 m_pModule->JBig2_Error("halftone region segment : has no patterns input"); |
| 1520 nRet = JBIG2_ERROR_FETAL; |
| 1521 goto failed; |
| 1522 } |
| 1523 pHRD->HNUMPATS = pPatternDict->NUMPATS; |
| 1524 pHRD->HPATS = pPatternDict->HDPATS; |
| 1525 pHRD->HPW = pPatternDict->HDPATS[0]->m_nWidth; |
| 1526 pHRD->HPH = pPatternDict->HDPATS[0]->m_nHeight; |
| 1527 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; |
| 1528 if (pHRD->HMMR == 0) { |
| 1529 dwTemp = pHRD->HTEMPLATE == 0 ? 65536 : pHRD->HTEMPLATE == 1 ? 8192 : 1024; |
| 1530 gbContext = |
| 1531 (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2ArithCtx), dwTemp); |
| 1532 JBIG2_memset(gbContext, 0, sizeof(JBig2ArithCtx) * dwTemp); |
| 1533 JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(m_pStream)); |
| 1534 pSegment->m_Result.im = |
| 1535 pHRD->decode_Arith(pArithDecoder, gbContext, pPause); |
| 1536 delete pArithDecoder; |
| 1537 if (pSegment->m_Result.im == NULL) { |
| 1538 m_pModule->JBig2_Free(gbContext); |
| 1539 nRet = JBIG2_ERROR_FETAL; |
| 1540 goto failed; |
| 1541 } |
| 1542 m_pModule->JBig2_Free(gbContext); |
| 1543 m_pStream->alignByte(); |
| 1544 m_pStream->offset(2); |
| 1545 } else { |
| 1546 pSegment->m_Result.im = pHRD->decode_MMR(m_pStream, pPause); |
| 1547 if (pSegment->m_Result.im == NULL) { |
| 1548 nRet = JBIG2_ERROR_FETAL; |
| 1549 goto failed; |
| 1550 } |
| 1551 m_pStream->alignByte(); |
| 1552 } |
| 1553 if (pSegment->m_cFlags.s.type != 20) { |
| 1554 if (!m_bBufSpecified) { |
| 1555 JBig2PageInfo* pPageInfo = m_pPageInfoList->getLast(); |
| 1556 if ((pPageInfo->m_bIsStriped == 1) && |
| 1557 (ri.y + ri.height > m_pPage->m_nHeight)) { |
| 1558 m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0); |
| 1559 } |
| 1560 } |
| 1561 m_pPage->composeFrom( |
| 1562 ri.x, ri.y, pSegment->m_Result.im, (JBig2ComposeOp)(ri.flags & 0x03)); |
| 1563 delete pSegment->m_Result.im; |
| 1564 pSegment->m_Result.im = NULL; |
| 1565 } |
| 1566 delete pHRD; |
| 1567 return JBIG2_SUCCESS; |
| 1568 failed: |
| 1569 delete pHRD; |
| 1570 return nRet; |
| 1571 } |
| 1572 |
| 1573 FX_BOOL CJBig2_Context::parseGenericRegion(CJBig2_Segment* pSegment, |
| 1574 IFX_Pause* pPause) { |
| 1575 FX_DWORD dwTemp; |
| 1576 FX_BYTE cFlags; |
| 1577 FX_INT32 i, nRet; |
| 1578 if (m_pGRD == NULL) { |
| 1579 JBIG2_ALLOC(m_pGRD, CJBig2_GRDProc()); |
| 1580 if ((parseRegionInfo(&m_ri) != JBIG2_SUCCESS) || |
| 1581 (m_pStream->read1Byte(&cFlags) != 0)) { |
| 1582 m_pModule->JBig2_Error("generic region segment : data header too short."); |
| 1583 nRet = JBIG2_ERROR_TOO_SHORT; |
| 1584 goto failed; |
| 1585 } |
| 1586 if (m_ri.height < 0 || m_ri.width < 0) { |
| 1587 m_pModule->JBig2_Error("generic region segment : wrong data."); |
| 1588 nRet = JBIG2_FAILED; |
| 1589 goto failed; |
| 1590 } |
| 1591 m_pGRD->GBW = m_ri.width; |
| 1592 m_pGRD->GBH = m_ri.height; |
| 1593 m_pGRD->MMR = cFlags & 0x01; |
| 1594 m_pGRD->GBTEMPLATE = (cFlags >> 1) & 0x03; |
| 1595 m_pGRD->TPGDON = (cFlags >> 3) & 0x01; |
| 1596 if (m_pGRD->MMR == 0) { |
| 1597 if (m_pGRD->GBTEMPLATE == 0) { |
| 1598 for (i = 0; i < 8; i++) { |
| 1599 if (m_pStream->read1Byte((FX_BYTE*)&m_pGRD->GBAT[i]) != 0) { |
| 1600 m_pModule->JBig2_Error( |
| 1601 "generic region segment : data header too short."); |
| 111 nRet = JBIG2_ERROR_TOO_SHORT; | 1602 nRet = JBIG2_ERROR_TOO_SHORT; |
| 112 goto failed; | 1603 goto failed; |
| 1604 } |
| 113 } | 1605 } |
| 114 if(dwTemp > 0) { | 1606 } else { |
| 115 delete m_pPageInfoList; | 1607 for (i = 0; i < 2; i++) { |
| 116 JBIG2_ALLOC(m_pPageInfoList, CJBig2_List<JBig2PageInfo>(dwTemp)); | 1608 if (m_pStream->read1Byte((FX_BYTE*)&m_pGRD->GBAT[i]) != 0) { |
| 117 } | 1609 m_pModule->JBig2_Error( |
| 118 } | 1610 "generic region segment : data header too short."); |
| 119 if(cFlags & 0x01) { | |
| 120 m_nStreamType = JBIG2_SQUENTIAL_STREAM; | |
| 121 return decode_SquentialOrgnazation(pPause); | |
| 122 } else { | |
| 123 m_nStreamType = JBIG2_RANDOM_STREAM; | |
| 124 return decode_RandomOrgnazation_FirstPage(pPause); | |
| 125 } | |
| 126 failed: | |
| 127 return nRet; | |
| 128 } | |
| 129 FX_INT32 CJBig2_Context::decode_SquentialOrgnazation(IFX_Pause* pPause) | |
| 130 { | |
| 131 FX_INT32 nRet; | |
| 132 if(m_pStream->getByteLeft() > 0) { | |
| 133 while(m_pStream->getByteLeft() >= JBIG2_MIN_SEGMENT_SIZE) { | |
| 134 if(m_pSegment == NULL) { | |
| 135 JBIG2_ALLOC(m_pSegment, CJBig2_Segment()); | |
| 136 nRet = parseSegmentHeader(m_pSegment); | |
| 137 if(nRet != JBIG2_SUCCESS) { | |
| 138 delete m_pSegment; | |
| 139 m_pSegment = NULL; | |
| 140 return nRet; | |
| 141 } | |
| 142 m_dwOffset = m_pStream->getOffset(); | |
| 143 } | |
| 144 nRet = parseSegmentData(m_pSegment, pPause); | |
| 145 if(m_ProcessiveStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) { | |
| 146 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; | |
| 147 m_PauseStep = 2; | |
| 148 return JBIG2_SUCCESS; | |
| 149 } | |
| 150 if((nRet == JBIG2_END_OF_PAGE) || (nRet == JBIG2_END_OF_FILE)) { | |
| 151 delete m_pSegment; | |
| 152 m_pSegment = NULL; | |
| 153 break; | |
| 154 } else if(nRet != JBIG2_SUCCESS) { | |
| 155 delete m_pSegment; | |
| 156 m_pSegment = NULL; | |
| 157 return nRet; | |
| 158 } | |
| 159 m_pSegmentList->addItem(m_pSegment); | |
| 160 if(m_pSegment->m_dwData_length != 0xffffffff) { | |
| 161 m_dwOffset = m_dwOffset + m_pSegment->m_dwData_length; | |
| 162 m_pStream->setOffset(m_dwOffset); | |
| 163 } else { | |
| 164 m_pStream->offset(4); | |
| 165 } | |
| 166 OutputBitmap(m_pPage); | |
| 167 m_pSegment = NULL; | |
| 168 if(m_pStream->getByteLeft() > 0 && m_pPage && pPause && pPause->Need
ToPauseNow()) { | |
| 169 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; | |
| 170 m_PauseStep = 2; | |
| 171 return JBIG2_SUCCESS; | |
| 172 } | |
| 173 } | |
| 174 } else { | |
| 175 return JBIG2_END_OF_FILE; | |
| 176 } | |
| 177 return JBIG2_SUCCESS; | |
| 178 } | |
| 179 FX_INT32 CJBig2_Context::decode_EmbedOrgnazation(IFX_Pause* pPause) | |
| 180 { | |
| 181 return decode_SquentialOrgnazation(pPause); | |
| 182 } | |
| 183 FX_INT32 CJBig2_Context::decode_RandomOrgnazation_FirstPage(IFX_Pause* pPause) | |
| 184 { | |
| 185 CJBig2_Segment *pSegment; | |
| 186 FX_INT32 nRet; | |
| 187 while(m_pStream->getByteLeft() > JBIG2_MIN_SEGMENT_SIZE) { | |
| 188 JBIG2_ALLOC(pSegment, CJBig2_Segment()); | |
| 189 nRet = parseSegmentHeader(pSegment); | |
| 190 if(nRet != JBIG2_SUCCESS) { | |
| 191 delete pSegment; | |
| 192 return nRet; | |
| 193 } else if(pSegment->m_cFlags.s.type == 51) { | |
| 194 delete pSegment; | |
| 195 break; | |
| 196 } | |
| 197 m_pSegmentList->addItem(pSegment); | |
| 198 if(pPause && m_pPause && pPause->NeedToPauseNow()) { | |
| 199 m_PauseStep = 3; | |
| 200 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; | |
| 201 return JBIG2_SUCCESS; | |
| 202 } | |
| 203 } | |
| 204 m_nSegmentDecoded = 0; | |
| 205 return decode_RandomOrgnazation(pPause); | |
| 206 } | |
| 207 FX_INT32 CJBig2_Context::decode_RandomOrgnazation(IFX_Pause* pPause) | |
| 208 { | |
| 209 FX_INT32 nRet; | |
| 210 for(; m_nSegmentDecoded < m_pSegmentList->getLength(); m_nSegmentDecoded++)
{ | |
| 211 nRet = parseSegmentData(m_pSegmentList->getAt(m_nSegmentDecoded), pPause
); | |
| 212 if((nRet == JBIG2_END_OF_PAGE) || (nRet == JBIG2_END_OF_FILE)) { | |
| 213 break; | |
| 214 } else if(nRet != JBIG2_SUCCESS) { | |
| 215 return nRet; | |
| 216 } | |
| 217 if(m_pPage && pPause && pPause->NeedToPauseNow()) { | |
| 218 m_PauseStep = 4; | |
| 219 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; | |
| 220 return JBIG2_SUCCESS; | |
| 221 } | |
| 222 } | |
| 223 return JBIG2_SUCCESS; | |
| 224 } | |
| 225 FX_INT32 CJBig2_Context::getFirstPage(FX_BYTE *pBuf, FX_INT32 width, FX_INT32 he
ight, FX_INT32 stride, IFX_Pause* pPause) | |
| 226 { | |
| 227 FX_INT32 nRet = 0; | |
| 228 if(m_pGlobalContext) { | |
| 229 nRet = m_pGlobalContext->decode_EmbedOrgnazation(pPause); | |
| 230 if(nRet != JBIG2_SUCCESS) { | |
| 231 m_ProcessiveStatus = FXCODEC_STATUS_ERROR; | |
| 232 return nRet; | |
| 233 } | |
| 234 } | |
| 235 m_bFirstPage = TRUE; | |
| 236 m_PauseStep = 0; | |
| 237 if(m_pPage) { | |
| 238 delete m_pPage; | |
| 239 } | |
| 240 JBIG2_ALLOC(m_pPage, CJBig2_Image(width, height, stride, pBuf)); | |
| 241 m_bBufSpecified = TRUE; | |
| 242 if(m_pPage && pPause && pPause->NeedToPauseNow()) { | |
| 243 m_PauseStep = 1; | |
| 244 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; | |
| 245 return nRet; | |
| 246 } | |
| 247 int ret = Continue(pPause); | |
| 248 return ret; | |
| 249 } | |
| 250 FX_INT32 CJBig2_Context::Continue(IFX_Pause* pPause) | |
| 251 { | |
| 252 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_READY; | |
| 253 FX_INT32 nRet; | |
| 254 if(m_PauseStep <= 1) { | |
| 255 switch(m_nStreamType) { | |
| 256 case JBIG2_FILE_STREAM: | |
| 257 nRet = decodeFile(pPause); | |
| 258 break; | |
| 259 case JBIG2_SQUENTIAL_STREAM: | |
| 260 nRet = decode_SquentialOrgnazation(pPause); | |
| 261 break; | |
| 262 case JBIG2_RANDOM_STREAM: | |
| 263 if(m_bFirstPage) { | |
| 264 nRet = decode_RandomOrgnazation_FirstPage(pPause); | |
| 265 } else { | |
| 266 nRet = decode_RandomOrgnazation(pPause); | |
| 267 } | |
| 268 break; | |
| 269 case JBIG2_EMBED_STREAM: | |
| 270 nRet = decode_EmbedOrgnazation(pPause); | |
| 271 break; | |
| 272 default: | |
| 273 m_ProcessiveStatus = FXCODEC_STATUS_ERROR; | |
| 274 return JBIG2_ERROR_STREAM_TYPE; | |
| 275 } | |
| 276 } else if(m_PauseStep == 2) { | |
| 277 nRet = decode_SquentialOrgnazation(pPause); | |
| 278 } else if(m_PauseStep == 3) { | |
| 279 nRet = decode_RandomOrgnazation_FirstPage(pPause); | |
| 280 } else if(m_PauseStep == 4) { | |
| 281 nRet = decode_RandomOrgnazation(pPause); | |
| 282 } else if(m_PauseStep == 5) { | |
| 283 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_FINISH; | |
| 284 return JBIG2_SUCCESS; | |
| 285 } | |
| 286 if(m_ProcessiveStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) { | |
| 287 return nRet; | |
| 288 } | |
| 289 m_PauseStep = 5; | |
| 290 if(!m_bBufSpecified && nRet == JBIG2_SUCCESS) { | |
| 291 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_FINISH; | |
| 292 return JBIG2_SUCCESS; | |
| 293 } | |
| 294 if(nRet == JBIG2_SUCCESS) { | |
| 295 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_FINISH; | |
| 296 } else { | |
| 297 m_ProcessiveStatus = FXCODEC_STATUS_ERROR; | |
| 298 } | |
| 299 return nRet; | |
| 300 } | |
| 301 FX_INT32 CJBig2_Context::getNextPage(FX_BYTE *pBuf, FX_INT32 width, FX_INT32 hei
ght, FX_INT32 stride, IFX_Pause* pPause) | |
| 302 { | |
| 303 FX_INT32 nRet = JBIG2_ERROR_STREAM_TYPE; | |
| 304 m_bFirstPage = FALSE; | |
| 305 m_PauseStep = 0; | |
| 306 if(m_pPage) { | |
| 307 delete m_pPage; | |
| 308 } | |
| 309 JBIG2_ALLOC(m_pPage, CJBig2_Image(width, height, stride, pBuf)); | |
| 310 m_bBufSpecified = TRUE; | |
| 311 if(m_pPage && pPause && pPause->NeedToPauseNow()) { | |
| 312 m_PauseStep = 1; | |
| 313 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; | |
| 314 return nRet; | |
| 315 } | |
| 316 return Continue(pPause); | |
| 317 switch(m_nStreamType) { | |
| 318 case JBIG2_FILE_STREAM: | |
| 319 nRet = decodeFile(pPause); | |
| 320 break; | |
| 321 case JBIG2_SQUENTIAL_STREAM: | |
| 322 nRet = decode_SquentialOrgnazation(pPause); | |
| 323 break; | |
| 324 case JBIG2_RANDOM_STREAM: | |
| 325 nRet = decode_RandomOrgnazation(pPause); | |
| 326 break; | |
| 327 case JBIG2_EMBED_STREAM: | |
| 328 nRet = decode_EmbedOrgnazation(pPause); | |
| 329 break; | |
| 330 default: | |
| 331 return JBIG2_ERROR_STREAM_TYPE; | |
| 332 } | |
| 333 return nRet; | |
| 334 } | |
| 335 FX_INT32 CJBig2_Context::getFirstPage(CJBig2_Image **image, IFX_Pause* pPause) | |
| 336 { | |
| 337 FX_INT32 nRet; | |
| 338 m_bFirstPage = TRUE; | |
| 339 m_PauseStep = 0; | |
| 340 if(m_pGlobalContext) { | |
| 341 nRet = m_pGlobalContext->decode_EmbedOrgnazation(pPause); | |
| 342 if(nRet != JBIG2_SUCCESS) { | |
| 343 return nRet; | |
| 344 } | |
| 345 } | |
| 346 m_bBufSpecified = FALSE; | |
| 347 return Continue(pPause); | |
| 348 } | |
| 349 FX_INT32 CJBig2_Context::getNextPage(CJBig2_Image **image, IFX_Pause* pPause) | |
| 350 { | |
| 351 FX_INT32 nRet; | |
| 352 m_bBufSpecified = FALSE; | |
| 353 m_bFirstPage = FALSE; | |
| 354 m_PauseStep = 0; | |
| 355 switch(m_nStreamType) { | |
| 356 case JBIG2_FILE_STREAM: | |
| 357 nRet = decodeFile(pPause); | |
| 358 break; | |
| 359 case JBIG2_SQUENTIAL_STREAM: | |
| 360 nRet = decode_SquentialOrgnazation(pPause); | |
| 361 break; | |
| 362 case JBIG2_RANDOM_STREAM: | |
| 363 nRet = decode_RandomOrgnazation(pPause); | |
| 364 break; | |
| 365 case JBIG2_EMBED_STREAM: | |
| 366 nRet = decode_EmbedOrgnazation(pPause); | |
| 367 break; | |
| 368 default: | |
| 369 return JBIG2_ERROR_STREAM_TYPE; | |
| 370 } | |
| 371 if(nRet == JBIG2_SUCCESS) { | |
| 372 *image = m_pPage; | |
| 373 m_pPage = NULL; | |
| 374 return JBIG2_SUCCESS; | |
| 375 } | |
| 376 return nRet; | |
| 377 } | |
| 378 CJBig2_Segment *CJBig2_Context::findSegmentByNumber(FX_DWORD dwNumber) | |
| 379 { | |
| 380 CJBig2_Segment *pSeg; | |
| 381 FX_INT32 i; | |
| 382 if(m_pGlobalContext) { | |
| 383 pSeg = m_pGlobalContext->findSegmentByNumber(dwNumber); | |
| 384 if(pSeg) { | |
| 385 return pSeg; | |
| 386 } | |
| 387 } | |
| 388 for(i = 0; i < m_pSegmentList->getLength(); i++) { | |
| 389 pSeg = m_pSegmentList->getAt(i); | |
| 390 if(pSeg->m_dwNumber == dwNumber) { | |
| 391 return pSeg; | |
| 392 } | |
| 393 } | |
| 394 return NULL; | |
| 395 } | |
| 396 CJBig2_Segment *CJBig2_Context::findReferredSegmentByTypeAndIndex(CJBig2_Segment
*pSegment, | |
| 397 FX_BYTE cType, FX_INT32 nIndex) | |
| 398 { | |
| 399 CJBig2_Segment *pSeg; | |
| 400 FX_INT32 i, count; | |
| 401 count = 0; | |
| 402 for(i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | |
| 403 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); | |
| 404 if(pSeg && pSeg->m_cFlags.s.type == cType) { | |
| 405 if(count == nIndex) { | |
| 406 return pSeg; | |
| 407 } else { | |
| 408 count ++; | |
| 409 } | |
| 410 } | |
| 411 } | |
| 412 return NULL; | |
| 413 } | |
| 414 FX_INT32 CJBig2_Context::parseSegmentHeader(CJBig2_Segment *pSegment) | |
| 415 { | |
| 416 FX_BYTE cSSize, cPSize; | |
| 417 FX_BYTE cTemp; | |
| 418 FX_WORD wTemp; | |
| 419 FX_DWORD dwTemp; | |
| 420 if((m_pStream->readInteger(&pSegment->m_dwNumber) != 0) | |
| 421 || (m_pStream->read1Byte(&pSegment->m_cFlags.c) != 0)) { | |
| 422 goto failed; | |
| 423 } | |
| 424 cTemp = m_pStream->getCurByte(); | |
| 425 if((cTemp >> 5) == 7) { | |
| 426 if(m_pStream->readInteger((FX_DWORD*)&pSegment->m_nReferred_to_segment_c
ount) != 0) { | |
| 427 goto failed; | |
| 428 } | |
| 429 pSegment->m_nReferred_to_segment_count &= 0x1fffffff; | |
| 430 if (pSegment->m_nReferred_to_segment_count > JBIG2_MAX_REFERRED_SEGMENT_
COUNT) { | |
| 431 m_pModule->JBig2_Error("Too many referred segments."); | |
| 432 return JBIG2_ERROR_LIMIT; | |
| 433 } | |
| 434 dwTemp = 5 + 4 + (pSegment->m_nReferred_to_segment_count + 1) / 8; | |
| 435 } else { | |
| 436 if(m_pStream->read1Byte(&cTemp) != 0) { | |
| 437 goto failed; | |
| 438 } | |
| 439 pSegment->m_nReferred_to_segment_count = cTemp >> 5; | |
| 440 dwTemp = 5 + 1; | |
| 441 } | |
| 442 cSSize = pSegment->m_dwNumber > 65536 ? 4 : pSegment->m_dwNumber > 256 ? 2 :
1; | |
| 443 cPSize = pSegment->m_cFlags.s.page_association_size ? 4 : 1; | |
| 444 if(pSegment->m_nReferred_to_segment_count) { | |
| 445 pSegment->m_pReferred_to_segment_numbers = (FX_DWORD*)m_pModule->JBig2_M
alloc2( | |
| 446 sizeof(FX_DWORD), pSegment->m_nReferred_to_segment_count); | |
| 447 for(FX_INT32 i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | |
| 448 switch(cSSize) { | |
| 449 case 1: | |
| 450 if(m_pStream->read1Byte(&cTemp) != 0) { | |
| 451 goto failed; | |
| 452 } | |
| 453 pSegment->m_pReferred_to_segment_numbers[i] = cTemp; | |
| 454 break; | |
| 455 case 2: | |
| 456 if(m_pStream->readShortInteger(&wTemp) != 0) { | |
| 457 goto failed; | |
| 458 } | |
| 459 pSegment->m_pReferred_to_segment_numbers[i] = wTemp; | |
| 460 break; | |
| 461 case 4: | |
| 462 if(m_pStream->readInteger(&dwTemp) != 0) { | |
| 463 goto failed; | |
| 464 } | |
| 465 pSegment->m_pReferred_to_segment_numbers[i] = dwTemp; | |
| 466 break; | |
| 467 } | |
| 468 if (pSegment->m_pReferred_to_segment_numbers[i] >= pSegment->m_dwNum
ber) { | |
| 469 m_pModule->JBig2_Error("The referred segment number is greater t
han this segment number."); | |
| 470 goto failed; | |
| 471 } | |
| 472 } | |
| 473 } | |
| 474 if(cPSize == 1) { | |
| 475 if(m_pStream->read1Byte(&cTemp) != 0) { | |
| 476 goto failed; | |
| 477 } | |
| 478 pSegment->m_dwPage_association = cTemp; | |
| 479 } else { | |
| 480 if(m_pStream->readInteger(&pSegment->m_dwPage_association) != 0) { | |
| 481 goto failed; | |
| 482 } | |
| 483 } | |
| 484 if(m_pStream->readInteger(&pSegment->m_dwData_length) != 0) { | |
| 485 goto failed; | |
| 486 } | |
| 487 pSegment->m_pData = m_pStream->getPointer(); | |
| 488 pSegment->m_State = JBIG2_SEGMENT_DATA_UNPARSED; | |
| 489 return JBIG2_SUCCESS; | |
| 490 failed: | |
| 491 m_pModule->JBig2_Error("header too short."); | |
| 492 return JBIG2_ERROR_TOO_SHORT; | |
| 493 } | |
| 494 FX_INT32 CJBig2_Context::parseSegmentData(CJBig2_Segment *pSegment, IFX_Pause* p
Pause) | |
| 495 { | |
| 496 FX_INT32 ret = ProcessiveParseSegmentData(pSegment, pPause); | |
| 497 while(m_ProcessiveStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE && m_pStream
->getByteLeft() > 0) { | |
| 498 ret = ProcessiveParseSegmentData(pSegment, pPause); | |
| 499 } | |
| 500 return ret; | |
| 501 } | |
| 502 FX_INT32 CJBig2_Context::ProcessiveParseSegmentData(CJBig2_Segment *pSegment, IF
X_Pause* pPause) | |
| 503 { | |
| 504 switch(pSegment->m_cFlags.s.type) { | |
| 505 case 0: | |
| 506 return parseSymbolDict(pSegment, pPause); | |
| 507 case 4: | |
| 508 case 6: | |
| 509 case 7: | |
| 510 if(m_nState == JBIG2_OUT_OF_PAGE) { | |
| 511 goto failed2; | |
| 512 } else { | |
| 513 return parseTextRegion(pSegment); | |
| 514 } | |
| 515 case 16: | |
| 516 return parsePatternDict(pSegment, pPause); | |
| 517 case 20: | |
| 518 case 22: | |
| 519 case 23: | |
| 520 if(m_nState == JBIG2_OUT_OF_PAGE) { | |
| 521 goto failed2; | |
| 522 } else { | |
| 523 return parseHalftoneRegion(pSegment, pPause); | |
| 524 } | |
| 525 case 36: | |
| 526 case 38: | |
| 527 case 39: | |
| 528 if(m_nState == JBIG2_OUT_OF_PAGE) { | |
| 529 goto failed2; | |
| 530 } else { | |
| 531 return parseGenericRegion(pSegment, pPause); | |
| 532 } | |
| 533 case 40: | |
| 534 case 42: | |
| 535 case 43: | |
| 536 if(m_nState == JBIG2_OUT_OF_PAGE) { | |
| 537 goto failed2; | |
| 538 } else { | |
| 539 return parseGenericRefinementRegion(pSegment); | |
| 540 } | |
| 541 case 48: { | |
| 542 FX_WORD wTemp; | |
| 543 JBig2PageInfo *pPageInfo; | |
| 544 JBIG2_ALLOC(pPageInfo, JBig2PageInfo); | |
| 545 if((m_pStream->readInteger(&pPageInfo->m_dwWidth) != 0) | |
| 546 || (m_pStream->readInteger(&pPageInfo->m_dwHeight) != 0) | |
| 547 || (m_pStream->readInteger(&pPageInfo->m_dwResolutionX)
!= 0) | |
| 548 || (m_pStream->readInteger(&pPageInfo->m_dwResolutionY)
!= 0) | |
| 549 || (m_pStream->read1Byte(&pPageInfo->m_cFlags) != 0) | |
| 550 || (m_pStream->readShortInteger(&wTemp) != 0)) { | |
| 551 delete pPageInfo; | |
| 552 goto failed1; | |
| 553 } | |
| 554 pPageInfo->m_bIsStriped = ((wTemp >> 15) & 1) ? 1 : 0; | |
| 555 pPageInfo->m_wMaxStripeSize = wTemp & 0x7fff; | |
| 556 if((pPageInfo->m_dwHeight == 0xffffffff) && (pPageInfo->m_bIsStr
iped != 1)) { | |
| 557 m_pModule->JBig2_Warn("page height = 0xffffffff buf stripe f
ield is 0"); | |
| 558 pPageInfo->m_bIsStriped = 1; | |
| 559 } | |
| 560 if(!m_bBufSpecified) { | |
| 561 if(m_pPage) { | |
| 562 delete m_pPage; | |
| 563 } | |
| 564 if(pPageInfo->m_dwHeight == 0xffffffff) { | |
| 565 JBIG2_ALLOC(m_pPage, CJBig2_Image(pPageInfo->m_dwWidth,
pPageInfo->m_wMaxStripeSize)); | |
| 566 } else { | |
| 567 JBIG2_ALLOC(m_pPage, CJBig2_Image(pPageInfo->m_dwWidth,
pPageInfo->m_dwHeight)); | |
| 568 } | |
| 569 } | |
| 570 m_pPage->fill((pPageInfo->m_cFlags & 4) ? 1 : 0); | |
| 571 m_pPageInfoList->addItem(pPageInfo); | |
| 572 m_nState = JBIG2_IN_PAGE; | |
| 573 } | |
| 574 break; | |
| 575 case 49: | |
| 576 m_nState = JBIG2_OUT_OF_PAGE; | |
| 577 return JBIG2_END_OF_PAGE; | |
| 578 break; | |
| 579 case 50: | |
| 580 m_pStream->offset(pSegment->m_dwData_length); | |
| 581 break; | |
| 582 case 51: | |
| 583 return JBIG2_END_OF_FILE; | |
| 584 case 52: | |
| 585 m_pStream->offset(pSegment->m_dwData_length); | |
| 586 break; | |
| 587 case 53: | |
| 588 return parseTable(pSegment); | |
| 589 case 62: | |
| 590 m_pStream->offset(pSegment->m_dwData_length); | |
| 591 break; | |
| 592 default: | |
| 593 break; | |
| 594 } | |
| 595 return JBIG2_SUCCESS; | |
| 596 failed1: | |
| 597 m_pModule->JBig2_Error("segment data too short."); | |
| 598 return JBIG2_ERROR_TOO_SHORT; | |
| 599 failed2: | |
| 600 m_pModule->JBig2_Error("segment syntax error."); | |
| 601 return JBIG2_ERROR_FETAL; | |
| 602 } | |
| 603 FX_INT32 CJBig2_Context::parseSymbolDict(CJBig2_Segment *pSegment, IFX_Pause* pP
ause) | |
| 604 { | |
| 605 FX_DWORD dwTemp; | |
| 606 FX_WORD wFlags; | |
| 607 FX_BYTE cSDHUFFDH, cSDHUFFDW, cSDHUFFBMSIZE, cSDHUFFAGGINST; | |
| 608 CJBig2_HuffmanTable *Table_B1 = NULL, *Table_B2 = NULL, *Table_B3 = NULL, *T
able_B4 = NULL, *Table_B5 = NULL; | |
| 609 FX_INT32 i, nIndex, nRet; | |
| 610 CJBig2_Segment *pSeg = NULL, *pLRSeg = NULL; | |
| 611 FX_BOOL bUsed; | |
| 612 CJBig2_Image ** SDINSYMS = NULL; | |
| 613 CJBig2_SDDProc *pSymbolDictDecoder; | |
| 614 JBig2ArithCtx *gbContext = NULL, *grContext = NULL; | |
| 615 CJBig2_ArithDecoder *pArithDecoder; | |
| 616 JBIG2_ALLOC(pSymbolDictDecoder, CJBig2_SDDProc()); | |
| 617 if(m_pStream->readShortInteger(&wFlags) != 0) { | |
| 618 m_pModule->JBig2_Error("symbol dictionary segment : data header too shor
t."); | |
| 619 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 620 goto failed; | |
| 621 } | |
| 622 pSymbolDictDecoder->SDHUFF = wFlags & 0x0001; | |
| 623 pSymbolDictDecoder->SDREFAGG = (wFlags >> 1) & 0x0001; | |
| 624 pSymbolDictDecoder->SDTEMPLATE = (wFlags >> 10) & 0x0003; | |
| 625 pSymbolDictDecoder->SDRTEMPLATE = (wFlags >> 12) & 0x0003; | |
| 626 cSDHUFFDH = (wFlags >> 2) & 0x0003; | |
| 627 cSDHUFFDW = (wFlags >> 4) & 0x0003; | |
| 628 cSDHUFFBMSIZE = (wFlags >> 6) & 0x0001; | |
| 629 cSDHUFFAGGINST = (wFlags >> 7) & 0x0001; | |
| 630 if(pSymbolDictDecoder->SDHUFF == 0) { | |
| 631 if(pSymbolDictDecoder->SDTEMPLATE == 0) { | |
| 632 dwTemp = 8; | |
| 633 } else { | |
| 634 dwTemp = 2; | |
| 635 } | |
| 636 for(i = 0; i < (FX_INT32)dwTemp; i++) { | |
| 637 if(m_pStream->read1Byte((FX_BYTE*)&pSymbolDictDecoder->SDAT[i]) != 0
) { | |
| 638 m_pModule->JBig2_Error("symbol dictionary segment : data header
too short."); | |
| 639 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 640 goto failed; | |
| 641 } | |
| 642 } | |
| 643 } | |
| 644 if((pSymbolDictDecoder->SDREFAGG == 1) && (pSymbolDictDecoder->SDRTEMPLATE =
= 0)) { | |
| 645 for(i = 0; i < 4; i++) { | |
| 646 if(m_pStream->read1Byte((FX_BYTE*)&pSymbolDictDecoder->SDRAT[i]) !=
0) { | |
| 647 m_pModule->JBig2_Error("symbol dictionary segment : data header
too short."); | |
| 648 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 649 goto failed; | |
| 650 } | |
| 651 } | |
| 652 } | |
| 653 if((m_pStream->readInteger(&pSymbolDictDecoder->SDNUMEXSYMS) != 0) | |
| 654 || (m_pStream->readInteger(&pSymbolDictDecoder->SDNUMNEWSYMS) != 0))
{ | |
| 655 m_pModule->JBig2_Error("symbol dictionary segment : data header too shor
t."); | |
| 656 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 657 goto failed; | |
| 658 } | |
| 659 if (pSymbolDictDecoder->SDNUMEXSYMS > JBIG2_MAX_EXPORT_SYSMBOLS | |
| 660 || pSymbolDictDecoder->SDNUMNEWSYMS > JBIG2_MAX_NEW_SYSMBOLS) { | |
| 661 m_pModule->JBig2_Error("symbol dictionary segment : too many export/new
symbols."); | |
| 662 nRet = JBIG2_ERROR_LIMIT; | |
| 663 goto failed; | |
| 664 } | |
| 665 for(i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | |
| 666 if(!findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i])) { | |
| 667 m_pModule->JBig2_Error("symbol dictionary segment : can't find refer
ed to segments"); | |
| 668 nRet = JBIG2_ERROR_FETAL; | |
| 669 goto failed; | |
| 670 } | |
| 671 } | |
| 672 pSymbolDictDecoder->SDNUMINSYMS = 0; | |
| 673 for(i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | |
| 674 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); | |
| 675 if(pSeg->m_cFlags.s.type == 0) { | |
| 676 pSymbolDictDecoder->SDNUMINSYMS += pSeg->m_Result.sd->SDNUMEXSYMS; | |
| 677 pLRSeg = pSeg; | |
| 678 } | |
| 679 } | |
| 680 if(pSymbolDictDecoder->SDNUMINSYMS == 0) { | |
| 681 SDINSYMS = NULL; | |
| 682 } else { | |
| 683 SDINSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2( | |
| 684 sizeof(CJBig2_Image*), pSymbolDictDecoder->SDNUMINSYMS); | |
| 685 dwTemp = 0; | |
| 686 for(i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | |
| 687 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[
i]); | |
| 688 if(pSeg->m_cFlags.s.type == 0) { | |
| 689 JBIG2_memcpy(SDINSYMS + dwTemp, pSeg->m_Result.sd->SDEXSYMS, | |
| 690 pSeg->m_Result.sd->SDNUMEXSYMS * sizeof(CJBig2_Imag
e*)); | |
| 691 dwTemp += pSeg->m_Result.sd->SDNUMEXSYMS; | |
| 692 } | |
| 693 } | |
| 694 } | |
| 695 pSymbolDictDecoder->SDINSYMS = SDINSYMS; | |
| 696 if(pSymbolDictDecoder->SDHUFF == 1) { | |
| 697 if((cSDHUFFDH == 2) || (cSDHUFFDW == 2)) { | |
| 698 m_pModule->JBig2_Error("symbol dictionary segment : SDHUFFDH=2 or SD
HUFFDW=2 is not permitted."); | |
| 699 nRet = JBIG2_ERROR_FETAL; | |
| 700 goto failed; | |
| 701 } | |
| 702 nIndex = 0; | |
| 703 if(cSDHUFFDH == 0) { | |
| 704 JBIG2_ALLOC(Table_B4, CJBig2_HuffmanTable(HuffmanTable_B4, | |
| 705 sizeof(HuffmanTable_B4) / sizeof(JBig2TableLine), Huffma
nTable_HTOOB_B4)); | |
| 706 pSymbolDictDecoder->SDHUFFDH = Table_B4; | |
| 707 } else if(cSDHUFFDH == 1) { | |
| 708 JBIG2_ALLOC(Table_B5, CJBig2_HuffmanTable(HuffmanTable_B5, | |
| 709 sizeof(HuffmanTable_B5) / sizeof(JBig2TableLine), Huffma
nTable_HTOOB_B5)); | |
| 710 pSymbolDictDecoder->SDHUFFDH = Table_B5; | |
| 711 } else { | |
| 712 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | |
| 713 if(!pSeg) { | |
| 714 m_pModule->JBig2_Error("symbol dictionary segment : SDHUFFDH can
't find user supplied table."); | |
| 715 nRet = JBIG2_ERROR_FETAL; | |
| 716 goto failed; | |
| 717 } | |
| 718 pSymbolDictDecoder->SDHUFFDH = pSeg->m_Result.ht; | |
| 719 } | |
| 720 if(cSDHUFFDW == 0) { | |
| 721 JBIG2_ALLOC(Table_B2, CJBig2_HuffmanTable(HuffmanTable_B2, | |
| 722 sizeof(HuffmanTable_B2) / sizeof(JBig2TableLine), Huffma
nTable_HTOOB_B2)); | |
| 723 pSymbolDictDecoder->SDHUFFDW = Table_B2; | |
| 724 } else if(cSDHUFFDW == 1) { | |
| 725 JBIG2_ALLOC(Table_B3, CJBig2_HuffmanTable(HuffmanTable_B3, | |
| 726 sizeof(HuffmanTable_B3) / sizeof(JBig2TableLine), Huffma
nTable_HTOOB_B3)); | |
| 727 pSymbolDictDecoder->SDHUFFDW = Table_B3; | |
| 728 } else { | |
| 729 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | |
| 730 if(!pSeg) { | |
| 731 m_pModule->JBig2_Error("symbol dictionary segment : SDHUFFDW can
't find user supplied table."); | |
| 732 nRet = JBIG2_ERROR_FETAL; | |
| 733 goto failed; | |
| 734 } | |
| 735 pSymbolDictDecoder->SDHUFFDW = pSeg->m_Result.ht; | |
| 736 } | |
| 737 if(cSDHUFFBMSIZE == 0) { | |
| 738 JBIG2_ALLOC(Table_B1, CJBig2_HuffmanTable(HuffmanTable_B1, | |
| 739 sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), Huffma
nTable_HTOOB_B1)); | |
| 740 pSymbolDictDecoder->SDHUFFBMSIZE = Table_B1; | |
| 741 } else { | |
| 742 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | |
| 743 if(!pSeg) { | |
| 744 m_pModule->JBig2_Error("symbol dictionary segment : SDHUFFBMSIZE
can't find user supplied table."); | |
| 745 nRet = JBIG2_ERROR_FETAL; | |
| 746 goto failed; | |
| 747 } | |
| 748 pSymbolDictDecoder->SDHUFFBMSIZE = pSeg->m_Result.ht; | |
| 749 } | |
| 750 if(pSymbolDictDecoder->SDREFAGG == 1) { | |
| 751 if(cSDHUFFAGGINST == 0) { | |
| 752 if(!Table_B1) { | |
| 753 JBIG2_ALLOC(Table_B1, CJBig2_HuffmanTable(HuffmanTable_B1, | |
| 754 sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine)
, HuffmanTable_HTOOB_B1)); | |
| 755 } | |
| 756 pSymbolDictDecoder->SDHUFFAGGINST = Table_B1; | |
| 757 } else { | |
| 758 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++)
; | |
| 759 if(!pSeg) { | |
| 760 m_pModule->JBig2_Error("symbol dictionary segment : SDHUFFAG
GINST can't find user supplied table."); | |
| 761 nRet = JBIG2_ERROR_FETAL; | |
| 762 goto failed; | |
| 763 } | |
| 764 pSymbolDictDecoder->SDHUFFAGGINST = pSeg->m_Result.ht; | |
| 765 } | |
| 766 } | |
| 767 } | |
| 768 if((wFlags & 0x0100) && pLRSeg && pLRSeg->m_Result.sd->m_bContextRetained) { | |
| 769 if (pSymbolDictDecoder->SDHUFF == 0) { | |
| 770 dwTemp = pSymbolDictDecoder->SDTEMPLATE == 0 ? 65536 : pSymbolDictDe
coder->SDTEMPLATE == 1 ? | |
| 771 8192 : 1024; | |
| 772 gbContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2Ari
thCtx), dwTemp); | |
| 773 JBIG2_memcpy(gbContext, pLRSeg->m_Result.sd->m_gbContext, sizeof(JBi
g2ArithCtx)*dwTemp); | |
| 774 } | |
| 775 if (pSymbolDictDecoder->SDREFAGG == 1) { | |
| 776 dwTemp = pSymbolDictDecoder->SDRTEMPLATE ? 1 << 10 : 1 << 13; | |
| 777 grContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2Ari
thCtx), dwTemp); | |
| 778 JBIG2_memcpy(grContext, pLRSeg->m_Result.sd->m_grContext, sizeof(JBi
g2ArithCtx)*dwTemp); | |
| 779 } | |
| 780 } else { | |
| 781 if (pSymbolDictDecoder->SDHUFF == 0) { | |
| 782 dwTemp = pSymbolDictDecoder->SDTEMPLATE == 0 ? 65536 : pSymbolDictDe
coder->SDTEMPLATE == 1 ? | |
| 783 8192 : 1024; | |
| 784 gbContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2Ari
thCtx), dwTemp); | |
| 785 JBIG2_memset(gbContext, 0, sizeof(JBig2ArithCtx)*dwTemp); | |
| 786 } | |
| 787 if (pSymbolDictDecoder->SDREFAGG == 1) { | |
| 788 dwTemp = pSymbolDictDecoder->SDRTEMPLATE ? 1 << 10 : 1 << 13; | |
| 789 grContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2Ari
thCtx), dwTemp); | |
| 790 JBIG2_memset(grContext, 0, sizeof(JBig2ArithCtx)*dwTemp); | |
| 791 } | |
| 792 } | |
| 793 pSegment->m_nResultType = JBIG2_SYMBOL_DICT_POINTER; | |
| 794 if(pSymbolDictDecoder->SDHUFF == 0) { | |
| 795 JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(m_pStream)); | |
| 796 pSegment->m_Result.sd = pSymbolDictDecoder->decode_Arith(pArithDecoder,
gbContext, grContext); | |
| 797 delete pArithDecoder; | |
| 798 if(pSegment->m_Result.sd == NULL) { | |
| 799 nRet = JBIG2_ERROR_FETAL; | |
| 800 goto failed; | |
| 801 } | |
| 802 m_pStream->alignByte(); | |
| 803 m_pStream->offset(2); | |
| 804 } else { | |
| 805 pSegment->m_Result.sd = pSymbolDictDecoder->decode_Huffman(m_pStream, gb
Context, grContext, pPause); | |
| 806 if(pSegment->m_Result.sd == NULL) { | |
| 807 nRet = JBIG2_ERROR_FETAL; | |
| 808 goto failed; | |
| 809 } | |
| 810 m_pStream->alignByte(); | |
| 811 } | |
| 812 if(wFlags & 0x0200) { | |
| 813 pSegment->m_Result.sd->m_bContextRetained = TRUE; | |
| 814 if(pSymbolDictDecoder->SDHUFF == 0) { | |
| 815 pSegment->m_Result.sd->m_gbContext = gbContext; | |
| 816 } | |
| 817 if(pSymbolDictDecoder->SDREFAGG == 1) { | |
| 818 pSegment->m_Result.sd->m_grContext = grContext; | |
| 819 } | |
| 820 bUsed = TRUE; | |
| 821 } else { | |
| 822 bUsed = FALSE; | |
| 823 } | |
| 824 delete pSymbolDictDecoder; | |
| 825 if(SDINSYMS) { | |
| 826 m_pModule->JBig2_Free(SDINSYMS); | |
| 827 } | |
| 828 if(Table_B1) { | |
| 829 delete Table_B1; | |
| 830 } | |
| 831 if(Table_B2) { | |
| 832 delete Table_B2; | |
| 833 } | |
| 834 if(Table_B3) { | |
| 835 delete Table_B3; | |
| 836 } | |
| 837 if(Table_B4) { | |
| 838 delete Table_B4; | |
| 839 } | |
| 840 if(Table_B5) { | |
| 841 delete Table_B5; | |
| 842 } | |
| 843 if(bUsed == FALSE) { | |
| 844 if(gbContext) { | |
| 845 m_pModule->JBig2_Free(gbContext); | |
| 846 } | |
| 847 if(grContext) { | |
| 848 m_pModule->JBig2_Free(grContext); | |
| 849 } | |
| 850 } | |
| 851 return JBIG2_SUCCESS; | |
| 852 failed: | |
| 853 delete pSymbolDictDecoder; | |
| 854 if(SDINSYMS) { | |
| 855 m_pModule->JBig2_Free(SDINSYMS); | |
| 856 } | |
| 857 if(Table_B1) { | |
| 858 delete Table_B1; | |
| 859 } | |
| 860 if(Table_B2) { | |
| 861 delete Table_B2; | |
| 862 } | |
| 863 if(Table_B3) { | |
| 864 delete Table_B3; | |
| 865 } | |
| 866 if(Table_B4) { | |
| 867 delete Table_B4; | |
| 868 } | |
| 869 if(Table_B5) { | |
| 870 delete Table_B5; | |
| 871 } | |
| 872 if(gbContext) { | |
| 873 m_pModule->JBig2_Free(gbContext); | |
| 874 } | |
| 875 if(grContext) { | |
| 876 m_pModule->JBig2_Free(grContext); | |
| 877 } | |
| 878 return nRet; | |
| 879 } | |
| 880 | |
| 881 FX_BOOL CJBig2_Context::parseTextRegion(CJBig2_Segment *pSegment) | |
| 882 { | |
| 883 FX_DWORD dwTemp; | |
| 884 FX_WORD wFlags; | |
| 885 FX_INT32 i, nIndex, nRet; | |
| 886 JBig2RegionInfo ri; | |
| 887 CJBig2_Segment *pSeg; | |
| 888 CJBig2_Image **SBSYMS = NULL; | |
| 889 JBig2HuffmanCode *SBSYMCODES = NULL; | |
| 890 FX_BYTE cSBHUFFFS, cSBHUFFDS, cSBHUFFDT, cSBHUFFRDW, cSBHUFFRDH, cSBHUFFRDX,
cSBHUFFRDY, cSBHUFFRSIZE; | |
| 891 CJBig2_HuffmanTable *Table_B1 = NULL, | |
| 892 *Table_B6 = NULL, | |
| 893 *Table_B7 = NULL, | |
| 894 *Table_B8 = NULL, | |
| 895 *Table_B9 = NULL, | |
| 896 *Table_B10 = NULL, | |
| 897 *Table_B11 = NULL, | |
| 898 *Table_B12 = NULL, | |
| 899 *Table_B13 = NULL, | |
| 900 *Table_B14 = NULL, | |
| 901 *Table_B15 = NULL; | |
| 902 JBig2ArithCtx *grContext = NULL; | |
| 903 CJBig2_ArithDecoder *pArithDecoder; | |
| 904 CJBig2_TRDProc *pTRD; | |
| 905 JBIG2_ALLOC(pTRD, CJBig2_TRDProc()); | |
| 906 if((parseRegionInfo(&ri) != JBIG2_SUCCESS) | |
| 907 || (m_pStream->readShortInteger(&wFlags) != 0)) { | |
| 908 m_pModule->JBig2_Error("text region segment : data header too short."); | |
| 909 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 910 goto failed; | |
| 911 } | |
| 912 pTRD->SBW = ri.width; | |
| 913 pTRD->SBH = ri.height; | |
| 914 pTRD->SBHUFF = wFlags & 0x0001; | |
| 915 pTRD->SBREFINE = (wFlags >> 1) & 0x0001; | |
| 916 dwTemp = (wFlags >> 2) & 0x0003; | |
| 917 pTRD->SBSTRIPS = 1 << dwTemp; | |
| 918 pTRD->REFCORNER = (JBig2Corner)((wFlags >> 4) & 0x0003); | |
| 919 pTRD->TRANSPOSED = (wFlags >> 6) & 0x0001; | |
| 920 pTRD->SBCOMBOP = (JBig2ComposeOp)((wFlags >> 7) & 0x0003); | |
| 921 pTRD->SBDEFPIXEL = (wFlags >> 9) & 0x0001; | |
| 922 pTRD->SBDSOFFSET = (wFlags >> 10) & 0x001f; | |
| 923 if(pTRD->SBDSOFFSET >= 0x0010) { | |
| 924 pTRD->SBDSOFFSET = pTRD->SBDSOFFSET - 0x0020; | |
| 925 } | |
| 926 pTRD->SBRTEMPLATE = (wFlags >> 15) & 0x0001; | |
| 927 if(pTRD->SBHUFF == 1) { | |
| 928 if(m_pStream->readShortInteger(&wFlags) != 0) { | |
| 929 m_pModule->JBig2_Error("text region segment : data header too short.
"); | |
| 930 nRet = JBIG2_ERROR_TOO_SHORT; | 1611 nRet = JBIG2_ERROR_TOO_SHORT; |
| 931 goto failed; | 1612 goto failed; |
| 1613 } |
| 932 } | 1614 } |
| 933 cSBHUFFFS = wFlags & 0x0003; | 1615 } |
| 934 cSBHUFFDS = (wFlags >> 2) & 0x0003; | 1616 } |
| 935 cSBHUFFDT = (wFlags >> 4) & 0x0003; | 1617 m_pGRD->USESKIP = 0; |
| 936 cSBHUFFRDW = (wFlags >> 6) & 0x0003; | 1618 } |
| 937 cSBHUFFRDH = (wFlags >> 8) & 0x0003; | 1619 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; |
| 938 cSBHUFFRDX = (wFlags >> 10) & 0x0003; | 1620 if (m_pGRD->MMR == 0) { |
| 939 cSBHUFFRDY = (wFlags >> 12) & 0x0003; | 1621 dwTemp = |
| 940 cSBHUFFRSIZE = (wFlags >> 14) & 0x0001; | 1622 m_pGRD->GBTEMPLATE == 0 ? 65536 : m_pGRD->GBTEMPLATE == 1 ? 8192 : 1024; |
| 941 } | 1623 if (m_gbContext == NULL) { |
| 942 if((pTRD->SBREFINE == 1) && (pTRD->SBRTEMPLATE == 0)) { | 1624 m_gbContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc( |
| 943 for(i = 0; i < 4; i++) { | 1625 sizeof(JBig2ArithCtx) * dwTemp); |
| 944 if(m_pStream->read1Byte((FX_BYTE*)&pTRD->SBRAT[i]) != 0) { | 1626 JBIG2_memset(m_gbContext, 0, sizeof(JBig2ArithCtx) * dwTemp); |
| 945 m_pModule->JBig2_Error("text region segment : data header too sh
ort."); | 1627 } |
| 946 nRet = JBIG2_ERROR_TOO_SHORT; | 1628 if (m_pArithDecoder == NULL) { |
| 947 goto failed; | 1629 JBIG2_ALLOC(m_pArithDecoder, CJBig2_ArithDecoder(m_pStream)); |
| 948 } | 1630 m_ProcessiveStatus = m_pGRD->Start_decode_Arith( |
| 949 } | 1631 &pSegment->m_Result.im, m_pArithDecoder, m_gbContext, pPause); |
| 950 } | |
| 951 if(m_pStream->readInteger(&pTRD->SBNUMINSTANCES) != 0) { | |
| 952 m_pModule->JBig2_Error("text region segment : data header too short."); | |
| 953 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 954 goto failed; | |
| 955 } | |
| 956 for(i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | |
| 957 if(!findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i])) { | |
| 958 m_pModule->JBig2_Error("text region segment : can't find refered to
segments"); | |
| 959 nRet = JBIG2_ERROR_FETAL; | |
| 960 goto failed; | |
| 961 } | |
| 962 } | |
| 963 pTRD->SBNUMSYMS = 0; | |
| 964 for(i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | |
| 965 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); | |
| 966 if(pSeg->m_cFlags.s.type == 0) { | |
| 967 pTRD->SBNUMSYMS += pSeg->m_Result.sd->SDNUMEXSYMS; | |
| 968 } | |
| 969 } | |
| 970 if (pTRD->SBNUMSYMS > 0) { | |
| 971 SBSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2( | |
| 972 sizeof(CJBig2_Image*), pTRD->SBNUMSYMS); | |
| 973 dwTemp = 0; | |
| 974 for(i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | |
| 975 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[
i]); | |
| 976 if(pSeg->m_cFlags.s.type == 0) { | |
| 977 JBIG2_memcpy(SBSYMS + dwTemp, pSeg->m_Result.sd->SDEXSYMS, | |
| 978 pSeg->m_Result.sd->SDNUMEXSYMS * sizeof(CJBig2_Imag
e*)); | |
| 979 dwTemp += pSeg->m_Result.sd->SDNUMEXSYMS; | |
| 980 } | |
| 981 } | |
| 982 pTRD->SBSYMS = SBSYMS; | |
| 983 } else { | 1632 } else { |
| 984 pTRD->SBSYMS = NULL; | 1633 m_ProcessiveStatus = m_pGRD->Continue_decode(pPause); |
| 985 } | 1634 } |
| 986 if(pTRD->SBHUFF == 1) { | 1635 OutputBitmap(pSegment->m_Result.im); |
| 987 SBSYMCODES = decodeSymbolIDHuffmanTable(m_pStream, pTRD->SBNUMSYMS); | 1636 if (m_ProcessiveStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) { |
| 988 if(SBSYMCODES == NULL) { | 1637 if (pSegment->m_cFlags.s.type != 36) { |
| 989 m_pModule->JBig2_Error("text region segment: symbol ID huffman table
decode failure!"); | 1638 if (!m_bBufSpecified) { |
| 990 nRet = JBIG2_ERROR_FETAL; | 1639 JBig2PageInfo* pPageInfo = m_pPageInfoList->getLast(); |
| 991 goto failed; | 1640 if ((pPageInfo->m_bIsStriped == 1) && |
| 992 } | 1641 (m_ri.y + m_ri.height > m_pPage->m_nHeight)) { |
| 993 m_pStream->alignByte(); | 1642 m_pPage->expand(m_ri.y + m_ri.height, |
| 994 pTRD->SBSYMCODES = SBSYMCODES; | 1643 (pPageInfo->m_cFlags & 4) ? 1 : 0); |
| 995 } else { | 1644 } |
| 996 dwTemp = 0; | |
| 997 while((FX_DWORD)(1 << dwTemp) < pTRD->SBNUMSYMS) { | |
| 998 dwTemp ++; | |
| 999 } | |
| 1000 pTRD->SBSYMCODELEN = (FX_BYTE)dwTemp; | |
| 1001 } | |
| 1002 if(pTRD->SBHUFF == 1) { | |
| 1003 if((cSBHUFFFS == 2) || (cSBHUFFRDW == 2) || (cSBHUFFRDH == 2) | |
| 1004 || (cSBHUFFRDX == 2) || (cSBHUFFRDY == 2)) { | |
| 1005 m_pModule->JBig2_Error("text region segment : SBHUFFFS=2 or SBHUFFRD
W=2 or " | |
| 1006 "SBHUFFRDH=2 or SBHUFFRDX=2 or SBHUFFRDY=2 is
not permitted"); | |
| 1007 nRet = JBIG2_ERROR_FETAL; | |
| 1008 goto failed; | |
| 1009 } | |
| 1010 nIndex = 0; | |
| 1011 if(cSBHUFFFS == 0) { | |
| 1012 JBIG2_ALLOC(Table_B6, CJBig2_HuffmanTable(HuffmanTable_B6, | |
| 1013 sizeof(HuffmanTable_B6) / sizeof(JBig2TableLine), Huffma
nTable_HTOOB_B6)); | |
| 1014 pTRD->SBHUFFFS = Table_B6; | |
| 1015 } else if(cSBHUFFFS == 1) { | |
| 1016 JBIG2_ALLOC(Table_B7, CJBig2_HuffmanTable(HuffmanTable_B7, | |
| 1017 sizeof(HuffmanTable_B7) / sizeof(JBig2TableLine), Huffma
nTable_HTOOB_B7)); | |
| 1018 pTRD->SBHUFFFS = Table_B7; | |
| 1019 } else { | |
| 1020 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | |
| 1021 if(!pSeg) { | |
| 1022 m_pModule->JBig2_Error("text region segment : SBHUFFFS can't fin
d user supplied table"); | |
| 1023 nRet = JBIG2_ERROR_FETAL; | |
| 1024 goto failed; | |
| 1025 } | |
| 1026 pTRD->SBHUFFFS = pSeg->m_Result.ht; | |
| 1027 } | |
| 1028 if(cSBHUFFDS == 0) { | |
| 1029 JBIG2_ALLOC(Table_B8, CJBig2_HuffmanTable(HuffmanTable_B8, | |
| 1030 sizeof(HuffmanTable_B8) / sizeof(JBig2TableLine), Huffma
nTable_HTOOB_B8)); | |
| 1031 pTRD->SBHUFFDS = Table_B8; | |
| 1032 } else if(cSBHUFFDS == 1) { | |
| 1033 JBIG2_ALLOC(Table_B9, CJBig2_HuffmanTable(HuffmanTable_B9, | |
| 1034 sizeof(HuffmanTable_B9) / sizeof(JBig2TableLine), Huffma
nTable_HTOOB_B9)); | |
| 1035 pTRD->SBHUFFDS = Table_B9; | |
| 1036 } else if(cSBHUFFDS == 2) { | |
| 1037 JBIG2_ALLOC(Table_B10, CJBig2_HuffmanTable(HuffmanTable_B10, | |
| 1038 sizeof(HuffmanTable_B10) / sizeof(JBig2TableLine), Huffm
anTable_HTOOB_B10)); | |
| 1039 pTRD->SBHUFFDS = Table_B10; | |
| 1040 } else { | |
| 1041 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | |
| 1042 if(!pSeg) { | |
| 1043 m_pModule->JBig2_Error("text region segment : SBHUFFDS can't fin
d user supplied table"); | |
| 1044 nRet = JBIG2_ERROR_FETAL; | |
| 1045 goto failed; | |
| 1046 } | |
| 1047 pTRD->SBHUFFDS = pSeg->m_Result.ht; | |
| 1048 } | |
| 1049 if(cSBHUFFDT == 0) { | |
| 1050 JBIG2_ALLOC(Table_B11, CJBig2_HuffmanTable(HuffmanTable_B11, | |
| 1051 sizeof(HuffmanTable_B11) / sizeof(JBig2TableLine), Huffm
anTable_HTOOB_B11)); | |
| 1052 pTRD->SBHUFFDT = Table_B11; | |
| 1053 } else if(cSBHUFFDT == 1) { | |
| 1054 JBIG2_ALLOC(Table_B12, CJBig2_HuffmanTable(HuffmanTable_B12, | |
| 1055 sizeof(HuffmanTable_B12) / sizeof(JBig2TableLine), Huffm
anTable_HTOOB_B12)); | |
| 1056 pTRD->SBHUFFDT = Table_B12; | |
| 1057 } else if(cSBHUFFDT == 2) { | |
| 1058 JBIG2_ALLOC(Table_B13, CJBig2_HuffmanTable(HuffmanTable_B13, | |
| 1059 sizeof(HuffmanTable_B13) / sizeof(JBig2TableLine), Huffm
anTable_HTOOB_B13)); | |
| 1060 pTRD->SBHUFFDT = Table_B13; | |
| 1061 } else { | |
| 1062 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | |
| 1063 if(!pSeg) { | |
| 1064 m_pModule->JBig2_Error("text region segment : SBHUFFDT can't fin
d user supplied table"); | |
| 1065 nRet = JBIG2_ERROR_FETAL; | |
| 1066 goto failed; | |
| 1067 } | |
| 1068 pTRD->SBHUFFDT = pSeg->m_Result.ht; | |
| 1069 } | |
| 1070 if(cSBHUFFRDW == 0) { | |
| 1071 JBIG2_ALLOC(Table_B14, CJBig2_HuffmanTable(HuffmanTable_B14, | |
| 1072 sizeof(HuffmanTable_B14) / sizeof(JBig2TableLine), Huffm
anTable_HTOOB_B14)); | |
| 1073 pTRD->SBHUFFRDW = Table_B14; | |
| 1074 } else if(cSBHUFFRDW == 1) { | |
| 1075 JBIG2_ALLOC(Table_B15, CJBig2_HuffmanTable(HuffmanTable_B15, | |
| 1076 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), Huffm
anTable_HTOOB_B15)); | |
| 1077 pTRD->SBHUFFRDW = Table_B15; | |
| 1078 } else { | |
| 1079 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | |
| 1080 if(!pSeg) { | |
| 1081 m_pModule->JBig2_Error("text region segment : SBHUFFRDW can't fi
nd user supplied table"); | |
| 1082 nRet = JBIG2_ERROR_FETAL; | |
| 1083 goto failed; | |
| 1084 } | |
| 1085 pTRD->SBHUFFRDW = pSeg->m_Result.ht; | |
| 1086 } | |
| 1087 if(cSBHUFFRDH == 0) { | |
| 1088 if(!Table_B14) { | |
| 1089 JBIG2_ALLOC(Table_B14, CJBig2_HuffmanTable(HuffmanTable_B14, | |
| 1090 sizeof(HuffmanTable_B14) / sizeof(JBig2TableLine), H
uffmanTable_HTOOB_B14)); | |
| 1091 } | |
| 1092 pTRD->SBHUFFRDH = Table_B14; | |
| 1093 } else if(cSBHUFFRDH == 1) { | |
| 1094 if(!Table_B15) { | |
| 1095 JBIG2_ALLOC(Table_B15, CJBig2_HuffmanTable(HuffmanTable_B15, | |
| 1096 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), H
uffmanTable_HTOOB_B15)); | |
| 1097 } | |
| 1098 pTRD->SBHUFFRDH = Table_B15; | |
| 1099 } else { | |
| 1100 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | |
| 1101 if(!pSeg) { | |
| 1102 m_pModule->JBig2_Error("text region segment : SBHUFFRDH can't fi
nd user supplied table"); | |
| 1103 nRet = JBIG2_ERROR_FETAL; | |
| 1104 goto failed; | |
| 1105 } | |
| 1106 pTRD->SBHUFFRDH = pSeg->m_Result.ht; | |
| 1107 } | |
| 1108 if(cSBHUFFRDX == 0) { | |
| 1109 if(!Table_B14) { | |
| 1110 JBIG2_ALLOC(Table_B14, CJBig2_HuffmanTable(HuffmanTable_B14, | |
| 1111 sizeof(HuffmanTable_B14) / sizeof(JBig2TableLine), H
uffmanTable_HTOOB_B14)); | |
| 1112 } | |
| 1113 pTRD->SBHUFFRDX = Table_B14; | |
| 1114 } else if(cSBHUFFRDX == 1) { | |
| 1115 if(!Table_B15) { | |
| 1116 JBIG2_ALLOC(Table_B15, CJBig2_HuffmanTable(HuffmanTable_B15, | |
| 1117 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), H
uffmanTable_HTOOB_B15)); | |
| 1118 } | |
| 1119 pTRD->SBHUFFRDX = Table_B15; | |
| 1120 } else { | |
| 1121 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | |
| 1122 if(!pSeg) { | |
| 1123 m_pModule->JBig2_Error("text region segment : SBHUFFRDX can't fi
nd user supplied table"); | |
| 1124 nRet = JBIG2_ERROR_FETAL; | |
| 1125 goto failed; | |
| 1126 } | |
| 1127 pTRD->SBHUFFRDX = pSeg->m_Result.ht; | |
| 1128 } | |
| 1129 if(cSBHUFFRDY == 0) { | |
| 1130 if(!Table_B14) { | |
| 1131 JBIG2_ALLOC(Table_B14, CJBig2_HuffmanTable(HuffmanTable_B14, | |
| 1132 sizeof(HuffmanTable_B14) / sizeof(JBig2TableLine), H
uffmanTable_HTOOB_B14)); | |
| 1133 } | |
| 1134 pTRD->SBHUFFRDY = Table_B14; | |
| 1135 } else if(cSBHUFFRDY == 1) { | |
| 1136 if(!Table_B15) { | |
| 1137 JBIG2_ALLOC(Table_B15, CJBig2_HuffmanTable(HuffmanTable_B15, | |
| 1138 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), H
uffmanTable_HTOOB_B15)); | |
| 1139 } | |
| 1140 pTRD->SBHUFFRDY = Table_B15; | |
| 1141 } else { | |
| 1142 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | |
| 1143 if(!pSeg) { | |
| 1144 m_pModule->JBig2_Error("text region segment : SBHUFFRDY can't fi
nd user supplied table"); | |
| 1145 nRet = JBIG2_ERROR_FETAL; | |
| 1146 goto failed; | |
| 1147 } | |
| 1148 pTRD->SBHUFFRDY = pSeg->m_Result.ht; | |
| 1149 } | |
| 1150 if(cSBHUFFRSIZE == 0) { | |
| 1151 JBIG2_ALLOC(Table_B1, CJBig2_HuffmanTable(HuffmanTable_B1, | |
| 1152 sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), Huffma
nTable_HTOOB_B1)); | |
| 1153 pTRD->SBHUFFRSIZE = Table_B1; | |
| 1154 } else { | |
| 1155 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | |
| 1156 if(!pSeg) { | |
| 1157 m_pModule->JBig2_Error("text region segment : SBHUFFRSIZE can't
find user supplied table"); | |
| 1158 nRet = JBIG2_ERROR_FETAL; | |
| 1159 goto failed; | |
| 1160 } | |
| 1161 pTRD->SBHUFFRSIZE = pSeg->m_Result.ht; | |
| 1162 } | |
| 1163 } | |
| 1164 if(pTRD->SBREFINE == 1) { | |
| 1165 dwTemp = pTRD->SBRTEMPLATE ? 1 << 10 : 1 << 13; | |
| 1166 grContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2ArithCt
x), dwTemp); | |
| 1167 JBIG2_memset(grContext, 0, sizeof(JBig2ArithCtx)*dwTemp); | |
| 1168 } | |
| 1169 if(pTRD->SBHUFF == 0) { | |
| 1170 JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(m_pStream)); | |
| 1171 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; | |
| 1172 pSegment->m_Result.im = pTRD->decode_Arith(pArithDecoder, grContext); | |
| 1173 delete pArithDecoder; | |
| 1174 if(pSegment->m_Result.im == NULL) { | |
| 1175 nRet = JBIG2_ERROR_FETAL; | |
| 1176 goto failed; | |
| 1177 } | |
| 1178 m_pStream->alignByte(); | |
| 1179 m_pStream->offset(2); | |
| 1180 } else { | |
| 1181 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; | |
| 1182 pSegment->m_Result.im = pTRD->decode_Huffman(m_pStream, grContext); | |
| 1183 if(pSegment->m_Result.im == NULL) { | |
| 1184 nRet = JBIG2_ERROR_FETAL; | |
| 1185 goto failed; | |
| 1186 } | |
| 1187 m_pStream->alignByte(); | |
| 1188 } | |
| 1189 if(pSegment->m_cFlags.s.type != 4) { | |
| 1190 if(!m_bBufSpecified) { | |
| 1191 JBig2PageInfo *pPageInfo = m_pPageInfoList->getLast(); | |
| 1192 if ((pPageInfo->m_bIsStriped == 1) && (ri.y + ri.height > m_pPage->m
_nHeight)) { | |
| 1193 m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1
: 0); | |
| 1194 } | |
| 1195 } | |
| 1196 m_pPage->composeFrom(ri.x, ri.y, pSegment->m_Result.im, (JBig2ComposeOp)
(ri.flags & 0x03)); | |
| 1197 delete pSegment->m_Result.im; | |
| 1198 pSegment->m_Result.im = NULL; | |
| 1199 } | |
| 1200 delete pTRD; | |
| 1201 if(SBSYMS) { | |
| 1202 m_pModule->JBig2_Free(SBSYMS); | |
| 1203 } | |
| 1204 if(SBSYMCODES) { | |
| 1205 m_pModule->JBig2_Free(SBSYMCODES); | |
| 1206 } | |
| 1207 if(grContext) { | |
| 1208 m_pModule->JBig2_Free(grContext); | |
| 1209 } | |
| 1210 if(Table_B1) { | |
| 1211 delete Table_B1; | |
| 1212 } | |
| 1213 if(Table_B6) { | |
| 1214 delete Table_B6; | |
| 1215 } | |
| 1216 if(Table_B7) { | |
| 1217 delete Table_B7; | |
| 1218 } | |
| 1219 if(Table_B8) { | |
| 1220 delete Table_B8; | |
| 1221 } | |
| 1222 if(Table_B9) { | |
| 1223 delete Table_B9; | |
| 1224 } | |
| 1225 if(Table_B10) { | |
| 1226 delete Table_B10; | |
| 1227 } | |
| 1228 if(Table_B11) { | |
| 1229 delete Table_B11; | |
| 1230 } | |
| 1231 if(Table_B12) { | |
| 1232 delete Table_B12; | |
| 1233 } | |
| 1234 if(Table_B13) { | |
| 1235 delete Table_B13; | |
| 1236 } | |
| 1237 if(Table_B14) { | |
| 1238 delete Table_B14; | |
| 1239 } | |
| 1240 if(Table_B15) { | |
| 1241 delete Table_B15; | |
| 1242 } | |
| 1243 return JBIG2_SUCCESS; | |
| 1244 failed: | |
| 1245 delete pTRD; | |
| 1246 if(SBSYMS) { | |
| 1247 m_pModule->JBig2_Free(SBSYMS); | |
| 1248 } | |
| 1249 if(SBSYMCODES) { | |
| 1250 m_pModule->JBig2_Free(SBSYMCODES); | |
| 1251 } | |
| 1252 if(grContext) { | |
| 1253 m_pModule->JBig2_Free(grContext); | |
| 1254 } | |
| 1255 if(Table_B1) { | |
| 1256 delete Table_B1; | |
| 1257 } | |
| 1258 if(Table_B6) { | |
| 1259 delete Table_B6; | |
| 1260 } | |
| 1261 if(Table_B7) { | |
| 1262 delete Table_B7; | |
| 1263 } | |
| 1264 if(Table_B8) { | |
| 1265 delete Table_B8; | |
| 1266 } | |
| 1267 if(Table_B9) { | |
| 1268 delete Table_B9; | |
| 1269 } | |
| 1270 if(Table_B10) { | |
| 1271 delete Table_B10; | |
| 1272 } | |
| 1273 if(Table_B11) { | |
| 1274 delete Table_B11; | |
| 1275 } | |
| 1276 if(Table_B12) { | |
| 1277 delete Table_B12; | |
| 1278 } | |
| 1279 if(Table_B13) { | |
| 1280 delete Table_B13; | |
| 1281 } | |
| 1282 if(Table_B14) { | |
| 1283 delete Table_B14; | |
| 1284 } | |
| 1285 if(Table_B15) { | |
| 1286 delete Table_B15; | |
| 1287 } | |
| 1288 return nRet; | |
| 1289 } | |
| 1290 | |
| 1291 FX_BOOL CJBig2_Context::parsePatternDict(CJBig2_Segment *pSegment, IFX_Pause* pP
ause) | |
| 1292 { | |
| 1293 FX_DWORD dwTemp; | |
| 1294 FX_BYTE cFlags; | |
| 1295 JBig2ArithCtx *gbContext; | |
| 1296 CJBig2_ArithDecoder *pArithDecoder; | |
| 1297 CJBig2_PDDProc *pPDD; | |
| 1298 FX_INT32 nRet; | |
| 1299 JBIG2_ALLOC(pPDD, CJBig2_PDDProc()); | |
| 1300 if((m_pStream->read1Byte(&cFlags) != 0) | |
| 1301 || (m_pStream->read1Byte(&pPDD->HDPW) != 0) | |
| 1302 || (m_pStream->read1Byte(&pPDD->HDPH) != 0) | |
| 1303 || (m_pStream->readInteger(&pPDD->GRAYMAX) != 0)) { | |
| 1304 m_pModule->JBig2_Error("pattern dictionary segment : data header too sho
rt."); | |
| 1305 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 1306 goto failed; | |
| 1307 } | |
| 1308 if (pPDD->GRAYMAX > JBIG2_MAX_PATTERN_INDEX) { | |
| 1309 m_pModule->JBig2_Error("pattern dictionary segment : too max gray max.")
; | |
| 1310 nRet = JBIG2_ERROR_LIMIT; | |
| 1311 goto failed; | |
| 1312 } | |
| 1313 pPDD->HDMMR = cFlags & 0x01; | |
| 1314 pPDD->HDTEMPLATE = (cFlags >> 1) & 0x03; | |
| 1315 pSegment->m_nResultType = JBIG2_PATTERN_DICT_POINTER; | |
| 1316 if(pPDD->HDMMR == 0) { | |
| 1317 dwTemp = pPDD->HDTEMPLATE == 0 ? 65536 : pPDD->HDTEMPLATE == 1 ? 8192 :
1024; | |
| 1318 gbContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2ArithCt
x), dwTemp); | |
| 1319 JBIG2_memset(gbContext, 0, sizeof(JBig2ArithCtx)*dwTemp); | |
| 1320 JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(m_pStream)); | |
| 1321 pSegment->m_Result.pd = pPDD->decode_Arith(pArithDecoder, gbContext, pPa
use); | |
| 1322 delete pArithDecoder; | |
| 1323 if(pSegment->m_Result.pd == NULL) { | |
| 1324 m_pModule->JBig2_Free(gbContext); | |
| 1325 nRet = JBIG2_ERROR_FETAL; | |
| 1326 goto failed; | |
| 1327 } | |
| 1328 m_pModule->JBig2_Free(gbContext); | |
| 1329 m_pStream->alignByte(); | |
| 1330 m_pStream->offset(2); | |
| 1331 } else { | |
| 1332 pSegment->m_Result.pd = pPDD->decode_MMR(m_pStream, pPause); | |
| 1333 if(pSegment->m_Result.pd == NULL) { | |
| 1334 nRet = JBIG2_ERROR_FETAL; | |
| 1335 goto failed; | |
| 1336 } | |
| 1337 m_pStream->alignByte(); | |
| 1338 } | |
| 1339 delete pPDD; | |
| 1340 return JBIG2_SUCCESS; | |
| 1341 failed: | |
| 1342 delete pPDD; | |
| 1343 return nRet; | |
| 1344 } | |
| 1345 FX_BOOL CJBig2_Context::parseHalftoneRegion(CJBig2_Segment *pSegment, IFX_Pause*
pPause) | |
| 1346 { | |
| 1347 FX_DWORD dwTemp; | |
| 1348 FX_BYTE cFlags; | |
| 1349 JBig2RegionInfo ri; | |
| 1350 CJBig2_Segment *pSeg; | |
| 1351 CJBig2_PatternDict *pPatternDict; | |
| 1352 JBig2ArithCtx *gbContext; | |
| 1353 CJBig2_ArithDecoder *pArithDecoder; | |
| 1354 CJBig2_HTRDProc *pHRD; | |
| 1355 FX_INT32 nRet; | |
| 1356 JBIG2_ALLOC(pHRD, CJBig2_HTRDProc()); | |
| 1357 if((parseRegionInfo(&ri) != JBIG2_SUCCESS) | |
| 1358 || (m_pStream->read1Byte(&cFlags) != 0) | |
| 1359 || (m_pStream->readInteger(&pHRD->HGW) != 0) | |
| 1360 || (m_pStream->readInteger(&pHRD->HGH) != 0) | |
| 1361 || (m_pStream->readInteger((FX_DWORD*)&pHRD->HGX) != 0) | |
| 1362 || (m_pStream->readInteger((FX_DWORD*)&pHRD->HGY) != 0) | |
| 1363 || (m_pStream->readShortInteger(&pHRD->HRX) != 0) | |
| 1364 || (m_pStream->readShortInteger(&pHRD->HRY) != 0)) { | |
| 1365 m_pModule->JBig2_Error("halftone region segment : data header too short.
"); | |
| 1366 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 1367 goto failed; | |
| 1368 } | |
| 1369 pHRD->HBW = ri.width; | |
| 1370 pHRD->HBH = ri.height; | |
| 1371 pHRD->HMMR = cFlags & 0x01; | |
| 1372 pHRD->HTEMPLATE = (cFlags >> 1) & 0x03; | |
| 1373 pHRD->HENABLESKIP = (cFlags >> 3) & 0x01; | |
| 1374 pHRD->HCOMBOP = (JBig2ComposeOp)((cFlags >> 4) & 0x07); | |
| 1375 pHRD->HDEFPIXEL = (cFlags >> 7) & 0x01; | |
| 1376 if(pSegment->m_nReferred_to_segment_count != 1) { | |
| 1377 m_pModule->JBig2_Error("halftone region segment : refered to segment cou
nt not equals 1"); | |
| 1378 nRet = JBIG2_ERROR_FETAL; | |
| 1379 goto failed; | |
| 1380 } | |
| 1381 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[0]); | |
| 1382 if( (pSeg == NULL) || (pSeg->m_cFlags.s.type != 16)) { | |
| 1383 m_pModule->JBig2_Error("halftone region segment : refered to segment is
not pattern dict"); | |
| 1384 nRet = JBIG2_ERROR_FETAL; | |
| 1385 goto failed; | |
| 1386 } | |
| 1387 pPatternDict = pSeg->m_Result.pd; | |
| 1388 if((pPatternDict == NULL) || (pPatternDict->NUMPATS == 0)) { | |
| 1389 m_pModule->JBig2_Error("halftone region segment : has no patterns input"
); | |
| 1390 nRet = JBIG2_ERROR_FETAL; | |
| 1391 goto failed; | |
| 1392 } | |
| 1393 pHRD->HNUMPATS = pPatternDict->NUMPATS; | |
| 1394 pHRD->HPATS = pPatternDict->HDPATS; | |
| 1395 pHRD->HPW = pPatternDict->HDPATS[0]->m_nWidth; | |
| 1396 pHRD->HPH = pPatternDict->HDPATS[0]->m_nHeight; | |
| 1397 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; | |
| 1398 if(pHRD->HMMR == 0) { | |
| 1399 dwTemp = pHRD->HTEMPLATE == 0 ? 65536 : pHRD->HTEMPLATE == 1 ? 8192 : 10
24; | |
| 1400 gbContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2ArithCt
x), dwTemp); | |
| 1401 JBIG2_memset(gbContext, 0, sizeof(JBig2ArithCtx)*dwTemp); | |
| 1402 JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(m_pStream)); | |
| 1403 pSegment->m_Result.im = pHRD->decode_Arith(pArithDecoder, gbContext, pPa
use); | |
| 1404 delete pArithDecoder; | |
| 1405 if(pSegment->m_Result.im == NULL) { | |
| 1406 m_pModule->JBig2_Free(gbContext); | |
| 1407 nRet = JBIG2_ERROR_FETAL; | |
| 1408 goto failed; | |
| 1409 } | |
| 1410 m_pModule->JBig2_Free(gbContext); | |
| 1411 m_pStream->alignByte(); | |
| 1412 m_pStream->offset(2); | |
| 1413 } else { | |
| 1414 pSegment->m_Result.im = pHRD->decode_MMR(m_pStream, pPause); | |
| 1415 if(pSegment->m_Result.im == NULL) { | |
| 1416 nRet = JBIG2_ERROR_FETAL; | |
| 1417 goto failed; | |
| 1418 } | |
| 1419 m_pStream->alignByte(); | |
| 1420 } | |
| 1421 if(pSegment->m_cFlags.s.type != 20) { | |
| 1422 if(!m_bBufSpecified) { | |
| 1423 JBig2PageInfo *pPageInfo = m_pPageInfoList->getLast(); | |
| 1424 if ((pPageInfo->m_bIsStriped == 1) && (ri.y + ri.height > m_pPage->m
_nHeight)) { | |
| 1425 m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1
: 0); | |
| 1426 } | |
| 1427 } | |
| 1428 m_pPage->composeFrom(ri.x, ri.y, pSegment->m_Result.im, (JBig2ComposeOp)
(ri.flags & 0x03)); | |
| 1429 delete pSegment->m_Result.im; | |
| 1430 pSegment->m_Result.im = NULL; | |
| 1431 } | |
| 1432 delete pHRD; | |
| 1433 return JBIG2_SUCCESS; | |
| 1434 failed: | |
| 1435 delete pHRD; | |
| 1436 return nRet; | |
| 1437 } | |
| 1438 | |
| 1439 FX_BOOL CJBig2_Context::parseGenericRegion(CJBig2_Segment *pSegment, IFX_Pause*
pPause) | |
| 1440 { | |
| 1441 FX_DWORD dwTemp; | |
| 1442 FX_BYTE cFlags; | |
| 1443 FX_INT32 i, nRet; | |
| 1444 if(m_pGRD == NULL) { | |
| 1445 JBIG2_ALLOC(m_pGRD, CJBig2_GRDProc()); | |
| 1446 if((parseRegionInfo(&m_ri) != JBIG2_SUCCESS) | |
| 1447 || (m_pStream->read1Byte(&cFlags) != 0)) { | |
| 1448 m_pModule->JBig2_Error("generic region segment : data header too sho
rt."); | |
| 1449 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 1450 goto failed; | |
| 1451 } | |
| 1452 if (m_ri.height < 0 || m_ri.width < 0) { | |
| 1453 m_pModule->JBig2_Error("generic region segment : wrong data."); | |
| 1454 nRet = JBIG2_FAILED; | |
| 1455 goto failed; | |
| 1456 } | |
| 1457 m_pGRD->GBW = m_ri.width; | |
| 1458 m_pGRD->GBH = m_ri.height; | |
| 1459 m_pGRD->MMR = cFlags & 0x01; | |
| 1460 m_pGRD->GBTEMPLATE = (cFlags >> 1) & 0x03; | |
| 1461 m_pGRD->TPGDON = (cFlags >> 3) & 0x01; | |
| 1462 if(m_pGRD->MMR == 0) { | |
| 1463 if(m_pGRD->GBTEMPLATE == 0) { | |
| 1464 for(i = 0; i < 8; i++) { | |
| 1465 if(m_pStream->read1Byte((FX_BYTE*)&m_pGRD->GBAT[i]) != 0) { | |
| 1466 m_pModule->JBig2_Error("generic region segment : data he
ader too short."); | |
| 1467 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 1468 goto failed; | |
| 1469 } | |
| 1470 } | |
| 1471 } else { | |
| 1472 for(i = 0; i < 2; i++) { | |
| 1473 if(m_pStream->read1Byte((FX_BYTE*)&m_pGRD->GBAT[i]) != 0) { | |
| 1474 m_pModule->JBig2_Error("generic region segment : data he
ader too short."); | |
| 1475 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 1476 goto failed; | |
| 1477 } | |
| 1478 } | |
| 1479 } | |
| 1480 } | |
| 1481 m_pGRD->USESKIP = 0; | |
| 1482 } | |
| 1483 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; | |
| 1484 if(m_pGRD->MMR == 0) { | |
| 1485 dwTemp = m_pGRD->GBTEMPLATE == 0 ? 65536 : m_pGRD->GBTEMPLATE == 1 ? 819
2 : 1024; | |
| 1486 if(m_gbContext == NULL) { | |
| 1487 m_gbContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc(sizeof(JBig2Ar
ithCtx) * dwTemp); | |
| 1488 JBIG2_memset(m_gbContext, 0, sizeof(JBig2ArithCtx)*dwTemp); | |
| 1489 } | |
| 1490 if(m_pArithDecoder == NULL) { | |
| 1491 JBIG2_ALLOC(m_pArithDecoder, CJBig2_ArithDecoder(m_pStream)); | |
| 1492 m_ProcessiveStatus = m_pGRD->Start_decode_Arith(&pSegment->m_Result.
im, m_pArithDecoder, m_gbContext, pPause); | |
| 1493 } else { | |
| 1494 m_ProcessiveStatus = m_pGRD->Continue_decode(pPause); | |
| 1495 } | |
| 1496 OutputBitmap(pSegment->m_Result.im); | |
| 1497 if(m_ProcessiveStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) { | |
| 1498 if(pSegment->m_cFlags.s.type != 36) { | |
| 1499 if(!m_bBufSpecified) { | |
| 1500 JBig2PageInfo *pPageInfo = m_pPageInfoList->getLast(); | |
| 1501 if ((pPageInfo->m_bIsStriped == 1) && (m_ri.y + m_ri.height
> m_pPage->m_nHeight)) { | |
| 1502 m_pPage->expand(m_ri.y + m_ri.height, (pPageInfo->m_cFla
gs & 4) ? 1 : 0); | |
| 1503 } | |
| 1504 } | |
| 1505 FX_RECT Rect = m_pGRD->GetReplaceRect(); | |
| 1506 m_pPage->composeFrom(m_ri.x + Rect.left, m_ri.y + Rect.top, pSeg
ment->m_Result.im, (JBig2ComposeOp)(m_ri.flags & 0x03), &Rect); | |
| 1507 } | |
| 1508 return JBIG2_SUCCESS; | |
| 1509 } else { | |
| 1510 delete m_pArithDecoder; | |
| 1511 m_pArithDecoder = NULL; | |
| 1512 if(pSegment->m_Result.im == NULL) { | |
| 1513 m_pModule->JBig2_Free(m_gbContext); | |
| 1514 nRet = JBIG2_ERROR_FETAL; | |
| 1515 m_gbContext = NULL; | |
| 1516 m_ProcessiveStatus = FXCODEC_STATUS_ERROR; | |
| 1517 goto failed; | |
| 1518 } | |
| 1519 m_pModule->JBig2_Free(m_gbContext); | |
| 1520 m_gbContext = NULL; | |
| 1521 m_pStream->alignByte(); | |
| 1522 m_pStream->offset(2); | |
| 1523 } | |
| 1524 } else { | |
| 1525 FXCODEC_STATUS status = m_pGRD->Start_decode_MMR(&pSegment->m_Result.im,
m_pStream, pPause); | |
| 1526 while(status == FXCODEC_STATUS_DECODE_TOBECONTINUE) { | |
| 1527 m_pGRD->Continue_decode(pPause); | |
| 1528 } | |
| 1529 if(pSegment->m_Result.im == NULL) { | |
| 1530 nRet = JBIG2_ERROR_FETAL; | |
| 1531 goto failed; | |
| 1532 } | |
| 1533 m_pStream->alignByte(); | |
| 1534 } | |
| 1535 if(pSegment->m_cFlags.s.type != 36) { | |
| 1536 if(!m_bBufSpecified) { | |
| 1537 JBig2PageInfo *pPageInfo = m_pPageInfoList->getLast(); | |
| 1538 if ((pPageInfo->m_bIsStriped == 1) && (m_ri.y + m_ri.height > m_pPag
e->m_nHeight)) { | |
| 1539 m_pPage->expand(m_ri.y + m_ri.height, (pPageInfo->m_cFlags & 4)
? 1 : 0); | |
| 1540 } | |
| 1541 } | 1645 } |
| 1542 FX_RECT Rect = m_pGRD->GetReplaceRect(); | 1646 FX_RECT Rect = m_pGRD->GetReplaceRect(); |
| 1543 m_pPage->composeFrom(m_ri.x + Rect.left, m_ri.y + Rect.top, pSegment->m_
Result.im, (JBig2ComposeOp)(m_ri.flags & 0x03), &Rect); | 1647 m_pPage->composeFrom(m_ri.x + Rect.left, |
| 1544 delete pSegment->m_Result.im; | 1648 m_ri.y + Rect.top, |
| 1545 pSegment->m_Result.im = NULL; | 1649 pSegment->m_Result.im, |
| 1546 } | 1650 (JBig2ComposeOp)(m_ri.flags & 0x03), |
| 1547 delete m_pGRD; | 1651 &Rect); |
| 1548 m_pGRD = NULL; | 1652 } |
| 1549 return JBIG2_SUCCESS; | 1653 return JBIG2_SUCCESS; |
| 1654 } else { |
| 1655 delete m_pArithDecoder; |
| 1656 m_pArithDecoder = NULL; |
| 1657 if (pSegment->m_Result.im == NULL) { |
| 1658 m_pModule->JBig2_Free(m_gbContext); |
| 1659 nRet = JBIG2_ERROR_FETAL; |
| 1660 m_gbContext = NULL; |
| 1661 m_ProcessiveStatus = FXCODEC_STATUS_ERROR; |
| 1662 goto failed; |
| 1663 } |
| 1664 m_pModule->JBig2_Free(m_gbContext); |
| 1665 m_gbContext = NULL; |
| 1666 m_pStream->alignByte(); |
| 1667 m_pStream->offset(2); |
| 1668 } |
| 1669 } else { |
| 1670 FXCODEC_STATUS status = |
| 1671 m_pGRD->Start_decode_MMR(&pSegment->m_Result.im, m_pStream, pPause); |
| 1672 while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) { |
| 1673 m_pGRD->Continue_decode(pPause); |
| 1674 } |
| 1675 if (pSegment->m_Result.im == NULL) { |
| 1676 nRet = JBIG2_ERROR_FETAL; |
| 1677 goto failed; |
| 1678 } |
| 1679 m_pStream->alignByte(); |
| 1680 } |
| 1681 if (pSegment->m_cFlags.s.type != 36) { |
| 1682 if (!m_bBufSpecified) { |
| 1683 JBig2PageInfo* pPageInfo = m_pPageInfoList->getLast(); |
| 1684 if ((pPageInfo->m_bIsStriped == 1) && |
| 1685 (m_ri.y + m_ri.height > m_pPage->m_nHeight)) { |
| 1686 m_pPage->expand(m_ri.y + m_ri.height, |
| 1687 (pPageInfo->m_cFlags & 4) ? 1 : 0); |
| 1688 } |
| 1689 } |
| 1690 FX_RECT Rect = m_pGRD->GetReplaceRect(); |
| 1691 m_pPage->composeFrom(m_ri.x + Rect.left, |
| 1692 m_ri.y + Rect.top, |
| 1693 pSegment->m_Result.im, |
| 1694 (JBig2ComposeOp)(m_ri.flags & 0x03), |
| 1695 &Rect); |
| 1696 delete pSegment->m_Result.im; |
| 1697 pSegment->m_Result.im = NULL; |
| 1698 } |
| 1699 delete m_pGRD; |
| 1700 m_pGRD = NULL; |
| 1701 return JBIG2_SUCCESS; |
| 1550 failed: | 1702 failed: |
| 1551 delete m_pGRD; | 1703 delete m_pGRD; |
| 1552 m_pGRD = NULL; | 1704 m_pGRD = NULL; |
| 1553 return nRet; | 1705 return nRet; |
| 1554 } | 1706 } |
| 1555 | 1707 |
| 1556 FX_BOOL CJBig2_Context::parseGenericRefinementRegion(CJBig2_Segment *pSegment) | 1708 FX_BOOL CJBig2_Context::parseGenericRefinementRegion(CJBig2_Segment* pSegment) { |
| 1557 { | 1709 FX_DWORD dwTemp; |
| 1558 FX_DWORD dwTemp; | 1710 JBig2RegionInfo ri; |
| 1559 JBig2RegionInfo ri; | 1711 CJBig2_Segment* pSeg; |
| 1560 CJBig2_Segment *pSeg; | 1712 FX_INT32 i, nRet; |
| 1561 FX_INT32 i, nRet; | 1713 FX_BYTE cFlags; |
| 1562 FX_BYTE cFlags; | 1714 JBig2ArithCtx* grContext; |
| 1563 JBig2ArithCtx *grContext; | 1715 CJBig2_GRRDProc* pGRRD; |
| 1564 CJBig2_GRRDProc *pGRRD; | 1716 CJBig2_ArithDecoder* pArithDecoder; |
| 1565 CJBig2_ArithDecoder *pArithDecoder; | 1717 JBIG2_ALLOC(pGRRD, CJBig2_GRRDProc()); |
| 1566 JBIG2_ALLOC(pGRRD, CJBig2_GRRDProc()); | 1718 if ((parseRegionInfo(&ri) != JBIG2_SUCCESS) || |
| 1567 if((parseRegionInfo(&ri) != JBIG2_SUCCESS) | 1719 (m_pStream->read1Byte(&cFlags) != 0)) { |
| 1568 || (m_pStream->read1Byte(&cFlags) != 0)) { | 1720 m_pModule->JBig2_Error( |
| 1569 m_pModule->JBig2_Error("generic refinement region segment : data header
too short."); | 1721 "generic refinement region segment : data header too short."); |
| 1722 nRet = JBIG2_ERROR_TOO_SHORT; |
| 1723 goto failed; |
| 1724 } |
| 1725 pGRRD->GRW = ri.width; |
| 1726 pGRRD->GRH = ri.height; |
| 1727 pGRRD->GRTEMPLATE = cFlags & 0x01; |
| 1728 pGRRD->TPGRON = (cFlags >> 1) & 0x01; |
| 1729 if (pGRRD->GRTEMPLATE == 0) { |
| 1730 for (i = 0; i < 4; i++) { |
| 1731 if (m_pStream->read1Byte((FX_BYTE*)&pGRRD->GRAT[i]) != 0) { |
| 1732 m_pModule->JBig2_Error( |
| 1733 "generic refinement region segment : data header too short."); |
| 1570 nRet = JBIG2_ERROR_TOO_SHORT; | 1734 nRet = JBIG2_ERROR_TOO_SHORT; |
| 1571 goto failed; | 1735 goto failed; |
| 1572 } | 1736 } |
| 1573 pGRRD->GRW = ri.width; | 1737 } |
| 1574 pGRRD->GRH = ri.height; | 1738 } |
| 1575 pGRRD->GRTEMPLATE = cFlags & 0x01; | 1739 pSeg = NULL; |
| 1576 pGRRD->TPGRON = (cFlags >> 1) & 0x01; | 1740 if (pSegment->m_nReferred_to_segment_count > 0) { |
| 1577 if(pGRRD->GRTEMPLATE == 0) { | 1741 for (i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { |
| 1578 for(i = 0; i < 4; i++) { | 1742 pSeg = this->findSegmentByNumber( |
| 1579 if(m_pStream->read1Byte((FX_BYTE*)&pGRRD->GRAT[i]) != 0) { | 1743 pSegment->m_pReferred_to_segment_numbers[0]); |
| 1580 m_pModule->JBig2_Error("generic refinement region segment : data
header too short."); | 1744 if (pSeg == NULL) { |
| 1581 nRet = JBIG2_ERROR_TOO_SHORT; | 1745 m_pModule->JBig2_Error( |
| 1582 goto failed; | 1746 "generic refinement region segment : can't find refered to " |
| 1583 } | 1747 "segments"); |
| 1748 nRet = JBIG2_ERROR_FETAL; |
| 1749 goto failed; |
| 1750 } |
| 1751 if ((pSeg->m_cFlags.s.type == 4) || (pSeg->m_cFlags.s.type == 20) || |
| 1752 (pSeg->m_cFlags.s.type == 36) || (pSeg->m_cFlags.s.type == 40)) { |
| 1753 break; |
| 1754 } |
| 1755 } |
| 1756 if (i >= pSegment->m_nReferred_to_segment_count) { |
| 1757 m_pModule->JBig2_Error( |
| 1758 "generic refinement region segment : can't find refered to " |
| 1759 "intermediate region"); |
| 1760 nRet = JBIG2_ERROR_FETAL; |
| 1761 goto failed; |
| 1762 } |
| 1763 pGRRD->GRREFERENCE = pSeg->m_Result.im; |
| 1764 } else { |
| 1765 pGRRD->GRREFERENCE = m_pPage; |
| 1766 } |
| 1767 pGRRD->GRREFERENCEDX = 0; |
| 1768 pGRRD->GRREFERENCEDY = 0; |
| 1769 dwTemp = pGRRD->GRTEMPLATE ? 1 << 10 : 1 << 13; |
| 1770 grContext = |
| 1771 (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2ArithCtx), dwTemp); |
| 1772 JBIG2_memset(grContext, 0, sizeof(JBig2ArithCtx) * dwTemp); |
| 1773 JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(m_pStream)); |
| 1774 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; |
| 1775 pSegment->m_Result.im = pGRRD->decode(pArithDecoder, grContext); |
| 1776 delete pArithDecoder; |
| 1777 if (pSegment->m_Result.im == NULL) { |
| 1778 m_pModule->JBig2_Free(grContext); |
| 1779 nRet = JBIG2_ERROR_FETAL; |
| 1780 goto failed; |
| 1781 } |
| 1782 m_pModule->JBig2_Free(grContext); |
| 1783 m_pStream->alignByte(); |
| 1784 m_pStream->offset(2); |
| 1785 if (pSegment->m_cFlags.s.type != 40) { |
| 1786 if (!m_bBufSpecified) { |
| 1787 JBig2PageInfo* pPageInfo = m_pPageInfoList->getLast(); |
| 1788 if ((pPageInfo->m_bIsStriped == 1) && |
| 1789 (ri.y + ri.height > m_pPage->m_nHeight)) { |
| 1790 m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0); |
| 1791 } |
| 1792 } |
| 1793 m_pPage->composeFrom( |
| 1794 ri.x, ri.y, pSegment->m_Result.im, (JBig2ComposeOp)(ri.flags & 0x03)); |
| 1795 delete pSegment->m_Result.im; |
| 1796 pSegment->m_Result.im = NULL; |
| 1797 } |
| 1798 delete pGRRD; |
| 1799 return JBIG2_SUCCESS; |
| 1800 failed: |
| 1801 delete pGRRD; |
| 1802 return nRet; |
| 1803 } |
| 1804 FX_BOOL CJBig2_Context::parseTable(CJBig2_Segment* pSegment) { |
| 1805 pSegment->m_nResultType = JBIG2_HUFFMAN_TABLE_POINTER; |
| 1806 JBIG2_ALLOC(pSegment->m_Result.ht, CJBig2_HuffmanTable(m_pStream)); |
| 1807 if (!pSegment->m_Result.ht->isOK()) { |
| 1808 delete pSegment->m_Result.ht; |
| 1809 pSegment->m_Result.ht = NULL; |
| 1810 return JBIG2_ERROR_FETAL; |
| 1811 } |
| 1812 m_pStream->alignByte(); |
| 1813 return JBIG2_SUCCESS; |
| 1814 } |
| 1815 FX_INT32 CJBig2_Context::parseRegionInfo(JBig2RegionInfo* pRI) { |
| 1816 if ((m_pStream->readInteger((FX_DWORD*)&pRI->width) != 0) || |
| 1817 (m_pStream->readInteger((FX_DWORD*)&pRI->height) != 0) || |
| 1818 (m_pStream->readInteger((FX_DWORD*)&pRI->x) != 0) || |
| 1819 (m_pStream->readInteger((FX_DWORD*)&pRI->y) != 0) || |
| 1820 (m_pStream->read1Byte(&pRI->flags) != 0)) { |
| 1821 return JBIG2_ERROR_TOO_SHORT; |
| 1822 } |
| 1823 return JBIG2_SUCCESS; |
| 1824 } |
| 1825 JBig2HuffmanCode* CJBig2_Context::decodeSymbolIDHuffmanTable( |
| 1826 CJBig2_BitStream* pStream, |
| 1827 FX_DWORD SBNUMSYMS) { |
| 1828 JBig2HuffmanCode* SBSYMCODES; |
| 1829 FX_INT32 runcodes[35], runcodes_len[35], runcode; |
| 1830 FX_INT32 i, j, nTemp, nVal, nBits; |
| 1831 FX_INT32 run; |
| 1832 SBSYMCODES = (JBig2HuffmanCode*)m_pModule->JBig2_Malloc2( |
| 1833 sizeof(JBig2HuffmanCode), SBNUMSYMS); |
| 1834 for (i = 0; i < 35; i++) { |
| 1835 if (pStream->readNBits(4, &runcodes_len[i]) != 0) { |
| 1836 goto failed; |
| 1837 } |
| 1838 } |
| 1839 huffman_assign_code(runcodes, runcodes_len, 35); |
| 1840 i = 0; |
| 1841 while (i < (int)SBNUMSYMS) { |
| 1842 nVal = 0; |
| 1843 nBits = 0; |
| 1844 for (;;) { |
| 1845 if (pStream->read1Bit(&nTemp) != 0) { |
| 1846 goto failed; |
| 1847 } |
| 1848 nVal = (nVal << 1) | nTemp; |
| 1849 nBits++; |
| 1850 for (j = 0; j < 35; j++) { |
| 1851 if ((nBits == runcodes_len[j]) && (nVal == runcodes[j])) { |
| 1852 break; |
| 1584 } | 1853 } |
| 1585 } | 1854 } |
| 1586 pSeg = NULL; | 1855 if (j < 35) { |
| 1587 if(pSegment->m_nReferred_to_segment_count > 0) { | 1856 break; |
| 1588 for(i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | 1857 } |
| 1589 pSeg = this->findSegmentByNumber(pSegment->m_pReferred_to_segment_nu
mbers[0]); | 1858 } |
| 1590 if(pSeg == NULL) { | 1859 runcode = j; |
| 1591 m_pModule->JBig2_Error("generic refinement region segment : can'
t find refered to segments"); | 1860 if (runcode < 32) { |
| 1592 nRet = JBIG2_ERROR_FETAL; | 1861 SBSYMCODES[i].codelen = runcode; |
| 1593 goto failed; | 1862 run = 0; |
| 1594 } | 1863 } else if (runcode == 32) { |
| 1595 if((pSeg->m_cFlags.s.type == 4) || (pSeg->m_cFlags.s.type == 20) | 1864 if (pStream->readNBits(2, &nTemp) != 0) { |
| 1596 || (pSeg->m_cFlags.s.type == 36) || (pSeg->m_cFlags.s.type =
= 40)) { | 1865 goto failed; |
| 1597 break; | 1866 } |
| 1598 } | 1867 run = nTemp + 3; |
| 1868 } else if (runcode == 33) { |
| 1869 if (pStream->readNBits(3, &nTemp) != 0) { |
| 1870 goto failed; |
| 1871 } |
| 1872 run = nTemp + 3; |
| 1873 } else if (runcode == 34) { |
| 1874 if (pStream->readNBits(7, &nTemp) != 0) { |
| 1875 goto failed; |
| 1876 } |
| 1877 run = nTemp + 11; |
| 1878 } |
| 1879 if (run > 0) { |
| 1880 if (i + run > (int)SBNUMSYMS) { |
| 1881 goto failed; |
| 1882 } |
| 1883 for (j = 0; j < run; j++) { |
| 1884 if (runcode == 32 && i > 0) { |
| 1885 SBSYMCODES[i + j].codelen = SBSYMCODES[i - 1].codelen; |
| 1886 } else { |
| 1887 SBSYMCODES[i + j].codelen = 0; |
| 1599 } | 1888 } |
| 1600 if(i >= pSegment->m_nReferred_to_segment_count) { | 1889 } |
| 1601 m_pModule->JBig2_Error("generic refinement region segment : can't fi
nd refered to intermediate region"); | 1890 i += run; |
| 1602 nRet = JBIG2_ERROR_FETAL; | |
| 1603 goto failed; | |
| 1604 } | |
| 1605 pGRRD->GRREFERENCE = pSeg->m_Result.im; | |
| 1606 } else { | 1891 } else { |
| 1607 pGRRD->GRREFERENCE = m_pPage; | 1892 i++; |
| 1608 } | 1893 } |
| 1609 pGRRD->GRREFERENCEDX = 0; | 1894 } |
| 1610 pGRRD->GRREFERENCEDY = 0; | 1895 huffman_assign_code(SBSYMCODES, SBNUMSYMS); |
| 1611 dwTemp = pGRRD->GRTEMPLATE ? 1 << 10 : 1 << 13; | 1896 return SBSYMCODES; |
| 1612 grContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2ArithCtx),
dwTemp); | |
| 1613 JBIG2_memset(grContext, 0, sizeof(JBig2ArithCtx)*dwTemp); | |
| 1614 JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(m_pStream)); | |
| 1615 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; | |
| 1616 pSegment->m_Result.im = pGRRD->decode(pArithDecoder, grContext); | |
| 1617 delete pArithDecoder; | |
| 1618 if(pSegment->m_Result.im == NULL) { | |
| 1619 m_pModule->JBig2_Free(grContext); | |
| 1620 nRet = JBIG2_ERROR_FETAL; | |
| 1621 goto failed; | |
| 1622 } | |
| 1623 m_pModule->JBig2_Free(grContext); | |
| 1624 m_pStream->alignByte(); | |
| 1625 m_pStream->offset(2); | |
| 1626 if(pSegment->m_cFlags.s.type != 40) { | |
| 1627 if(!m_bBufSpecified) { | |
| 1628 JBig2PageInfo *pPageInfo = m_pPageInfoList->getLast(); | |
| 1629 if ((pPageInfo->m_bIsStriped == 1) && (ri.y + ri.height > m_pPage->m
_nHeight)) { | |
| 1630 m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1
: 0); | |
| 1631 } | |
| 1632 } | |
| 1633 m_pPage->composeFrom(ri.x, ri.y, pSegment->m_Result.im, (JBig2ComposeOp)
(ri.flags & 0x03)); | |
| 1634 delete pSegment->m_Result.im; | |
| 1635 pSegment->m_Result.im = NULL; | |
| 1636 } | |
| 1637 delete pGRRD; | |
| 1638 return JBIG2_SUCCESS; | |
| 1639 failed: | 1897 failed: |
| 1640 delete pGRRD; | 1898 m_pModule->JBig2_Free(SBSYMCODES); |
| 1641 return nRet; | 1899 return NULL; |
| 1642 } | 1900 } |
| 1643 FX_BOOL CJBig2_Context::parseTable(CJBig2_Segment *pSegment) | 1901 void CJBig2_Context::huffman_assign_code(int* CODES, int* PREFLEN, int NTEMP) { |
| 1644 { | 1902 int CURLEN, LENMAX, CURCODE, CURTEMP, i; |
| 1645 pSegment->m_nResultType = JBIG2_HUFFMAN_TABLE_POINTER; | 1903 int* LENCOUNT; |
| 1646 JBIG2_ALLOC(pSegment->m_Result.ht, CJBig2_HuffmanTable(m_pStream)); | 1904 int* FIRSTCODE; |
| 1647 if(!pSegment->m_Result.ht->isOK()) { | 1905 LENMAX = 0; |
| 1648 delete pSegment->m_Result.ht; | 1906 for (i = 0; i < NTEMP; i++) { |
| 1649 pSegment->m_Result.ht = NULL; | 1907 if (PREFLEN[i] > LENMAX) { |
| 1650 return JBIG2_ERROR_FETAL; | 1908 LENMAX = PREFLEN[i]; |
| 1651 } | 1909 } |
| 1652 m_pStream->alignByte(); | 1910 } |
| 1653 return JBIG2_SUCCESS; | 1911 LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1)); |
| 1654 } | 1912 JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1)); |
| 1655 FX_INT32 CJBig2_Context::parseRegionInfo(JBig2RegionInfo *pRI) | 1913 FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1)); |
| 1656 { | 1914 for (i = 0; i < NTEMP; i++) { |
| 1657 if((m_pStream->readInteger((FX_DWORD*)&pRI->width) != 0) | 1915 LENCOUNT[PREFLEN[i]]++; |
| 1658 || (m_pStream->readInteger((FX_DWORD*)&pRI->height) != 0) | 1916 } |
| 1659 || (m_pStream->readInteger((FX_DWORD*)&pRI->x) != 0) | 1917 CURLEN = 1; |
| 1660 || (m_pStream->readInteger((FX_DWORD*)&pRI->y) != 0) | 1918 FIRSTCODE[0] = 0; |
| 1661 || (m_pStream->read1Byte(&pRI->flags) != 0)) { | 1919 LENCOUNT[0] = 0; |
| 1662 return JBIG2_ERROR_TOO_SHORT; | 1920 while (CURLEN <= LENMAX) { |
| 1663 } | 1921 FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1; |
| 1664 return JBIG2_SUCCESS; | 1922 CURCODE = FIRSTCODE[CURLEN]; |
| 1665 } | 1923 CURTEMP = 0; |
| 1666 JBig2HuffmanCode *CJBig2_Context::decodeSymbolIDHuffmanTable(CJBig2_BitStream *p
Stream, | 1924 while (CURTEMP < NTEMP) { |
| 1667 FX_DWORD SBNUMSYMS) | 1925 if (PREFLEN[CURTEMP] == CURLEN) { |
| 1668 { | 1926 CODES[CURTEMP] = CURCODE; |
| 1669 JBig2HuffmanCode *SBSYMCODES; | 1927 CURCODE = CURCODE + 1; |
| 1670 FX_INT32 runcodes[35], runcodes_len[35], runcode; | 1928 } |
| 1671 FX_INT32 i, j, nTemp, nVal, nBits; | 1929 CURTEMP = CURTEMP + 1; |
| 1672 FX_INT32 run; | 1930 } |
| 1673 SBSYMCODES = (JBig2HuffmanCode*)m_pModule->JBig2_Malloc2(sizeof(JBig2Huffman
Code), SBNUMSYMS); | 1931 CURLEN = CURLEN + 1; |
| 1674 for (i = 0; i < 35; i ++) { | 1932 } |
| 1675 if(pStream->readNBits(4, &runcodes_len[i]) != 0) { | 1933 m_pModule->JBig2_Free(LENCOUNT); |
| 1676 goto failed; | 1934 m_pModule->JBig2_Free(FIRSTCODE); |
| 1677 } | 1935 } |
| 1678 } | 1936 void CJBig2_Context::huffman_assign_code(JBig2HuffmanCode* SBSYMCODES, |
| 1679 huffman_assign_code(runcodes, runcodes_len, 35); | 1937 int NTEMP) { |
| 1680 i = 0; | 1938 int CURLEN, LENMAX, CURCODE, CURTEMP, i; |
| 1681 while(i < (int)SBNUMSYMS) { | 1939 int* LENCOUNT; |
| 1682 nVal = 0; | 1940 int* FIRSTCODE; |
| 1683 nBits = 0; | 1941 LENMAX = 0; |
| 1684 for(;;) { | 1942 for (i = 0; i < NTEMP; i++) { |
| 1685 if(pStream->read1Bit(&nTemp) != 0) { | 1943 if (SBSYMCODES[i].codelen > LENMAX) { |
| 1686 goto failed; | 1944 LENMAX = SBSYMCODES[i].codelen; |
| 1687 } | 1945 } |
| 1688 nVal = (nVal << 1) | nTemp; | 1946 } |
| 1689 nBits ++; | 1947 LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1)); |
| 1690 for(j = 0; j < 35; j++) { | 1948 JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1)); |
| 1691 if((nBits == runcodes_len[j]) && (nVal == runcodes[j])) { | 1949 FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1)); |
| 1692 break; | 1950 for (i = 0; i < NTEMP; i++) { |
| 1693 } | 1951 LENCOUNT[SBSYMCODES[i].codelen]++; |
| 1694 } | 1952 } |
| 1695 if(j < 35) { | 1953 CURLEN = 1; |
| 1696 break; | 1954 FIRSTCODE[0] = 0; |
| 1697 } | 1955 LENCOUNT[0] = 0; |
| 1698 } | 1956 while (CURLEN <= LENMAX) { |
| 1699 runcode = j; | 1957 FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1; |
| 1700 if(runcode < 32) { | 1958 CURCODE = FIRSTCODE[CURLEN]; |
| 1701 SBSYMCODES[i].codelen = runcode; | 1959 CURTEMP = 0; |
| 1702 run = 0; | 1960 while (CURTEMP < NTEMP) { |
| 1703 } else if(runcode == 32) { | 1961 if (SBSYMCODES[CURTEMP].codelen == CURLEN) { |
| 1704 if(pStream->readNBits(2, &nTemp) != 0) { | 1962 SBSYMCODES[CURTEMP].code = CURCODE; |
| 1705 goto failed; | 1963 CURCODE = CURCODE + 1; |
| 1706 } | 1964 } |
| 1707 run = nTemp + 3; | 1965 CURTEMP = CURTEMP + 1; |
| 1708 } else if(runcode == 33) { | 1966 } |
| 1709 if(pStream->readNBits(3, &nTemp) != 0) { | 1967 CURLEN = CURLEN + 1; |
| 1710 goto failed; | 1968 } |
| 1711 } | 1969 m_pModule->JBig2_Free(LENCOUNT); |
| 1712 run = nTemp + 3; | 1970 m_pModule->JBig2_Free(FIRSTCODE); |
| 1713 } else if(runcode == 34) { | 1971 } |
| 1714 if(pStream->readNBits(7, &nTemp) != 0) { | |
| 1715 goto failed; | |
| 1716 } | |
| 1717 run = nTemp + 11; | |
| 1718 } | |
| 1719 if(run > 0) { | |
| 1720 if (i + run > (int)SBNUMSYMS) { | |
| 1721 goto failed; | |
| 1722 } | |
| 1723 for(j = 0; j < run; j++) { | |
| 1724 if(runcode == 32 && i > 0) { | |
| 1725 SBSYMCODES[i + j].codelen = SBSYMCODES[i - 1].codelen; | |
| 1726 } else { | |
| 1727 SBSYMCODES[i + j].codelen = 0; | |
| 1728 } | |
| 1729 } | |
| 1730 i += run; | |
| 1731 } else { | |
| 1732 i ++; | |
| 1733 } | |
| 1734 } | |
| 1735 huffman_assign_code(SBSYMCODES, SBNUMSYMS); | |
| 1736 return SBSYMCODES; | |
| 1737 failed: | |
| 1738 m_pModule->JBig2_Free(SBSYMCODES); | |
| 1739 return NULL; | |
| 1740 } | |
| 1741 void CJBig2_Context::huffman_assign_code(int* CODES, int* PREFLEN, int NTEMP) | |
| 1742 { | |
| 1743 int CURLEN, LENMAX, CURCODE, CURTEMP, i; | |
| 1744 int *LENCOUNT; | |
| 1745 int *FIRSTCODE; | |
| 1746 LENMAX = 0; | |
| 1747 for(i = 0; i < NTEMP; i++) { | |
| 1748 if(PREFLEN[i] > LENMAX) { | |
| 1749 LENMAX = PREFLEN[i]; | |
| 1750 } | |
| 1751 } | |
| 1752 LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1)); | |
| 1753 JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1)); | |
| 1754 FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1)); | |
| 1755 for(i = 0; i < NTEMP; i++) { | |
| 1756 LENCOUNT[PREFLEN[i]] ++; | |
| 1757 } | |
| 1758 CURLEN = 1; | |
| 1759 FIRSTCODE[0] = 0; | |
| 1760 LENCOUNT[0] = 0; | |
| 1761 while(CURLEN <= LENMAX) { | |
| 1762 FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1; | |
| 1763 CURCODE = FIRSTCODE[CURLEN]; | |
| 1764 CURTEMP = 0; | |
| 1765 while(CURTEMP < NTEMP) { | |
| 1766 if(PREFLEN[CURTEMP] == CURLEN) { | |
| 1767 CODES[CURTEMP] = CURCODE; | |
| 1768 CURCODE = CURCODE + 1; | |
| 1769 } | |
| 1770 CURTEMP = CURTEMP + 1; | |
| 1771 } | |
| 1772 CURLEN = CURLEN + 1; | |
| 1773 } | |
| 1774 m_pModule->JBig2_Free(LENCOUNT); | |
| 1775 m_pModule->JBig2_Free(FIRSTCODE); | |
| 1776 } | |
| 1777 void CJBig2_Context::huffman_assign_code(JBig2HuffmanCode *SBSYMCODES, int NTEMP
) | |
| 1778 { | |
| 1779 int CURLEN, LENMAX, CURCODE, CURTEMP, i; | |
| 1780 int *LENCOUNT; | |
| 1781 int *FIRSTCODE; | |
| 1782 LENMAX = 0; | |
| 1783 for(i = 0; i < NTEMP; i++) { | |
| 1784 if(SBSYMCODES[i].codelen > LENMAX) { | |
| 1785 LENMAX = SBSYMCODES[i].codelen; | |
| 1786 } | |
| 1787 } | |
| 1788 LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1)); | |
| 1789 JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1)); | |
| 1790 FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1)); | |
| 1791 for(i = 0; i < NTEMP; i++) { | |
| 1792 LENCOUNT[SBSYMCODES[i].codelen] ++; | |
| 1793 } | |
| 1794 CURLEN = 1; | |
| 1795 FIRSTCODE[0] = 0; | |
| 1796 LENCOUNT[0] = 0; | |
| 1797 while(CURLEN <= LENMAX) { | |
| 1798 FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1; | |
| 1799 CURCODE = FIRSTCODE[CURLEN]; | |
| 1800 CURTEMP = 0; | |
| 1801 while(CURTEMP < NTEMP) { | |
| 1802 if(SBSYMCODES[CURTEMP].codelen == CURLEN) { | |
| 1803 SBSYMCODES[CURTEMP].code = CURCODE; | |
| 1804 CURCODE = CURCODE + 1; | |
| 1805 } | |
| 1806 CURTEMP = CURTEMP + 1; | |
| 1807 } | |
| 1808 CURLEN = CURLEN + 1; | |
| 1809 } | |
| 1810 m_pModule->JBig2_Free(LENCOUNT); | |
| 1811 m_pModule->JBig2_Free(FIRSTCODE); | |
| 1812 } | |
| OLD | NEW |