| 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 |