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