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 |