| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "JBig2_Context.h" | 7 #include "JBig2_Context.h" |
| 8 | 8 |
| 9 #include <list> | 9 #include <list> |
| 10 | 10 |
| 11 #include "JBig2_GrdProc.h" | 11 #include "JBig2_GrdProc.h" |
| 12 #include "JBig2_GrrdProc.h" | 12 #include "JBig2_GrrdProc.h" |
| 13 #include "JBig2_HtrdProc.h" | 13 #include "JBig2_HtrdProc.h" |
| 14 #include "JBig2_PddProc.h" | 14 #include "JBig2_PddProc.h" |
| 15 #include "JBig2_SddProc.h" | 15 #include "JBig2_SddProc.h" |
| 16 #include "JBig2_TrdProc.h" | 16 #include "JBig2_TrdProc.h" |
| 17 | 17 |
| 18 namespace { |
| 19 |
| 20 size_t GetHuffContextSize(uint8_t val) { |
| 21 return val == 0 ? 65536 : val == 1 ? 8192 : 1024; |
| 22 } |
| 23 |
| 24 size_t GetRefAggContextSize(FX_BOOL val) { |
| 25 return val ? 1024 : 8192; |
| 26 } |
| 27 |
| 28 } // namespace |
| 29 |
| 18 // Implement a very small least recently used (LRU) cache. It is very | 30 // Implement a very small least recently used (LRU) cache. It is very |
| 19 // common for a JBIG2 dictionary to span multiple pages in a PDF file, | 31 // common for a JBIG2 dictionary to span multiple pages in a PDF file, |
| 20 // and we do not want to decode the same dictionary over and over | 32 // and we do not want to decode the same dictionary over and over |
| 21 // again. We key off of the memory location of the dictionary. The | 33 // again. We key off of the memory location of the dictionary. The |
| 22 // list keeps track of the freshness of entries, with freshest ones | 34 // list keeps track of the freshness of entries, with freshest ones |
| 23 // at the front. Even a tiny cache size like 2 makes a dramatic | 35 // at the front. Even a tiny cache size like 2 makes a dramatic |
| 24 // difference for typical JBIG2 documents. | 36 // difference for typical JBIG2 documents. |
| 25 // | 37 // |
| 26 // Disabled until we can figure out how to clear cache between documents. | 38 // Disabled until we can figure out how to clear cache between documents. |
| 27 // https://code.google.com/p/pdfium/issues/detail?id=207 | 39 // https://code.google.com/p/pdfium/issues/detail?id=207 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 50 const uint8_t* pData, | 62 const uint8_t* pData, |
| 51 FX_DWORD dwLength, | 63 FX_DWORD dwLength, |
| 52 std::list<CJBig2_CachePair>* pSymbolDictCache, | 64 std::list<CJBig2_CachePair>* pSymbolDictCache, |
| 53 IFX_Pause* pPause) | 65 IFX_Pause* pPause) |
| 54 : m_nSegmentDecoded(0), | 66 : m_nSegmentDecoded(0), |
| 55 m_bInPage(false), | 67 m_bInPage(false), |
| 56 m_bBufSpecified(false), | 68 m_bBufSpecified(false), |
| 57 m_PauseStep(10), | 69 m_PauseStep(10), |
| 58 m_pPause(pPause), | 70 m_pPause(pPause), |
| 59 m_ProcessingStatus(FXCODEC_STATUS_FRAME_READY), | 71 m_ProcessingStatus(FXCODEC_STATUS_FRAME_READY), |
| 60 m_pArithDecoder(NULL), | |
| 61 m_gbContext(NULL), | 72 m_gbContext(NULL), |
| 62 m_dwOffset(0), | 73 m_dwOffset(0), |
| 63 m_pSymbolDictCache(pSymbolDictCache) { | 74 m_pSymbolDictCache(pSymbolDictCache) { |
| 64 if (pGlobalData && (dwGlobalLength > 0)) { | 75 if (pGlobalData && (dwGlobalLength > 0)) { |
| 65 m_pGlobalContext = new CJBig2_Context( | 76 m_pGlobalContext = new CJBig2_Context( |
| 66 nullptr, 0, pGlobalData, dwGlobalLength, pSymbolDictCache, pPause); | 77 nullptr, 0, pGlobalData, dwGlobalLength, pSymbolDictCache, pPause); |
| 67 } else { | 78 } else { |
| 68 m_pGlobalContext = nullptr; | 79 m_pGlobalContext = nullptr; |
| 69 } | 80 } |
| 70 | 81 |
| 71 m_pStream.reset(new CJBig2_BitStream(pData, dwLength)); | 82 m_pStream.reset(new CJBig2_BitStream(pData, dwLength)); |
| 72 } | 83 } |
| 73 | 84 |
| 74 CJBig2_Context::~CJBig2_Context() { | 85 CJBig2_Context::~CJBig2_Context() { |
| 75 delete m_pArithDecoder; | |
| 76 m_pArithDecoder = NULL; | |
| 77 FX_Free(m_gbContext); | 86 FX_Free(m_gbContext); |
| 78 m_gbContext = NULL; | 87 m_gbContext = NULL; |
| 79 delete m_pGlobalContext; | 88 delete m_pGlobalContext; |
| 80 m_pGlobalContext = NULL; | 89 m_pGlobalContext = NULL; |
| 81 } | 90 } |
| 82 | 91 |
| 83 int32_t CJBig2_Context::decode_SquentialOrgnazation(IFX_Pause* pPause) { | 92 int32_t CJBig2_Context::decode_SquentialOrgnazation(IFX_Pause* pPause) { |
| 84 int32_t nRet; | 93 int32_t nRet; |
| 85 if (m_pStream->getByteLeft() <= 0) | 94 if (m_pStream->getByteLeft() <= 0) |
| 86 return JBIG2_END_OF_FILE; | 95 return JBIG2_END_OF_FILE; |
| 87 | 96 |
| 88 while (m_pStream->getByteLeft() >= JBIG2_MIN_SEGMENT_SIZE) { | 97 while (m_pStream->getByteLeft() >= JBIG2_MIN_SEGMENT_SIZE) { |
| 89 if (!m_pSegment) { | 98 if (!m_pSegment) { |
| 90 m_pSegment.reset(new CJBig2_Segment); | 99 m_pSegment.reset(new CJBig2_Segment); |
| 91 nRet = parseSegmentHeader(m_pSegment.get()); | 100 nRet = parseSegmentHeader(m_pSegment.get()); |
| 92 if (nRet != JBIG2_SUCCESS) { | 101 if (nRet != JBIG2_SUCCESS) { |
| 93 m_pSegment.reset(); | 102 m_pSegment.reset(); |
| 94 return nRet; | 103 return nRet; |
| 95 } | 104 } |
| 96 m_dwOffset = m_pStream->getOffset(); | 105 m_dwOffset = m_pStream->getOffset(); |
| 97 } | 106 } |
| 98 nRet = parseSegmentData(m_pSegment.get(), pPause); | 107 nRet = parseSegmentData(m_pSegment.get(), pPause); |
| 99 if (m_ProcessingStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) { | 108 if (m_ProcessingStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) { |
| 100 m_ProcessingStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; | 109 m_ProcessingStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
| 101 m_PauseStep = 2; | 110 m_PauseStep = 2; |
| 102 return JBIG2_SUCCESS; | 111 return JBIG2_SUCCESS; |
| 103 } | 112 } |
| 104 if ((nRet == JBIG2_END_OF_PAGE) || (nRet == JBIG2_END_OF_FILE)) { | 113 if (nRet == JBIG2_END_OF_PAGE || nRet == JBIG2_END_OF_FILE) { |
| 105 m_pSegment.reset(); | 114 m_pSegment.reset(); |
| 106 return JBIG2_SUCCESS; | 115 return JBIG2_SUCCESS; |
| 107 } | 116 } |
| 108 if (nRet != JBIG2_SUCCESS) { | 117 if (nRet != JBIG2_SUCCESS) { |
| 109 m_pSegment.reset(); | 118 m_pSegment.reset(); |
| 110 return nRet; | 119 return nRet; |
| 111 } | 120 } |
| 112 if (m_pSegment->m_dwData_length != 0xffffffff) { | 121 if (m_pSegment->m_dwData_length != 0xffffffff) { |
| 113 m_dwOffset += m_pSegment->m_dwData_length; | 122 m_dwOffset += m_pSegment->m_dwData_length; |
| 114 m_pStream->setOffset(m_dwOffset); | 123 m_pStream->setOffset(m_dwOffset); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 145 return JBIG2_SUCCESS; | 154 return JBIG2_SUCCESS; |
| 146 } | 155 } |
| 147 } | 156 } |
| 148 m_nSegmentDecoded = 0; | 157 m_nSegmentDecoded = 0; |
| 149 return decode_RandomOrgnazation(pPause); | 158 return decode_RandomOrgnazation(pPause); |
| 150 } | 159 } |
| 151 int32_t CJBig2_Context::decode_RandomOrgnazation(IFX_Pause* pPause) { | 160 int32_t CJBig2_Context::decode_RandomOrgnazation(IFX_Pause* pPause) { |
| 152 for (; m_nSegmentDecoded < m_SegmentList.size(); ++m_nSegmentDecoded) { | 161 for (; m_nSegmentDecoded < m_SegmentList.size(); ++m_nSegmentDecoded) { |
| 153 int32_t nRet = | 162 int32_t nRet = |
| 154 parseSegmentData(m_SegmentList.get(m_nSegmentDecoded), pPause); | 163 parseSegmentData(m_SegmentList.get(m_nSegmentDecoded), pPause); |
| 155 if ((nRet == JBIG2_END_OF_PAGE) || (nRet == JBIG2_END_OF_FILE)) | 164 if (nRet == JBIG2_END_OF_PAGE || nRet == JBIG2_END_OF_FILE) |
| 156 return JBIG2_SUCCESS; | 165 return JBIG2_SUCCESS; |
| 157 | 166 |
| 158 if (nRet != JBIG2_SUCCESS) | 167 if (nRet != JBIG2_SUCCESS) |
| 159 return nRet; | 168 return nRet; |
| 160 | 169 |
| 161 if (m_pPage && pPause && pPause->NeedToPauseNow()) { | 170 if (m_pPage && pPause && pPause->NeedToPauseNow()) { |
| 162 m_PauseStep = 4; | 171 m_PauseStep = 4; |
| 163 m_ProcessingStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; | 172 m_ProcessingStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
| 164 return JBIG2_SUCCESS; | 173 return JBIG2_SUCCESS; |
| 165 } | 174 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 } | 223 } |
| 215 if (nRet == JBIG2_SUCCESS) { | 224 if (nRet == JBIG2_SUCCESS) { |
| 216 m_ProcessingStatus = FXCODEC_STATUS_DECODE_FINISH; | 225 m_ProcessingStatus = FXCODEC_STATUS_DECODE_FINISH; |
| 217 } else { | 226 } else { |
| 218 m_ProcessingStatus = FXCODEC_STATUS_ERROR; | 227 m_ProcessingStatus = FXCODEC_STATUS_ERROR; |
| 219 } | 228 } |
| 220 return nRet; | 229 return nRet; |
| 221 } | 230 } |
| 222 | 231 |
| 223 CJBig2_Segment* CJBig2_Context::findSegmentByNumber(FX_DWORD dwNumber) { | 232 CJBig2_Segment* CJBig2_Context::findSegmentByNumber(FX_DWORD dwNumber) { |
| 224 CJBig2_Segment* pSeg; | |
| 225 if (m_pGlobalContext) { | 233 if (m_pGlobalContext) { |
| 226 pSeg = m_pGlobalContext->findSegmentByNumber(dwNumber); | 234 CJBig2_Segment* pSeg = m_pGlobalContext->findSegmentByNumber(dwNumber); |
| 227 if (pSeg) { | 235 if (pSeg) { |
| 228 return pSeg; | 236 return pSeg; |
| 229 } | 237 } |
| 230 } | 238 } |
| 231 for (size_t i = 0; i < m_SegmentList.size(); ++i) { | 239 for (size_t i = 0; i < m_SegmentList.size(); ++i) { |
| 232 pSeg = m_SegmentList.get(i); | 240 CJBig2_Segment* pSeg = m_SegmentList.get(i); |
| 233 if (pSeg->m_dwNumber == dwNumber) { | 241 if (pSeg->m_dwNumber == dwNumber) { |
| 234 return pSeg; | 242 return pSeg; |
| 235 } | 243 } |
| 236 } | 244 } |
| 237 return nullptr; | 245 return nullptr; |
| 238 } | 246 } |
| 239 CJBig2_Segment* CJBig2_Context::findReferredSegmentByTypeAndIndex( | 247 CJBig2_Segment* CJBig2_Context::findReferredSegmentByTypeAndIndex( |
| 240 CJBig2_Segment* pSegment, | 248 CJBig2_Segment* pSegment, |
| 241 uint8_t cType, | 249 uint8_t cType, |
| 242 int32_t nIndex) { | 250 int32_t nIndex) { |
| 243 CJBig2_Segment* pSeg; | 251 int32_t count = 0; |
| 244 int32_t i, count; | 252 for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
| 245 count = 0; | 253 CJBig2_Segment* pSeg = |
| 246 for (i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | 254 findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); |
| 247 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); | |
| 248 if (pSeg && pSeg->m_cFlags.s.type == cType) { | 255 if (pSeg && pSeg->m_cFlags.s.type == cType) { |
| 249 if (count == nIndex) { | 256 if (count == nIndex) |
| 250 return pSeg; | 257 return pSeg; |
| 251 } else { | 258 ++count; |
| 252 count++; | |
| 253 } | |
| 254 } | 259 } |
| 255 } | 260 } |
| 256 return NULL; | 261 return NULL; |
| 257 } | 262 } |
| 258 int32_t CJBig2_Context::parseSegmentHeader(CJBig2_Segment* pSegment) { | 263 int32_t CJBig2_Context::parseSegmentHeader(CJBig2_Segment* pSegment) { |
| 259 if ((m_pStream->readInteger(&pSegment->m_dwNumber) != 0) || | 264 if (m_pStream->readInteger(&pSegment->m_dwNumber) != 0 || |
| 260 (m_pStream->read1Byte(&pSegment->m_cFlags.c) != 0)) { | 265 m_pStream->read1Byte(&pSegment->m_cFlags.c) != 0) { |
| 261 return JBIG2_ERROR_TOO_SHORT; | 266 return JBIG2_ERROR_TOO_SHORT; |
| 262 } | 267 } |
| 263 | 268 |
| 264 FX_DWORD dwTemp; | 269 FX_DWORD dwTemp; |
| 265 uint8_t cTemp = m_pStream->getCurByte(); | 270 uint8_t cTemp = m_pStream->getCurByte(); |
| 266 if ((cTemp >> 5) == 7) { | 271 if ((cTemp >> 5) == 7) { |
| 267 if (m_pStream->readInteger( | 272 if (m_pStream->readInteger( |
| 268 (FX_DWORD*)&pSegment->m_nReferred_to_segment_count) != 0) { | 273 (FX_DWORD*)&pSegment->m_nReferred_to_segment_count) != 0) { |
| 269 return JBIG2_ERROR_TOO_SHORT; | 274 return JBIG2_ERROR_TOO_SHORT; |
| 270 } | 275 } |
| 271 pSegment->m_nReferred_to_segment_count &= 0x1fffffff; | 276 pSegment->m_nReferred_to_segment_count &= 0x1fffffff; |
| 272 if (pSegment->m_nReferred_to_segment_count > | 277 if (pSegment->m_nReferred_to_segment_count > |
| 273 JBIG2_MAX_REFERRED_SEGMENT_COUNT) { | 278 JBIG2_MAX_REFERRED_SEGMENT_COUNT) { |
| 274 return JBIG2_ERROR_LIMIT; | 279 return JBIG2_ERROR_LIMIT; |
| 275 } | 280 } |
| 276 dwTemp = 5 + 4 + (pSegment->m_nReferred_to_segment_count + 1) / 8; | 281 dwTemp = 5 + 4 + (pSegment->m_nReferred_to_segment_count + 1) / 8; |
| 277 } else { | 282 } else { |
| 278 if (m_pStream->read1Byte(&cTemp) != 0) | 283 if (m_pStream->read1Byte(&cTemp) != 0) |
| 279 return JBIG2_ERROR_TOO_SHORT; | 284 return JBIG2_ERROR_TOO_SHORT; |
| 280 | 285 |
| 281 pSegment->m_nReferred_to_segment_count = cTemp >> 5; | 286 pSegment->m_nReferred_to_segment_count = cTemp >> 5; |
| 282 dwTemp = 5 + 1; | 287 dwTemp = 5 + 1; |
| 283 } | 288 } |
| 284 uint8_t cSSize = | 289 uint8_t cSSize = |
| 285 pSegment->m_dwNumber > 65536 ? 4 : pSegment->m_dwNumber > 256 ? 2 : 1; | 290 pSegment->m_dwNumber > 65536 ? 4 : pSegment->m_dwNumber > 256 ? 2 : 1; |
| 286 uint8_t cPSize = pSegment->m_cFlags.s.page_association_size ? 4 : 1; | 291 uint8_t cPSize = pSegment->m_cFlags.s.page_association_size ? 4 : 1; |
| 287 if (pSegment->m_nReferred_to_segment_count) { | 292 if (pSegment->m_nReferred_to_segment_count) { |
| 288 pSegment->m_pReferred_to_segment_numbers = | 293 pSegment->m_pReferred_to_segment_numbers = |
| 289 FX_Alloc(FX_DWORD, pSegment->m_nReferred_to_segment_count); | 294 FX_Alloc(FX_DWORD, pSegment->m_nReferred_to_segment_count); |
| 290 for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | 295 for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
| 291 switch (cSSize) { | 296 switch (cSSize) { |
| 292 case 1: | 297 case 1: |
| 293 if (m_pStream->read1Byte(&cTemp) != 0) | 298 if (m_pStream->read1Byte(&cTemp) != 0) |
| 294 return JBIG2_ERROR_TOO_SHORT; | 299 return JBIG2_ERROR_TOO_SHORT; |
| 295 | 300 |
| 296 pSegment->m_pReferred_to_segment_numbers[i] = cTemp; | 301 pSegment->m_pReferred_to_segment_numbers[i] = cTemp; |
| 297 break; | 302 break; |
| 298 case 2: | 303 case 2: |
| 299 FX_WORD wTemp; | 304 FX_WORD wTemp; |
| 300 if (m_pStream->readShortInteger(&wTemp) != 0) | 305 if (m_pStream->readShortInteger(&wTemp) != 0) |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 return parseGenericRegion(pSegment, pPause); | 372 return parseGenericRegion(pSegment, pPause); |
| 368 case 40: | 373 case 40: |
| 369 case 42: | 374 case 42: |
| 370 case 43: | 375 case 43: |
| 371 if (!m_bInPage) | 376 if (!m_bInPage) |
| 372 return JBIG2_ERROR_FATAL; | 377 return JBIG2_ERROR_FATAL; |
| 373 return parseGenericRefinementRegion(pSegment); | 378 return parseGenericRefinementRegion(pSegment); |
| 374 case 48: { | 379 case 48: { |
| 375 FX_WORD wTemp; | 380 FX_WORD wTemp; |
| 376 nonstd::unique_ptr<JBig2PageInfo> pPageInfo(new JBig2PageInfo); | 381 nonstd::unique_ptr<JBig2PageInfo> pPageInfo(new JBig2PageInfo); |
| 377 if ((m_pStream->readInteger(&pPageInfo->m_dwWidth) != 0) || | 382 if (m_pStream->readInteger(&pPageInfo->m_dwWidth) != 0 || |
| 378 (m_pStream->readInteger(&pPageInfo->m_dwHeight) != 0) || | 383 m_pStream->readInteger(&pPageInfo->m_dwHeight) != 0 || |
| 379 (m_pStream->readInteger(&pPageInfo->m_dwResolutionX) != 0) || | 384 m_pStream->readInteger(&pPageInfo->m_dwResolutionX) != 0 || |
| 380 (m_pStream->readInteger(&pPageInfo->m_dwResolutionY) != 0) || | 385 m_pStream->readInteger(&pPageInfo->m_dwResolutionY) != 0 || |
| 381 (m_pStream->read1Byte(&pPageInfo->m_cFlags) != 0) || | 386 m_pStream->read1Byte(&pPageInfo->m_cFlags) != 0 || |
| 382 (m_pStream->readShortInteger(&wTemp) != 0)) { | 387 m_pStream->readShortInteger(&wTemp) != 0) { |
| 383 return JBIG2_ERROR_TOO_SHORT; | 388 return JBIG2_ERROR_TOO_SHORT; |
| 384 } | 389 } |
| 385 pPageInfo->m_bIsStriped = ((wTemp >> 15) & 1) ? TRUE : FALSE; | 390 pPageInfo->m_bIsStriped = ((wTemp >> 15) & 1) ? TRUE : FALSE; |
| 386 pPageInfo->m_wMaxStripeSize = wTemp & 0x7fff; | 391 pPageInfo->m_wMaxStripeSize = wTemp & 0x7fff; |
| 387 bool bMaxHeight = (pPageInfo->m_dwHeight == 0xffffffff); | 392 bool bMaxHeight = (pPageInfo->m_dwHeight == 0xffffffff); |
| 388 if (bMaxHeight && pPageInfo->m_bIsStriped != TRUE) | 393 if (bMaxHeight && pPageInfo->m_bIsStriped != TRUE) |
| 389 pPageInfo->m_bIsStriped = TRUE; | 394 pPageInfo->m_bIsStriped = TRUE; |
| 390 | 395 |
| 391 if (!m_bBufSpecified) { | 396 if (!m_bBufSpecified) { |
| 392 FX_DWORD height = | 397 FX_DWORD height = |
| (...skipping 28 matching lines...) Expand all Loading... |
| 421 m_pStream->offset(pSegment->m_dwData_length); | 426 m_pStream->offset(pSegment->m_dwData_length); |
| 422 break; | 427 break; |
| 423 default: | 428 default: |
| 424 break; | 429 break; |
| 425 } | 430 } |
| 426 return JBIG2_SUCCESS; | 431 return JBIG2_SUCCESS; |
| 427 } | 432 } |
| 428 | 433 |
| 429 int32_t CJBig2_Context::parseSymbolDict(CJBig2_Segment* pSegment, | 434 int32_t CJBig2_Context::parseSymbolDict(CJBig2_Segment* pSegment, |
| 430 IFX_Pause* pPause) { | 435 IFX_Pause* pPause) { |
| 431 FX_DWORD dwTemp; | |
| 432 FX_WORD wFlags; | 436 FX_WORD wFlags; |
| 433 uint8_t cSDHUFFDH, cSDHUFFDW, cSDHUFFBMSIZE, cSDHUFFAGGINST; | 437 if (m_pStream->readShortInteger(&wFlags) != 0) |
| 434 CJBig2_HuffmanTable* Table_B1 = nullptr; | 438 return JBIG2_ERROR_TOO_SHORT; |
| 435 CJBig2_HuffmanTable* Table_B2 = nullptr; | 439 |
| 436 CJBig2_HuffmanTable* Table_B3 = nullptr; | 440 nonstd::unique_ptr<CJBig2_SDDProc> pSymbolDictDecoder(new CJBig2_SDDProc); |
| 437 CJBig2_HuffmanTable* Table_B4 = nullptr; | |
| 438 CJBig2_HuffmanTable* Table_B5 = nullptr; | |
| 439 int32_t i, nIndex, nRet; | |
| 440 CJBig2_Segment* pSeg = nullptr; | |
| 441 CJBig2_Segment* pLRSeg = nullptr; | |
| 442 FX_BOOL bUsed; | |
| 443 CJBig2_Image** SDINSYMS = nullptr; | |
| 444 JBig2ArithCtx* gbContext = nullptr; | |
| 445 JBig2ArithCtx* grContext = nullptr; | |
| 446 CJBig2_ArithDecoder* pArithDecoder; | |
| 447 CJBig2_SDDProc* pSymbolDictDecoder = new CJBig2_SDDProc(); | |
| 448 const uint8_t* key = pSegment->m_pData; | |
| 449 FX_BOOL cache_hit = false; | |
| 450 if (m_pStream->readShortInteger(&wFlags) != 0) { | |
| 451 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 452 goto failed; | |
| 453 } | |
| 454 pSymbolDictDecoder->SDHUFF = wFlags & 0x0001; | 441 pSymbolDictDecoder->SDHUFF = wFlags & 0x0001; |
| 455 pSymbolDictDecoder->SDREFAGG = (wFlags >> 1) & 0x0001; | 442 pSymbolDictDecoder->SDREFAGG = (wFlags >> 1) & 0x0001; |
| 456 pSymbolDictDecoder->SDTEMPLATE = (wFlags >> 10) & 0x0003; | 443 pSymbolDictDecoder->SDTEMPLATE = (wFlags >> 10) & 0x0003; |
| 457 pSymbolDictDecoder->SDRTEMPLATE = (wFlags >> 12) & 0x0003; | 444 pSymbolDictDecoder->SDRTEMPLATE = (wFlags >> 12) & 0x0003; |
| 458 cSDHUFFDH = (wFlags >> 2) & 0x0003; | 445 uint8_t cSDHUFFDH = (wFlags >> 2) & 0x0003; |
| 459 cSDHUFFDW = (wFlags >> 4) & 0x0003; | 446 uint8_t cSDHUFFDW = (wFlags >> 4) & 0x0003; |
| 460 cSDHUFFBMSIZE = (wFlags >> 6) & 0x0001; | 447 uint8_t cSDHUFFBMSIZE = (wFlags >> 6) & 0x0001; |
| 461 cSDHUFFAGGINST = (wFlags >> 7) & 0x0001; | 448 uint8_t cSDHUFFAGGINST = (wFlags >> 7) & 0x0001; |
| 462 if (pSymbolDictDecoder->SDHUFF == 0) { | 449 if (pSymbolDictDecoder->SDHUFF == 0) { |
| 463 if (pSymbolDictDecoder->SDTEMPLATE == 0) { | 450 const FX_DWORD dwTemp = (pSymbolDictDecoder->SDTEMPLATE == 0) ? 8 : 2; |
| 464 dwTemp = 8; | 451 for (FX_DWORD i = 0; i < dwTemp; ++i) { |
| 465 } else { | 452 if (m_pStream->read1Byte((uint8_t*)&pSymbolDictDecoder->SDAT[i]) != 0) |
| 466 dwTemp = 2; | 453 return JBIG2_ERROR_TOO_SHORT; |
| 467 } | |
| 468 for (i = 0; i < (int32_t)dwTemp; i++) { | |
| 469 if (m_pStream->read1Byte((uint8_t*)&pSymbolDictDecoder->SDAT[i]) != 0) { | |
| 470 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 471 goto failed; | |
| 472 } | |
| 473 } | 454 } |
| 474 } | 455 } |
| 475 if ((pSymbolDictDecoder->SDREFAGG == 1) && | 456 if (pSymbolDictDecoder->SDREFAGG == 1 && |
| 476 (pSymbolDictDecoder->SDRTEMPLATE == 0)) { | 457 pSymbolDictDecoder->SDRTEMPLATE == 0) { |
| 477 for (i = 0; i < 4; i++) { | 458 for (int32_t i = 0; i < 4; ++i) { |
| 478 if (m_pStream->read1Byte((uint8_t*)&pSymbolDictDecoder->SDRAT[i]) != 0) { | 459 if (m_pStream->read1Byte((uint8_t*)&pSymbolDictDecoder->SDRAT[i]) != 0) |
| 479 nRet = JBIG2_ERROR_TOO_SHORT; | 460 return JBIG2_ERROR_TOO_SHORT; |
| 480 goto failed; | |
| 481 } | |
| 482 } | 461 } |
| 483 } | 462 } |
| 484 if ((m_pStream->readInteger(&pSymbolDictDecoder->SDNUMEXSYMS) != 0) || | 463 if (m_pStream->readInteger(&pSymbolDictDecoder->SDNUMEXSYMS) != 0 || |
| 485 (m_pStream->readInteger(&pSymbolDictDecoder->SDNUMNEWSYMS) != 0)) { | 464 m_pStream->readInteger(&pSymbolDictDecoder->SDNUMNEWSYMS) != 0) { |
| 486 nRet = JBIG2_ERROR_TOO_SHORT; | 465 return JBIG2_ERROR_TOO_SHORT; |
| 487 goto failed; | |
| 488 } | 466 } |
| 489 if (pSymbolDictDecoder->SDNUMEXSYMS > JBIG2_MAX_EXPORT_SYSMBOLS || | 467 if (pSymbolDictDecoder->SDNUMEXSYMS > JBIG2_MAX_EXPORT_SYSMBOLS || |
| 490 pSymbolDictDecoder->SDNUMNEWSYMS > JBIG2_MAX_NEW_SYSMBOLS) { | 468 pSymbolDictDecoder->SDNUMNEWSYMS > JBIG2_MAX_NEW_SYSMBOLS) { |
| 491 nRet = JBIG2_ERROR_LIMIT; | 469 return JBIG2_ERROR_LIMIT; |
| 492 goto failed; | |
| 493 } | 470 } |
| 494 for (i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | 471 for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
| 495 if (!findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i])) { | 472 if (!findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i])) |
| 496 nRet = JBIG2_ERROR_FATAL; | 473 return JBIG2_ERROR_FATAL; |
| 497 goto failed; | |
| 498 } | |
| 499 } | 474 } |
| 475 CJBig2_Segment* pLRSeg = nullptr; |
| 500 pSymbolDictDecoder->SDNUMINSYMS = 0; | 476 pSymbolDictDecoder->SDNUMINSYMS = 0; |
| 501 for (i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | 477 for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
| 502 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); | 478 CJBig2_Segment* pSeg = |
| 479 findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); |
| 503 if (pSeg->m_cFlags.s.type == 0) { | 480 if (pSeg->m_cFlags.s.type == 0) { |
| 504 pSymbolDictDecoder->SDNUMINSYMS += pSeg->m_Result.sd->SDNUMEXSYMS; | 481 pSymbolDictDecoder->SDNUMINSYMS += pSeg->m_Result.sd->SDNUMEXSYMS; |
| 505 pLRSeg = pSeg; | 482 pLRSeg = pSeg; |
| 506 } | 483 } |
| 507 } | 484 } |
| 508 if (pSymbolDictDecoder->SDNUMINSYMS == 0) { | 485 |
| 509 SDINSYMS = NULL; | 486 nonstd::unique_ptr<CJBig2_Image*, FxFreeDeleter> SDINSYMS; |
| 510 } else { | 487 if (pSymbolDictDecoder->SDNUMINSYMS != 0) { |
| 511 SDINSYMS = FX_Alloc(CJBig2_Image*, pSymbolDictDecoder->SDNUMINSYMS); | 488 SDINSYMS.reset(FX_Alloc(CJBig2_Image*, pSymbolDictDecoder->SDNUMINSYMS)); |
| 512 dwTemp = 0; | 489 FX_DWORD dwTemp = 0; |
| 513 for (i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | 490 for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
| 514 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); | 491 CJBig2_Segment* pSeg = |
| 492 findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); |
| 515 if (pSeg->m_cFlags.s.type == 0) { | 493 if (pSeg->m_cFlags.s.type == 0) { |
| 516 JBIG2_memcpy(SDINSYMS + dwTemp, pSeg->m_Result.sd->SDEXSYMS, | 494 JBIG2_memcpy(SDINSYMS.get() + dwTemp, pSeg->m_Result.sd->SDEXSYMS, |
| 517 pSeg->m_Result.sd->SDNUMEXSYMS * sizeof(CJBig2_Image*)); | 495 pSeg->m_Result.sd->SDNUMEXSYMS * sizeof(CJBig2_Image*)); |
| 518 dwTemp += pSeg->m_Result.sd->SDNUMEXSYMS; | 496 dwTemp += pSeg->m_Result.sd->SDNUMEXSYMS; |
| 519 } | 497 } |
| 520 } | 498 } |
| 521 } | 499 } |
| 522 pSymbolDictDecoder->SDINSYMS = SDINSYMS; | 500 pSymbolDictDecoder->SDINSYMS = SDINSYMS.get(); |
| 501 |
| 502 nonstd::unique_ptr<CJBig2_HuffmanTable> Table_B1; |
| 503 nonstd::unique_ptr<CJBig2_HuffmanTable> Table_B2; |
| 504 nonstd::unique_ptr<CJBig2_HuffmanTable> Table_B3; |
| 505 nonstd::unique_ptr<CJBig2_HuffmanTable> Table_B4; |
| 506 nonstd::unique_ptr<CJBig2_HuffmanTable> Table_B5; |
| 523 if (pSymbolDictDecoder->SDHUFF == 1) { | 507 if (pSymbolDictDecoder->SDHUFF == 1) { |
| 524 if ((cSDHUFFDH == 2) || (cSDHUFFDW == 2)) { | 508 if (cSDHUFFDH == 2 || cSDHUFFDW == 2) |
| 525 nRet = JBIG2_ERROR_FATAL; | 509 return JBIG2_ERROR_FATAL; |
| 526 goto failed; | 510 |
| 527 } | 511 int32_t nIndex = 0; |
| 528 nIndex = 0; | |
| 529 if (cSDHUFFDH == 0) { | 512 if (cSDHUFFDH == 0) { |
| 530 Table_B4 = new CJBig2_HuffmanTable(HuffmanTable_B4, | 513 Table_B4.reset(new CJBig2_HuffmanTable(HuffmanTable_B4, |
| 531 FX_ArraySize(HuffmanTable_B4), | 514 FX_ArraySize(HuffmanTable_B4), |
| 532 HuffmanTable_HTOOB_B4); | 515 HuffmanTable_HTOOB_B4)); |
| 533 pSymbolDictDecoder->SDHUFFDH = Table_B4; | 516 pSymbolDictDecoder->SDHUFFDH = Table_B4.get(); |
| 534 } else if (cSDHUFFDH == 1) { | 517 } else if (cSDHUFFDH == 1) { |
| 535 Table_B5 = new CJBig2_HuffmanTable(HuffmanTable_B5, | 518 Table_B5.reset(new CJBig2_HuffmanTable(HuffmanTable_B5, |
| 536 FX_ArraySize(HuffmanTable_B5), | 519 FX_ArraySize(HuffmanTable_B5), |
| 537 HuffmanTable_HTOOB_B5); | 520 HuffmanTable_HTOOB_B5)); |
| 538 pSymbolDictDecoder->SDHUFFDH = Table_B5; | 521 pSymbolDictDecoder->SDHUFFDH = Table_B5.get(); |
| 539 } else { | 522 } else { |
| 540 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | 523 CJBig2_Segment* pSeg = |
| 541 if (!pSeg) { | 524 findReferredSegmentByTypeAndIndex(pSegment, 53, ++nIndex); |
| 542 nRet = JBIG2_ERROR_FATAL; | 525 if (!pSeg) |
| 543 goto failed; | 526 return JBIG2_ERROR_FATAL; |
| 544 } | |
| 545 pSymbolDictDecoder->SDHUFFDH = pSeg->m_Result.ht; | 527 pSymbolDictDecoder->SDHUFFDH = pSeg->m_Result.ht; |
| 546 } | 528 } |
| 547 if (cSDHUFFDW == 0) { | 529 if (cSDHUFFDW == 0) { |
| 548 Table_B2 = new CJBig2_HuffmanTable(HuffmanTable_B2, | 530 Table_B2.reset(new CJBig2_HuffmanTable(HuffmanTable_B2, |
| 549 FX_ArraySize(HuffmanTable_B2), | 531 FX_ArraySize(HuffmanTable_B2), |
| 550 HuffmanTable_HTOOB_B2); | 532 HuffmanTable_HTOOB_B2)); |
| 551 pSymbolDictDecoder->SDHUFFDW = Table_B2; | 533 pSymbolDictDecoder->SDHUFFDW = Table_B2.get(); |
| 552 } else if (cSDHUFFDW == 1) { | 534 } else if (cSDHUFFDW == 1) { |
| 553 Table_B3 = new CJBig2_HuffmanTable(HuffmanTable_B3, | 535 Table_B3.reset(new CJBig2_HuffmanTable(HuffmanTable_B3, |
| 554 FX_ArraySize(HuffmanTable_B3), | 536 FX_ArraySize(HuffmanTable_B3), |
| 555 HuffmanTable_HTOOB_B3); | 537 HuffmanTable_HTOOB_B3)); |
| 556 pSymbolDictDecoder->SDHUFFDW = Table_B3; | 538 pSymbolDictDecoder->SDHUFFDW = Table_B3.get(); |
| 557 } else { | 539 } else { |
| 558 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | 540 CJBig2_Segment* pSeg = |
| 559 if (!pSeg) { | 541 findReferredSegmentByTypeAndIndex(pSegment, 53, ++nIndex); |
| 560 nRet = JBIG2_ERROR_FATAL; | 542 if (!pSeg) |
| 561 goto failed; | 543 return JBIG2_ERROR_FATAL; |
| 562 } | |
| 563 pSymbolDictDecoder->SDHUFFDW = pSeg->m_Result.ht; | 544 pSymbolDictDecoder->SDHUFFDW = pSeg->m_Result.ht; |
| 564 } | 545 } |
| 565 if (cSDHUFFBMSIZE == 0) { | 546 if (cSDHUFFBMSIZE == 0) { |
| 566 Table_B1 = new CJBig2_HuffmanTable(HuffmanTable_B1, | 547 Table_B1.reset(new CJBig2_HuffmanTable(HuffmanTable_B1, |
| 567 FX_ArraySize(HuffmanTable_B1), | 548 FX_ArraySize(HuffmanTable_B1), |
| 568 HuffmanTable_HTOOB_B1); | 549 HuffmanTable_HTOOB_B1)); |
| 569 pSymbolDictDecoder->SDHUFFBMSIZE = Table_B1; | 550 pSymbolDictDecoder->SDHUFFBMSIZE = Table_B1.get(); |
| 570 } else { | 551 } else { |
| 571 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | 552 CJBig2_Segment* pSeg = |
| 572 if (!pSeg) { | 553 findReferredSegmentByTypeAndIndex(pSegment, 53, ++nIndex); |
| 573 nRet = JBIG2_ERROR_FATAL; | 554 if (!pSeg) |
| 574 goto failed; | 555 return JBIG2_ERROR_FATAL; |
| 575 } | |
| 576 pSymbolDictDecoder->SDHUFFBMSIZE = pSeg->m_Result.ht; | 556 pSymbolDictDecoder->SDHUFFBMSIZE = pSeg->m_Result.ht; |
| 577 } | 557 } |
| 578 if (pSymbolDictDecoder->SDREFAGG == 1) { | 558 if (pSymbolDictDecoder->SDREFAGG == 1) { |
| 579 if (cSDHUFFAGGINST == 0) { | 559 if (cSDHUFFAGGINST == 0) { |
| 580 if (!Table_B1) { | 560 if (!Table_B1) { |
| 581 Table_B1 = new CJBig2_HuffmanTable(HuffmanTable_B1, | 561 Table_B1.reset(new CJBig2_HuffmanTable(HuffmanTable_B1, |
| 582 FX_ArraySize(HuffmanTable_B1), | 562 FX_ArraySize(HuffmanTable_B1), |
| 583 HuffmanTable_HTOOB_B1); | 563 HuffmanTable_HTOOB_B1)); |
| 584 } | 564 } |
| 585 pSymbolDictDecoder->SDHUFFAGGINST = Table_B1; | 565 pSymbolDictDecoder->SDHUFFAGGINST = Table_B1.get(); |
| 586 } else { | 566 } else { |
| 587 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | 567 CJBig2_Segment* pSeg = |
| 588 if (!pSeg) { | 568 findReferredSegmentByTypeAndIndex(pSegment, 53, ++nIndex); |
| 589 nRet = JBIG2_ERROR_FATAL; | 569 if (!pSeg) |
| 590 goto failed; | 570 return JBIG2_ERROR_FATAL; |
| 591 } | |
| 592 pSymbolDictDecoder->SDHUFFAGGINST = pSeg->m_Result.ht; | 571 pSymbolDictDecoder->SDHUFFAGGINST = pSeg->m_Result.ht; |
| 593 } | 572 } |
| 594 } | 573 } |
| 595 } | 574 } |
| 575 |
| 576 nonstd::unique_ptr<JBig2ArithCtx, FxFreeDeleter> gbContext; |
| 577 nonstd::unique_ptr<JBig2ArithCtx, FxFreeDeleter> grContext; |
| 596 if ((wFlags & 0x0100) && pLRSeg && pLRSeg->m_Result.sd->m_bContextRetained) { | 578 if ((wFlags & 0x0100) && pLRSeg && pLRSeg->m_Result.sd->m_bContextRetained) { |
| 597 if (pSymbolDictDecoder->SDHUFF == 0) { | 579 if (pSymbolDictDecoder->SDHUFF == 0) { |
| 598 dwTemp = pSymbolDictDecoder->SDTEMPLATE == 0 | 580 const size_t size = GetHuffContextSize(pSymbolDictDecoder->SDTEMPLATE); |
| 599 ? 65536 | 581 gbContext.reset(FX_Alloc(JBig2ArithCtx, size)); |
| 600 : pSymbolDictDecoder->SDTEMPLATE == 1 ? 8192 : 1024; | 582 JBIG2_memcpy(gbContext.get(), pLRSeg->m_Result.sd->m_gbContext, |
| 601 gbContext = FX_Alloc(JBig2ArithCtx, dwTemp); | 583 sizeof(JBig2ArithCtx) * size); |
| 602 JBIG2_memcpy(gbContext, pLRSeg->m_Result.sd->m_gbContext, | |
| 603 sizeof(JBig2ArithCtx) * dwTemp); | |
| 604 } | 584 } |
| 605 if (pSymbolDictDecoder->SDREFAGG == 1) { | 585 if (pSymbolDictDecoder->SDREFAGG == 1) { |
| 606 dwTemp = pSymbolDictDecoder->SDRTEMPLATE ? 1 << 10 : 1 << 13; | 586 const size_t size = GetRefAggContextSize(pSymbolDictDecoder->SDRTEMPLATE); |
| 607 grContext = FX_Alloc(JBig2ArithCtx, dwTemp); | 587 grContext.reset(FX_Alloc(JBig2ArithCtx, size)); |
| 608 JBIG2_memcpy(grContext, pLRSeg->m_Result.sd->m_grContext, | 588 JBIG2_memcpy(grContext.get(), pLRSeg->m_Result.sd->m_grContext, |
| 609 sizeof(JBig2ArithCtx) * dwTemp); | 589 sizeof(JBig2ArithCtx) * size); |
| 610 } | 590 } |
| 611 } else { | 591 } else { |
| 612 if (pSymbolDictDecoder->SDHUFF == 0) { | 592 if (pSymbolDictDecoder->SDHUFF == 0) { |
| 613 dwTemp = pSymbolDictDecoder->SDTEMPLATE == 0 | 593 const size_t size = GetHuffContextSize(pSymbolDictDecoder->SDTEMPLATE); |
| 614 ? 65536 | 594 gbContext.reset(FX_Alloc(JBig2ArithCtx, size)); |
| 615 : pSymbolDictDecoder->SDTEMPLATE == 1 ? 8192 : 1024; | 595 JBIG2_memset(gbContext.get(), 0, sizeof(JBig2ArithCtx) * size); |
| 616 gbContext = FX_Alloc(JBig2ArithCtx, dwTemp); | |
| 617 JBIG2_memset(gbContext, 0, sizeof(JBig2ArithCtx) * dwTemp); | |
| 618 } | 596 } |
| 619 if (pSymbolDictDecoder->SDREFAGG == 1) { | 597 if (pSymbolDictDecoder->SDREFAGG == 1) { |
| 620 dwTemp = pSymbolDictDecoder->SDRTEMPLATE ? 1 << 10 : 1 << 13; | 598 const size_t size = GetRefAggContextSize(pSymbolDictDecoder->SDRTEMPLATE); |
| 621 grContext = FX_Alloc(JBig2ArithCtx, dwTemp); | 599 grContext.reset(FX_Alloc(JBig2ArithCtx, size)); |
| 622 JBIG2_memset(grContext, 0, sizeof(JBig2ArithCtx) * dwTemp); | 600 JBIG2_memset(grContext.get(), 0, sizeof(JBig2ArithCtx) * size); |
| 623 } | 601 } |
| 624 } | 602 } |
| 603 const uint8_t* key = pSegment->m_pData; |
| 604 FX_BOOL cache_hit = false; |
| 625 pSegment->m_nResultType = JBIG2_SYMBOL_DICT_POINTER; | 605 pSegment->m_nResultType = JBIG2_SYMBOL_DICT_POINTER; |
| 626 for (std::list<CJBig2_CachePair>::iterator it = m_pSymbolDictCache->begin(); | 606 for (std::list<CJBig2_CachePair>::iterator it = m_pSymbolDictCache->begin(); |
| 627 it != m_pSymbolDictCache->end(); ++it) { | 607 it != m_pSymbolDictCache->end(); ++it) { |
| 628 if (it->first == key) { | 608 if (it->first == key) { |
| 629 nonstd::unique_ptr<CJBig2_SymbolDict> copy(it->second->DeepCopy()); | 609 nonstd::unique_ptr<CJBig2_SymbolDict> copy(it->second->DeepCopy()); |
| 630 pSegment->m_Result.sd = copy.release(); | 610 pSegment->m_Result.sd = copy.release(); |
| 631 m_pSymbolDictCache->push_front(*it); | 611 m_pSymbolDictCache->push_front(*it); |
| 632 m_pSymbolDictCache->erase(it); | 612 m_pSymbolDictCache->erase(it); |
| 633 cache_hit = true; | 613 cache_hit = true; |
| 634 break; | 614 break; |
| 635 } | 615 } |
| 636 } | 616 } |
| 637 if (!cache_hit) { | 617 if (!cache_hit) { |
| 638 if (pSymbolDictDecoder->SDHUFF == 0) { | 618 if (pSymbolDictDecoder->SDHUFF == 0) { |
| 639 pArithDecoder = new CJBig2_ArithDecoder(m_pStream.get()); | 619 nonstd::unique_ptr<CJBig2_ArithDecoder> pArithDecoder( |
| 640 pSegment->m_Result.sd = | 620 new CJBig2_ArithDecoder(m_pStream.get())); |
| 641 pSymbolDictDecoder->decode_Arith(pArithDecoder, gbContext, grContext); | 621 pSegment->m_Result.sd = pSymbolDictDecoder->decode_Arith( |
| 642 delete pArithDecoder; | 622 pArithDecoder.get(), gbContext.get(), grContext.get()); |
| 643 if (pSegment->m_Result.sd == NULL) { | 623 if (!pSegment->m_Result.sd) |
| 644 nRet = JBIG2_ERROR_FATAL; | 624 return JBIG2_ERROR_FATAL; |
| 645 goto failed; | 625 |
| 646 } | |
| 647 m_pStream->alignByte(); | 626 m_pStream->alignByte(); |
| 648 m_pStream->offset(2); | 627 m_pStream->offset(2); |
| 649 } else { | 628 } else { |
| 650 pSegment->m_Result.sd = pSymbolDictDecoder->decode_Huffman( | 629 pSegment->m_Result.sd = pSymbolDictDecoder->decode_Huffman( |
| 651 m_pStream.get(), gbContext, grContext, pPause); | 630 m_pStream.get(), gbContext.get(), grContext.get(), pPause); |
| 652 if (pSegment->m_Result.sd == NULL) { | 631 if (!pSegment->m_Result.sd) |
| 653 nRet = JBIG2_ERROR_FATAL; | 632 return JBIG2_ERROR_FATAL; |
| 654 goto failed; | |
| 655 } | |
| 656 m_pStream->alignByte(); | 633 m_pStream->alignByte(); |
| 657 } | 634 } |
| 658 #ifndef DISABLE_SYMBOL_CACHE | 635 #ifndef DISABLE_SYMBOL_CACHE |
| 659 nonstd::unique_ptr<CJBig2_SymbolDict> value = | 636 nonstd::unique_ptr<CJBig2_SymbolDict> value = |
| 660 pSegment->m_Result.sd->DeepCopy(); | 637 pSegment->m_Result.sd->DeepCopy(); |
| 661 if (value && kSymbolDictCacheMaxSize > 0) { | 638 if (value && kSymbolDictCacheMaxSize > 0) { |
| 662 while (m_pSymbolDictCache->size() >= kSymbolDictCacheMaxSize) { | 639 while (m_pSymbolDictCache->size() >= kSymbolDictCacheMaxSize) { |
| 663 delete m_pSymbolDictCache->back().second; | 640 delete m_pSymbolDictCache->back().second; |
| 664 m_pSymbolDictCache->pop_back(); | 641 m_pSymbolDictCache->pop_back(); |
| 665 } | 642 } |
| 666 m_pSymbolDictCache->push_front(CJBig2_CachePair(key, value.release())); | 643 m_pSymbolDictCache->push_front(CJBig2_CachePair(key, value.release())); |
| 667 } | 644 } |
| 668 #endif | 645 #endif |
| 669 } | 646 } |
| 670 if (wFlags & 0x0200) { | 647 if (wFlags & 0x0200) { |
| 671 pSegment->m_Result.sd->m_bContextRetained = TRUE; | 648 pSegment->m_Result.sd->m_bContextRetained = TRUE; |
| 672 if (pSymbolDictDecoder->SDHUFF == 0) { | 649 if (pSymbolDictDecoder->SDHUFF == 0) { |
| 673 pSegment->m_Result.sd->m_gbContext = gbContext; | 650 pSegment->m_Result.sd->m_gbContext = gbContext.release(); |
| 674 } | 651 } |
| 675 if (pSymbolDictDecoder->SDREFAGG == 1) { | 652 if (pSymbolDictDecoder->SDREFAGG == 1) { |
| 676 pSegment->m_Result.sd->m_grContext = grContext; | 653 pSegment->m_Result.sd->m_grContext = grContext.release(); |
| 677 } | 654 } |
| 678 bUsed = TRUE; | |
| 679 } else { | |
| 680 bUsed = FALSE; | |
| 681 } | |
| 682 delete pSymbolDictDecoder; | |
| 683 FX_Free(SDINSYMS); | |
| 684 delete Table_B1; | |
| 685 delete Table_B2; | |
| 686 delete Table_B3; | |
| 687 delete Table_B4; | |
| 688 delete Table_B5; | |
| 689 if (bUsed == FALSE) { | |
| 690 FX_Free(gbContext); | |
| 691 FX_Free(grContext); | |
| 692 } | 655 } |
| 693 return JBIG2_SUCCESS; | 656 return JBIG2_SUCCESS; |
| 694 failed: | |
| 695 delete pSymbolDictDecoder; | |
| 696 FX_Free(SDINSYMS); | |
| 697 delete Table_B1; | |
| 698 delete Table_B2; | |
| 699 delete Table_B3; | |
| 700 delete Table_B4; | |
| 701 delete Table_B5; | |
| 702 FX_Free(gbContext); | |
| 703 FX_Free(grContext); | |
| 704 return nRet; | |
| 705 } | 657 } |
| 706 | 658 |
| 707 int32_t CJBig2_Context::parseTextRegion(CJBig2_Segment* pSegment) { | 659 int32_t CJBig2_Context::parseTextRegion(CJBig2_Segment* pSegment) { |
| 708 FX_DWORD dwTemp; | |
| 709 FX_WORD wFlags; | 660 FX_WORD wFlags; |
| 710 int32_t i, nIndex, nRet; | |
| 711 JBig2RegionInfo ri; | 661 JBig2RegionInfo ri; |
| 712 CJBig2_Segment* pSeg; | 662 if (parseRegionInfo(&ri) != JBIG2_SUCCESS || |
| 713 CJBig2_Image** SBSYMS = nullptr; | 663 m_pStream->readShortInteger(&wFlags) != 0) { |
| 714 JBig2HuffmanCode* SBSYMCODES = nullptr; | 664 return JBIG2_ERROR_TOO_SHORT; |
| 715 uint8_t cSBHUFFFS, cSBHUFFDS, cSBHUFFDT, cSBHUFFRDW, cSBHUFFRDH, cSBHUFFRDX, | |
| 716 cSBHUFFRDY, cSBHUFFRSIZE; | |
| 717 CJBig2_HuffmanTable* Table_B1 = nullptr; | |
| 718 CJBig2_HuffmanTable* Table_B6 = nullptr; | |
| 719 CJBig2_HuffmanTable* Table_B7 = nullptr; | |
| 720 CJBig2_HuffmanTable* Table_B8 = nullptr; | |
| 721 CJBig2_HuffmanTable* Table_B9 = nullptr; | |
| 722 CJBig2_HuffmanTable* Table_B10 = nullptr; | |
| 723 CJBig2_HuffmanTable* Table_B11 = nullptr; | |
| 724 CJBig2_HuffmanTable* Table_B12 = nullptr; | |
| 725 CJBig2_HuffmanTable* Table_B13 = nullptr; | |
| 726 CJBig2_HuffmanTable* Table_B14 = nullptr; | |
| 727 CJBig2_HuffmanTable* Table_B15 = nullptr; | |
| 728 JBig2ArithCtx* grContext = nullptr; | |
| 729 CJBig2_ArithDecoder* pArithDecoder; | |
| 730 CJBig2_TRDProc* pTRD = new CJBig2_TRDProc(); | |
| 731 if ((parseRegionInfo(&ri) != JBIG2_SUCCESS) || | |
| 732 (m_pStream->readShortInteger(&wFlags) != 0)) { | |
| 733 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 734 goto failed; | |
| 735 } | 665 } |
| 666 |
| 667 nonstd::unique_ptr<CJBig2_TRDProc> pTRD(new CJBig2_TRDProc); |
| 736 pTRD->SBW = ri.width; | 668 pTRD->SBW = ri.width; |
| 737 pTRD->SBH = ri.height; | 669 pTRD->SBH = ri.height; |
| 738 pTRD->SBHUFF = wFlags & 0x0001; | 670 pTRD->SBHUFF = wFlags & 0x0001; |
| 739 pTRD->SBREFINE = (wFlags >> 1) & 0x0001; | 671 pTRD->SBREFINE = (wFlags >> 1) & 0x0001; |
| 740 dwTemp = (wFlags >> 2) & 0x0003; | 672 FX_DWORD dwTemp = (wFlags >> 2) & 0x0003; |
| 741 pTRD->SBSTRIPS = 1 << dwTemp; | 673 pTRD->SBSTRIPS = 1 << dwTemp; |
| 742 pTRD->REFCORNER = (JBig2Corner)((wFlags >> 4) & 0x0003); | 674 pTRD->REFCORNER = (JBig2Corner)((wFlags >> 4) & 0x0003); |
| 743 pTRD->TRANSPOSED = (wFlags >> 6) & 0x0001; | 675 pTRD->TRANSPOSED = (wFlags >> 6) & 0x0001; |
| 744 pTRD->SBCOMBOP = (JBig2ComposeOp)((wFlags >> 7) & 0x0003); | 676 pTRD->SBCOMBOP = (JBig2ComposeOp)((wFlags >> 7) & 0x0003); |
| 745 pTRD->SBDEFPIXEL = (wFlags >> 9) & 0x0001; | 677 pTRD->SBDEFPIXEL = (wFlags >> 9) & 0x0001; |
| 746 pTRD->SBDSOFFSET = (wFlags >> 10) & 0x001f; | 678 pTRD->SBDSOFFSET = (wFlags >> 10) & 0x001f; |
| 747 if (pTRD->SBDSOFFSET >= 0x0010) { | 679 if (pTRD->SBDSOFFSET >= 0x0010) { |
| 748 pTRD->SBDSOFFSET = pTRD->SBDSOFFSET - 0x0020; | 680 pTRD->SBDSOFFSET = pTRD->SBDSOFFSET - 0x0020; |
| 749 } | 681 } |
| 750 pTRD->SBRTEMPLATE = (wFlags >> 15) & 0x0001; | 682 pTRD->SBRTEMPLATE = (wFlags >> 15) & 0x0001; |
| 683 |
| 684 uint8_t cSBHUFFFS; |
| 685 uint8_t cSBHUFFDS; |
| 686 uint8_t cSBHUFFDT; |
| 687 uint8_t cSBHUFFRDW; |
| 688 uint8_t cSBHUFFRDH; |
| 689 uint8_t cSBHUFFRDX; |
| 690 uint8_t cSBHUFFRDY; |
| 691 uint8_t cSBHUFFRSIZE; |
| 751 if (pTRD->SBHUFF == 1) { | 692 if (pTRD->SBHUFF == 1) { |
| 752 if (m_pStream->readShortInteger(&wFlags) != 0) { | 693 if (m_pStream->readShortInteger(&wFlags) != 0) |
| 753 nRet = JBIG2_ERROR_TOO_SHORT; | 694 return JBIG2_ERROR_TOO_SHORT; |
| 754 goto failed; | 695 |
| 755 } | |
| 756 cSBHUFFFS = wFlags & 0x0003; | 696 cSBHUFFFS = wFlags & 0x0003; |
| 757 cSBHUFFDS = (wFlags >> 2) & 0x0003; | 697 cSBHUFFDS = (wFlags >> 2) & 0x0003; |
| 758 cSBHUFFDT = (wFlags >> 4) & 0x0003; | 698 cSBHUFFDT = (wFlags >> 4) & 0x0003; |
| 759 cSBHUFFRDW = (wFlags >> 6) & 0x0003; | 699 cSBHUFFRDW = (wFlags >> 6) & 0x0003; |
| 760 cSBHUFFRDH = (wFlags >> 8) & 0x0003; | 700 cSBHUFFRDH = (wFlags >> 8) & 0x0003; |
| 761 cSBHUFFRDX = (wFlags >> 10) & 0x0003; | 701 cSBHUFFRDX = (wFlags >> 10) & 0x0003; |
| 762 cSBHUFFRDY = (wFlags >> 12) & 0x0003; | 702 cSBHUFFRDY = (wFlags >> 12) & 0x0003; |
| 763 cSBHUFFRSIZE = (wFlags >> 14) & 0x0001; | 703 cSBHUFFRSIZE = (wFlags >> 14) & 0x0001; |
| 764 } | 704 } |
| 765 if ((pTRD->SBREFINE == 1) && (pTRD->SBRTEMPLATE == 0)) { | 705 if (pTRD->SBREFINE == 1 && pTRD->SBRTEMPLATE == 0) { |
| 766 for (i = 0; i < 4; i++) { | 706 for (int32_t i = 0; i < 4; ++i) { |
| 767 if (m_pStream->read1Byte((uint8_t*)&pTRD->SBRAT[i]) != 0) { | 707 if (m_pStream->read1Byte((uint8_t*)&pTRD->SBRAT[i]) != 0) |
| 768 nRet = JBIG2_ERROR_TOO_SHORT; | 708 return JBIG2_ERROR_TOO_SHORT; |
| 769 goto failed; | 709 } |
| 770 } | 710 } |
| 771 } | 711 if (m_pStream->readInteger(&pTRD->SBNUMINSTANCES) != 0) |
| 772 } | 712 return JBIG2_ERROR_TOO_SHORT; |
| 773 if (m_pStream->readInteger(&pTRD->SBNUMINSTANCES) != 0) { | 713 |
| 774 nRet = JBIG2_ERROR_TOO_SHORT; | 714 for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
| 775 goto failed; | 715 if (!findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i])) |
| 776 } | 716 return JBIG2_ERROR_FATAL; |
| 777 for (i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | 717 } |
| 778 if (!findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i])) { | 718 |
| 779 nRet = JBIG2_ERROR_FATAL; | |
| 780 goto failed; | |
| 781 } | |
| 782 } | |
| 783 pTRD->SBNUMSYMS = 0; | 719 pTRD->SBNUMSYMS = 0; |
| 784 for (i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | 720 for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
| 785 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); | 721 CJBig2_Segment* pSeg = |
| 722 findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); |
| 786 if (pSeg->m_cFlags.s.type == 0) { | 723 if (pSeg->m_cFlags.s.type == 0) { |
| 787 pTRD->SBNUMSYMS += pSeg->m_Result.sd->SDNUMEXSYMS; | 724 pTRD->SBNUMSYMS += pSeg->m_Result.sd->SDNUMEXSYMS; |
| 788 } | 725 } |
| 789 } | 726 } |
| 727 |
| 728 nonstd::unique_ptr<CJBig2_Image*, FxFreeDeleter> SBSYMS; |
| 790 if (pTRD->SBNUMSYMS > 0) { | 729 if (pTRD->SBNUMSYMS > 0) { |
| 791 SBSYMS = FX_Alloc(CJBig2_Image*, pTRD->SBNUMSYMS); | 730 SBSYMS.reset(FX_Alloc(CJBig2_Image*, pTRD->SBNUMSYMS)); |
| 792 dwTemp = 0; | 731 dwTemp = 0; |
| 793 for (i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | 732 for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
| 794 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); | 733 CJBig2_Segment* pSeg = |
| 734 findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); |
| 795 if (pSeg->m_cFlags.s.type == 0) { | 735 if (pSeg->m_cFlags.s.type == 0) { |
| 796 JBIG2_memcpy(SBSYMS + dwTemp, pSeg->m_Result.sd->SDEXSYMS, | 736 JBIG2_memcpy(SBSYMS.get() + dwTemp, pSeg->m_Result.sd->SDEXSYMS, |
| 797 pSeg->m_Result.sd->SDNUMEXSYMS * sizeof(CJBig2_Image*)); | 737 pSeg->m_Result.sd->SDNUMEXSYMS * sizeof(CJBig2_Image*)); |
| 798 dwTemp += pSeg->m_Result.sd->SDNUMEXSYMS; | 738 dwTemp += pSeg->m_Result.sd->SDNUMEXSYMS; |
| 799 } | 739 } |
| 800 } | 740 } |
| 801 pTRD->SBSYMS = SBSYMS; | 741 pTRD->SBSYMS = SBSYMS.get(); |
| 802 } else { | 742 } else { |
| 803 pTRD->SBSYMS = NULL; | 743 pTRD->SBSYMS = NULL; |
| 804 } | 744 } |
| 745 |
| 746 nonstd::unique_ptr<JBig2HuffmanCode, FxFreeDeleter> SBSYMCODES; |
| 805 if (pTRD->SBHUFF == 1) { | 747 if (pTRD->SBHUFF == 1) { |
| 806 SBSYMCODES = decodeSymbolIDHuffmanTable(m_pStream.get(), pTRD->SBNUMSYMS); | 748 SBSYMCODES.reset( |
| 807 if (SBSYMCODES == NULL) { | 749 decodeSymbolIDHuffmanTable(m_pStream.get(), pTRD->SBNUMSYMS)); |
| 808 nRet = JBIG2_ERROR_FATAL; | 750 if (!SBSYMCODES) |
| 809 goto failed; | 751 return JBIG2_ERROR_FATAL; |
| 810 } | 752 |
| 811 m_pStream->alignByte(); | 753 m_pStream->alignByte(); |
| 812 pTRD->SBSYMCODES = SBSYMCODES; | 754 pTRD->SBSYMCODES = SBSYMCODES.get(); |
| 813 } else { | 755 } else { |
| 814 dwTemp = 0; | 756 dwTemp = 0; |
| 815 while ((FX_DWORD)(1 << dwTemp) < pTRD->SBNUMSYMS) { | 757 while ((FX_DWORD)(1 << dwTemp) < pTRD->SBNUMSYMS) { |
| 816 dwTemp++; | 758 ++dwTemp; |
| 817 } | 759 } |
| 818 pTRD->SBSYMCODELEN = (uint8_t)dwTemp; | 760 pTRD->SBSYMCODELEN = (uint8_t)dwTemp; |
| 819 } | 761 } |
| 762 |
| 763 nonstd::unique_ptr<CJBig2_HuffmanTable> Table_B1; |
| 764 nonstd::unique_ptr<CJBig2_HuffmanTable> Table_B6; |
| 765 nonstd::unique_ptr<CJBig2_HuffmanTable> Table_B7; |
| 766 nonstd::unique_ptr<CJBig2_HuffmanTable> Table_B8; |
| 767 nonstd::unique_ptr<CJBig2_HuffmanTable> Table_B9; |
| 768 nonstd::unique_ptr<CJBig2_HuffmanTable> Table_B10; |
| 769 nonstd::unique_ptr<CJBig2_HuffmanTable> Table_B11; |
| 770 nonstd::unique_ptr<CJBig2_HuffmanTable> Table_B12; |
| 771 nonstd::unique_ptr<CJBig2_HuffmanTable> Table_B13; |
| 772 nonstd::unique_ptr<CJBig2_HuffmanTable> Table_B14; |
| 773 nonstd::unique_ptr<CJBig2_HuffmanTable> Table_B15; |
| 820 if (pTRD->SBHUFF == 1) { | 774 if (pTRD->SBHUFF == 1) { |
| 821 if ((cSBHUFFFS == 2) || (cSBHUFFRDW == 2) || (cSBHUFFRDH == 2) || | 775 if (cSBHUFFFS == 2 || cSBHUFFRDW == 2 || cSBHUFFRDH == 2 || |
| 822 (cSBHUFFRDX == 2) || (cSBHUFFRDY == 2)) { | 776 cSBHUFFRDX == 2 || cSBHUFFRDY == 2) { |
| 823 nRet = JBIG2_ERROR_FATAL; | 777 return JBIG2_ERROR_FATAL; |
| 824 goto failed; | 778 } |
| 825 } | 779 int32_t nIndex = 0; |
| 826 nIndex = 0; | |
| 827 if (cSBHUFFFS == 0) { | 780 if (cSBHUFFFS == 0) { |
| 828 Table_B6 = new CJBig2_HuffmanTable(HuffmanTable_B6, | 781 Table_B6.reset(new CJBig2_HuffmanTable(HuffmanTable_B6, |
| 829 FX_ArraySize(HuffmanTable_B6), | 782 FX_ArraySize(HuffmanTable_B6), |
| 830 HuffmanTable_HTOOB_B6); | 783 HuffmanTable_HTOOB_B6)); |
| 831 pTRD->SBHUFFFS = Table_B6; | 784 pTRD->SBHUFFFS = Table_B6.get(); |
| 832 } else if (cSBHUFFFS == 1) { | 785 } else if (cSBHUFFFS == 1) { |
| 833 Table_B7 = new CJBig2_HuffmanTable(HuffmanTable_B7, | 786 Table_B7.reset(new CJBig2_HuffmanTable(HuffmanTable_B7, |
| 834 FX_ArraySize(HuffmanTable_B7), | 787 FX_ArraySize(HuffmanTable_B7), |
| 835 HuffmanTable_HTOOB_B7); | 788 HuffmanTable_HTOOB_B7)); |
| 836 pTRD->SBHUFFFS = Table_B7; | 789 pTRD->SBHUFFFS = Table_B7.get(); |
| 837 } else { | 790 } else { |
| 838 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | 791 CJBig2_Segment* pSeg = |
| 839 if (!pSeg) { | 792 findReferredSegmentByTypeAndIndex(pSegment, 53, ++nIndex); |
| 840 nRet = JBIG2_ERROR_FATAL; | 793 if (!pSeg) |
| 841 goto failed; | 794 return JBIG2_ERROR_FATAL; |
| 842 } | |
| 843 pTRD->SBHUFFFS = pSeg->m_Result.ht; | 795 pTRD->SBHUFFFS = pSeg->m_Result.ht; |
| 844 } | 796 } |
| 845 if (cSBHUFFDS == 0) { | 797 if (cSBHUFFDS == 0) { |
| 846 Table_B8 = new CJBig2_HuffmanTable(HuffmanTable_B8, | 798 Table_B8.reset(new CJBig2_HuffmanTable(HuffmanTable_B8, |
| 847 FX_ArraySize(HuffmanTable_B8), | 799 FX_ArraySize(HuffmanTable_B8), |
| 848 HuffmanTable_HTOOB_B8); | 800 HuffmanTable_HTOOB_B8)); |
| 849 pTRD->SBHUFFDS = Table_B8; | 801 pTRD->SBHUFFDS = Table_B8.get(); |
| 850 } else if (cSBHUFFDS == 1) { | 802 } else if (cSBHUFFDS == 1) { |
| 851 Table_B9 = new CJBig2_HuffmanTable(HuffmanTable_B9, | 803 Table_B9.reset(new CJBig2_HuffmanTable(HuffmanTable_B9, |
| 852 FX_ArraySize(HuffmanTable_B9), | 804 FX_ArraySize(HuffmanTable_B9), |
| 853 HuffmanTable_HTOOB_B9); | 805 HuffmanTable_HTOOB_B9)); |
| 854 pTRD->SBHUFFDS = Table_B9; | 806 pTRD->SBHUFFDS = Table_B9.get(); |
| 855 } else if (cSBHUFFDS == 2) { | 807 } else if (cSBHUFFDS == 2) { |
| 856 Table_B10 = new CJBig2_HuffmanTable(HuffmanTable_B10, | 808 Table_B10.reset(new CJBig2_HuffmanTable(HuffmanTable_B10, |
| 857 FX_ArraySize(HuffmanTable_B10), | 809 FX_ArraySize(HuffmanTable_B10), |
| 858 HuffmanTable_HTOOB_B10); | 810 HuffmanTable_HTOOB_B10)); |
| 859 pTRD->SBHUFFDS = Table_B10; | 811 pTRD->SBHUFFDS = Table_B10.get(); |
| 860 } else { | 812 } else { |
| 861 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | 813 CJBig2_Segment* pSeg = |
| 862 if (!pSeg) { | 814 findReferredSegmentByTypeAndIndex(pSegment, 53, ++nIndex); |
| 863 nRet = JBIG2_ERROR_FATAL; | 815 if (!pSeg) |
| 864 goto failed; | 816 return JBIG2_ERROR_FATAL; |
| 865 } | |
| 866 pTRD->SBHUFFDS = pSeg->m_Result.ht; | 817 pTRD->SBHUFFDS = pSeg->m_Result.ht; |
| 867 } | 818 } |
| 868 if (cSBHUFFDT == 0) { | 819 if (cSBHUFFDT == 0) { |
| 869 Table_B11 = new CJBig2_HuffmanTable(HuffmanTable_B11, | 820 Table_B11.reset(new CJBig2_HuffmanTable(HuffmanTable_B11, |
| 870 FX_ArraySize(HuffmanTable_B11), | 821 FX_ArraySize(HuffmanTable_B11), |
| 871 HuffmanTable_HTOOB_B11); | 822 HuffmanTable_HTOOB_B11)); |
| 872 pTRD->SBHUFFDT = Table_B11; | 823 pTRD->SBHUFFDT = Table_B11.get(); |
| 873 } else if (cSBHUFFDT == 1) { | 824 } else if (cSBHUFFDT == 1) { |
| 874 Table_B12 = new CJBig2_HuffmanTable(HuffmanTable_B12, | 825 Table_B12.reset(new CJBig2_HuffmanTable(HuffmanTable_B12, |
| 875 FX_ArraySize(HuffmanTable_B12), | 826 FX_ArraySize(HuffmanTable_B12), |
| 876 HuffmanTable_HTOOB_B12); | 827 HuffmanTable_HTOOB_B12)); |
| 877 pTRD->SBHUFFDT = Table_B12; | 828 pTRD->SBHUFFDT = Table_B12.get(); |
| 878 } else if (cSBHUFFDT == 2) { | 829 } else if (cSBHUFFDT == 2) { |
| 879 Table_B13 = new CJBig2_HuffmanTable(HuffmanTable_B13, | 830 Table_B13.reset(new CJBig2_HuffmanTable(HuffmanTable_B13, |
| 880 FX_ArraySize(HuffmanTable_B13), | 831 FX_ArraySize(HuffmanTable_B13), |
| 881 HuffmanTable_HTOOB_B13); | 832 HuffmanTable_HTOOB_B13)); |
| 882 pTRD->SBHUFFDT = Table_B13; | 833 pTRD->SBHUFFDT = Table_B13.get(); |
| 883 } else { | 834 } else { |
| 884 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | 835 CJBig2_Segment* pSeg = |
| 885 if (!pSeg) { | 836 findReferredSegmentByTypeAndIndex(pSegment, 53, ++nIndex); |
| 886 nRet = JBIG2_ERROR_FATAL; | 837 if (!pSeg) |
| 887 goto failed; | 838 return JBIG2_ERROR_FATAL; |
| 888 } | |
| 889 pTRD->SBHUFFDT = pSeg->m_Result.ht; | 839 pTRD->SBHUFFDT = pSeg->m_Result.ht; |
| 890 } | 840 } |
| 891 if (cSBHUFFRDW == 0) { | 841 if (cSBHUFFRDW == 0) { |
| 892 Table_B14 = new CJBig2_HuffmanTable(HuffmanTable_B14, | 842 Table_B14.reset(new CJBig2_HuffmanTable(HuffmanTable_B14, |
| 893 FX_ArraySize(HuffmanTable_B14), | 843 FX_ArraySize(HuffmanTable_B14), |
| 894 HuffmanTable_HTOOB_B14); | 844 HuffmanTable_HTOOB_B14)); |
| 895 pTRD->SBHUFFRDW = Table_B14; | 845 pTRD->SBHUFFRDW = Table_B14.get(); |
| 896 } else if (cSBHUFFRDW == 1) { | 846 } else if (cSBHUFFRDW == 1) { |
| 897 Table_B15 = new CJBig2_HuffmanTable(HuffmanTable_B15, | 847 Table_B15.reset(new CJBig2_HuffmanTable(HuffmanTable_B15, |
| 898 FX_ArraySize(HuffmanTable_B15), | 848 FX_ArraySize(HuffmanTable_B15), |
| 899 HuffmanTable_HTOOB_B15); | 849 HuffmanTable_HTOOB_B15)); |
| 900 pTRD->SBHUFFRDW = Table_B15; | 850 pTRD->SBHUFFRDW = Table_B15.get(); |
| 901 } else { | 851 } else { |
| 902 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | 852 CJBig2_Segment* pSeg = |
| 903 if (!pSeg) { | 853 findReferredSegmentByTypeAndIndex(pSegment, 53, ++nIndex); |
| 904 nRet = JBIG2_ERROR_FATAL; | 854 if (!pSeg) |
| 905 goto failed; | 855 return JBIG2_ERROR_FATAL; |
| 906 } | |
| 907 pTRD->SBHUFFRDW = pSeg->m_Result.ht; | 856 pTRD->SBHUFFRDW = pSeg->m_Result.ht; |
| 908 } | 857 } |
| 909 if (cSBHUFFRDH == 0) { | 858 if (cSBHUFFRDH == 0) { |
| 910 if (!Table_B14) { | 859 if (!Table_B14) { |
| 911 Table_B14 = new CJBig2_HuffmanTable(HuffmanTable_B14, | 860 Table_B14.reset(new CJBig2_HuffmanTable(HuffmanTable_B14, |
| 912 FX_ArraySize(HuffmanTable_B14), | 861 FX_ArraySize(HuffmanTable_B14), |
| 913 HuffmanTable_HTOOB_B14); | 862 HuffmanTable_HTOOB_B14)); |
| 914 } | 863 } |
| 915 pTRD->SBHUFFRDH = Table_B14; | 864 pTRD->SBHUFFRDH = Table_B14.get(); |
| 916 } else if (cSBHUFFRDH == 1) { | 865 } else if (cSBHUFFRDH == 1) { |
| 917 if (!Table_B15) { | 866 if (!Table_B15) { |
| 918 Table_B15 = new CJBig2_HuffmanTable(HuffmanTable_B15, | 867 Table_B15.reset(new CJBig2_HuffmanTable(HuffmanTable_B15, |
| 919 FX_ArraySize(HuffmanTable_B15), | 868 FX_ArraySize(HuffmanTable_B15), |
| 920 HuffmanTable_HTOOB_B15); | 869 HuffmanTable_HTOOB_B15)); |
| 921 } | 870 } |
| 922 pTRD->SBHUFFRDH = Table_B15; | 871 pTRD->SBHUFFRDH = Table_B15.get(); |
| 923 } else { | 872 } else { |
| 924 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | 873 CJBig2_Segment* pSeg = |
| 925 if (!pSeg) { | 874 findReferredSegmentByTypeAndIndex(pSegment, 53, ++nIndex); |
| 926 nRet = JBIG2_ERROR_FATAL; | 875 if (!pSeg) |
| 927 goto failed; | 876 return JBIG2_ERROR_FATAL; |
| 928 } | |
| 929 pTRD->SBHUFFRDH = pSeg->m_Result.ht; | 877 pTRD->SBHUFFRDH = pSeg->m_Result.ht; |
| 930 } | 878 } |
| 931 if (cSBHUFFRDX == 0) { | 879 if (cSBHUFFRDX == 0) { |
| 932 if (!Table_B14) { | 880 if (!Table_B14) { |
| 933 Table_B14 = new CJBig2_HuffmanTable(HuffmanTable_B14, | 881 Table_B14.reset(new CJBig2_HuffmanTable(HuffmanTable_B14, |
| 934 FX_ArraySize(HuffmanTable_B14), | 882 FX_ArraySize(HuffmanTable_B14), |
| 935 HuffmanTable_HTOOB_B14); | 883 HuffmanTable_HTOOB_B14)); |
| 936 } | 884 } |
| 937 pTRD->SBHUFFRDX = Table_B14; | 885 pTRD->SBHUFFRDX = Table_B14.get(); |
| 938 } else if (cSBHUFFRDX == 1) { | 886 } else if (cSBHUFFRDX == 1) { |
| 939 if (!Table_B15) { | 887 if (!Table_B15) { |
| 940 Table_B15 = new CJBig2_HuffmanTable(HuffmanTable_B15, | 888 Table_B15.reset(new CJBig2_HuffmanTable(HuffmanTable_B15, |
| 941 FX_ArraySize(HuffmanTable_B15), | 889 FX_ArraySize(HuffmanTable_B15), |
| 942 HuffmanTable_HTOOB_B15); | 890 HuffmanTable_HTOOB_B15)); |
| 943 } | 891 } |
| 944 pTRD->SBHUFFRDX = Table_B15; | 892 pTRD->SBHUFFRDX = Table_B15.get(); |
| 945 } else { | 893 } else { |
| 946 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | 894 CJBig2_Segment* pSeg = |
| 947 if (!pSeg) { | 895 findReferredSegmentByTypeAndIndex(pSegment, 53, ++nIndex); |
| 948 nRet = JBIG2_ERROR_FATAL; | 896 if (!pSeg) |
| 949 goto failed; | 897 return JBIG2_ERROR_FATAL; |
| 950 } | |
| 951 pTRD->SBHUFFRDX = pSeg->m_Result.ht; | 898 pTRD->SBHUFFRDX = pSeg->m_Result.ht; |
| 952 } | 899 } |
| 953 if (cSBHUFFRDY == 0) { | 900 if (cSBHUFFRDY == 0) { |
| 954 if (!Table_B14) { | 901 if (!Table_B14) { |
| 955 Table_B14 = new CJBig2_HuffmanTable(HuffmanTable_B14, | 902 Table_B14.reset(new CJBig2_HuffmanTable(HuffmanTable_B14, |
| 956 FX_ArraySize(HuffmanTable_B14), | 903 FX_ArraySize(HuffmanTable_B14), |
| 957 HuffmanTable_HTOOB_B14); | 904 HuffmanTable_HTOOB_B14)); |
| 958 } | 905 } |
| 959 pTRD->SBHUFFRDY = Table_B14; | 906 pTRD->SBHUFFRDY = Table_B14.get(); |
| 960 } else if (cSBHUFFRDY == 1) { | 907 } else if (cSBHUFFRDY == 1) { |
| 961 if (!Table_B15) { | 908 if (!Table_B15) { |
| 962 Table_B15 = new CJBig2_HuffmanTable(HuffmanTable_B15, | 909 Table_B15.reset(new CJBig2_HuffmanTable(HuffmanTable_B15, |
| 963 FX_ArraySize(HuffmanTable_B15), | 910 FX_ArraySize(HuffmanTable_B15), |
| 964 HuffmanTable_HTOOB_B15); | 911 HuffmanTable_HTOOB_B15)); |
| 965 } | 912 } |
| 966 pTRD->SBHUFFRDY = Table_B15; | 913 pTRD->SBHUFFRDY = Table_B15.get(); |
| 967 } else { | 914 } else { |
| 968 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | 915 CJBig2_Segment* pSeg = |
| 969 if (!pSeg) { | 916 findReferredSegmentByTypeAndIndex(pSegment, 53, ++nIndex); |
| 970 nRet = JBIG2_ERROR_FATAL; | 917 if (!pSeg) |
| 971 goto failed; | 918 return JBIG2_ERROR_FATAL; |
| 972 } | |
| 973 pTRD->SBHUFFRDY = pSeg->m_Result.ht; | 919 pTRD->SBHUFFRDY = pSeg->m_Result.ht; |
| 974 } | 920 } |
| 975 if (cSBHUFFRSIZE == 0) { | 921 if (cSBHUFFRSIZE == 0) { |
| 976 Table_B1 = new CJBig2_HuffmanTable(HuffmanTable_B1, | 922 Table_B1.reset(new CJBig2_HuffmanTable(HuffmanTable_B1, |
| 977 FX_ArraySize(HuffmanTable_B1), | 923 FX_ArraySize(HuffmanTable_B1), |
| 978 HuffmanTable_HTOOB_B1); | 924 HuffmanTable_HTOOB_B1)); |
| 979 pTRD->SBHUFFRSIZE = Table_B1; | 925 pTRD->SBHUFFRSIZE = Table_B1.get(); |
| 980 } else { | 926 } else { |
| 981 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); | 927 CJBig2_Segment* pSeg = |
| 982 if (!pSeg) { | 928 findReferredSegmentByTypeAndIndex(pSegment, 53, ++nIndex); |
| 983 nRet = JBIG2_ERROR_FATAL; | 929 if (!pSeg) |
| 984 goto failed; | 930 return JBIG2_ERROR_FATAL; |
| 985 } | |
| 986 pTRD->SBHUFFRSIZE = pSeg->m_Result.ht; | 931 pTRD->SBHUFFRSIZE = pSeg->m_Result.ht; |
| 987 } | 932 } |
| 988 } | 933 } |
| 934 nonstd::unique_ptr<JBig2ArithCtx, FxFreeDeleter> grContext; |
| 989 if (pTRD->SBREFINE == 1) { | 935 if (pTRD->SBREFINE == 1) { |
| 990 dwTemp = pTRD->SBRTEMPLATE ? 1 << 10 : 1 << 13; | 936 const size_t size = GetRefAggContextSize(pTRD->SBRTEMPLATE); |
| 991 grContext = FX_Alloc(JBig2ArithCtx, dwTemp); | 937 grContext.reset(FX_Alloc(JBig2ArithCtx, size)); |
| 992 JBIG2_memset(grContext, 0, sizeof(JBig2ArithCtx) * dwTemp); | 938 JBIG2_memset(grContext.get(), 0, sizeof(JBig2ArithCtx) * size); |
| 993 } | 939 } |
| 994 if (pTRD->SBHUFF == 0) { | 940 if (pTRD->SBHUFF == 0) { |
| 995 pArithDecoder = new CJBig2_ArithDecoder(m_pStream.get()); | 941 nonstd::unique_ptr<CJBig2_ArithDecoder> pArithDecoder( |
| 942 new CJBig2_ArithDecoder(m_pStream.get())); |
| 996 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; | 943 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; |
| 997 pSegment->m_Result.im = pTRD->decode_Arith(pArithDecoder, grContext); | 944 pSegment->m_Result.im = |
| 998 delete pArithDecoder; | 945 pTRD->decode_Arith(pArithDecoder.get(), grContext.get()); |
| 999 if (pSegment->m_Result.im == NULL) { | 946 if (!pSegment->m_Result.im) |
| 1000 nRet = JBIG2_ERROR_FATAL; | 947 return JBIG2_ERROR_FATAL; |
| 1001 goto failed; | |
| 1002 } | |
| 1003 m_pStream->alignByte(); | 948 m_pStream->alignByte(); |
| 1004 m_pStream->offset(2); | 949 m_pStream->offset(2); |
| 1005 } else { | 950 } else { |
| 1006 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; | 951 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; |
| 1007 pSegment->m_Result.im = pTRD->decode_Huffman(m_pStream.get(), grContext); | 952 pSegment->m_Result.im = |
| 1008 if (pSegment->m_Result.im == NULL) { | 953 pTRD->decode_Huffman(m_pStream.get(), grContext.get()); |
| 1009 nRet = JBIG2_ERROR_FATAL; | 954 if (!pSegment->m_Result.im) |
| 1010 goto failed; | 955 return JBIG2_ERROR_FATAL; |
| 1011 } | |
| 1012 m_pStream->alignByte(); | 956 m_pStream->alignByte(); |
| 1013 } | 957 } |
| 1014 if (pSegment->m_cFlags.s.type != 4) { | 958 if (pSegment->m_cFlags.s.type != 4) { |
| 1015 if (!m_bBufSpecified) { | 959 if (!m_bBufSpecified) { |
| 1016 JBig2PageInfo* pPageInfo = m_PageInfoList.back(); | 960 JBig2PageInfo* pPageInfo = m_PageInfoList.back(); |
| 1017 if ((pPageInfo->m_bIsStriped == 1) && | 961 if ((pPageInfo->m_bIsStriped == 1) && |
| 1018 (ri.y + ri.height > m_pPage->m_nHeight)) { | 962 (ri.y + ri.height > m_pPage->m_nHeight)) { |
| 1019 m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0); | 963 m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0); |
| 1020 } | 964 } |
| 1021 } | 965 } |
| 1022 m_pPage->composeFrom(ri.x, ri.y, pSegment->m_Result.im, | 966 m_pPage->composeFrom(ri.x, ri.y, pSegment->m_Result.im, |
| 1023 (JBig2ComposeOp)(ri.flags & 0x03)); | 967 (JBig2ComposeOp)(ri.flags & 0x03)); |
| 1024 delete pSegment->m_Result.im; | 968 delete pSegment->m_Result.im; |
| 1025 pSegment->m_Result.im = NULL; | 969 pSegment->m_Result.im = NULL; |
| 1026 } | 970 } |
| 1027 delete pTRD; | |
| 1028 FX_Free(SBSYMS); | |
| 1029 FX_Free(SBSYMCODES); | |
| 1030 FX_Free(grContext); | |
| 1031 delete Table_B1; | |
| 1032 delete Table_B6; | |
| 1033 delete Table_B7; | |
| 1034 delete Table_B8; | |
| 1035 delete Table_B9; | |
| 1036 delete Table_B10; | |
| 1037 delete Table_B11; | |
| 1038 delete Table_B12; | |
| 1039 delete Table_B13; | |
| 1040 delete Table_B14; | |
| 1041 delete Table_B15; | |
| 1042 return JBIG2_SUCCESS; | 971 return JBIG2_SUCCESS; |
| 1043 failed: | |
| 1044 delete pTRD; | |
| 1045 FX_Free(SBSYMS); | |
| 1046 FX_Free(SBSYMCODES); | |
| 1047 FX_Free(grContext); | |
| 1048 delete Table_B1; | |
| 1049 delete Table_B6; | |
| 1050 delete Table_B7; | |
| 1051 delete Table_B8; | |
| 1052 delete Table_B9; | |
| 1053 delete Table_B10; | |
| 1054 delete Table_B11; | |
| 1055 delete Table_B12; | |
| 1056 delete Table_B13; | |
| 1057 delete Table_B14; | |
| 1058 delete Table_B15; | |
| 1059 return nRet; | |
| 1060 } | 972 } |
| 1061 | 973 |
| 1062 int32_t CJBig2_Context::parsePatternDict(CJBig2_Segment* pSegment, | 974 int32_t CJBig2_Context::parsePatternDict(CJBig2_Segment* pSegment, |
| 1063 IFX_Pause* pPause) { | 975 IFX_Pause* pPause) { |
| 1064 FX_DWORD dwTemp; | |
| 1065 uint8_t cFlags; | 976 uint8_t cFlags; |
| 1066 JBig2ArithCtx* gbContext; | 977 nonstd::unique_ptr<CJBig2_PDDProc> pPDD(new CJBig2_PDDProc); |
| 1067 CJBig2_ArithDecoder* pArithDecoder; | 978 if (m_pStream->read1Byte(&cFlags) != 0 || |
| 1068 int32_t nRet; | 979 m_pStream->read1Byte(&pPDD->HDPW) != 0 || |
| 1069 CJBig2_PDDProc* pPDD = new CJBig2_PDDProc(); | 980 m_pStream->read1Byte(&pPDD->HDPH) != 0 || |
| 1070 if ((m_pStream->read1Byte(&cFlags) != 0) || | 981 m_pStream->readInteger(&pPDD->GRAYMAX) != 0) { |
| 1071 (m_pStream->read1Byte(&pPDD->HDPW) != 0) || | 982 return JBIG2_ERROR_TOO_SHORT; |
| 1072 (m_pStream->read1Byte(&pPDD->HDPH) != 0) || | |
| 1073 (m_pStream->readInteger(&pPDD->GRAYMAX) != 0)) { | |
| 1074 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 1075 goto failed; | |
| 1076 } | 983 } |
| 1077 if (pPDD->GRAYMAX > JBIG2_MAX_PATTERN_INDEX) { | 984 if (pPDD->GRAYMAX > JBIG2_MAX_PATTERN_INDEX) |
| 1078 nRet = JBIG2_ERROR_LIMIT; | 985 return JBIG2_ERROR_LIMIT; |
| 1079 goto failed; | 986 |
| 1080 } | |
| 1081 pPDD->HDMMR = cFlags & 0x01; | 987 pPDD->HDMMR = cFlags & 0x01; |
| 1082 pPDD->HDTEMPLATE = (cFlags >> 1) & 0x03; | 988 pPDD->HDTEMPLATE = (cFlags >> 1) & 0x03; |
| 1083 pSegment->m_nResultType = JBIG2_PATTERN_DICT_POINTER; | 989 pSegment->m_nResultType = JBIG2_PATTERN_DICT_POINTER; |
| 1084 if (pPDD->HDMMR == 0) { | 990 if (pPDD->HDMMR == 0) { |
| 1085 dwTemp = | 991 const size_t size = GetHuffContextSize(pPDD->HDTEMPLATE); |
| 1086 pPDD->HDTEMPLATE == 0 ? 65536 : pPDD->HDTEMPLATE == 1 ? 8192 : 1024; | 992 nonstd::unique_ptr<JBig2ArithCtx, FxFreeDeleter> gbContext( |
| 1087 gbContext = FX_Alloc(JBig2ArithCtx, dwTemp); | 993 FX_Alloc(JBig2ArithCtx, size)); |
| 1088 JBIG2_memset(gbContext, 0, sizeof(JBig2ArithCtx) * dwTemp); | 994 JBIG2_memset(gbContext.get(), 0, sizeof(JBig2ArithCtx) * size); |
| 1089 pArithDecoder = new CJBig2_ArithDecoder(m_pStream.get()); | 995 nonstd::unique_ptr<CJBig2_ArithDecoder> pArithDecoder( |
| 996 new CJBig2_ArithDecoder(m_pStream.get())); |
| 1090 pSegment->m_Result.pd = | 997 pSegment->m_Result.pd = |
| 1091 pPDD->decode_Arith(pArithDecoder, gbContext, pPause); | 998 pPDD->decode_Arith(pArithDecoder.get(), gbContext.get(), pPause); |
| 1092 delete pArithDecoder; | 999 if (!pSegment->m_Result.pd) |
| 1093 if (pSegment->m_Result.pd == NULL) { | 1000 return JBIG2_ERROR_FATAL; |
| 1094 FX_Free(gbContext); | 1001 |
| 1095 nRet = JBIG2_ERROR_FATAL; | |
| 1096 goto failed; | |
| 1097 } | |
| 1098 FX_Free(gbContext); | |
| 1099 m_pStream->alignByte(); | 1002 m_pStream->alignByte(); |
| 1100 m_pStream->offset(2); | 1003 m_pStream->offset(2); |
| 1101 } else { | 1004 } else { |
| 1102 pSegment->m_Result.pd = pPDD->decode_MMR(m_pStream.get(), pPause); | 1005 pSegment->m_Result.pd = pPDD->decode_MMR(m_pStream.get(), pPause); |
| 1103 if (pSegment->m_Result.pd == NULL) { | 1006 if (!pSegment->m_Result.pd) |
| 1104 nRet = JBIG2_ERROR_FATAL; | 1007 return JBIG2_ERROR_FATAL; |
| 1105 goto failed; | |
| 1106 } | |
| 1107 m_pStream->alignByte(); | 1008 m_pStream->alignByte(); |
| 1108 } | 1009 } |
| 1109 delete pPDD; | |
| 1110 return JBIG2_SUCCESS; | 1010 return JBIG2_SUCCESS; |
| 1111 failed: | |
| 1112 delete pPDD; | |
| 1113 return nRet; | |
| 1114 } | 1011 } |
| 1012 |
| 1115 int32_t CJBig2_Context::parseHalftoneRegion(CJBig2_Segment* pSegment, | 1013 int32_t CJBig2_Context::parseHalftoneRegion(CJBig2_Segment* pSegment, |
| 1116 IFX_Pause* pPause) { | 1014 IFX_Pause* pPause) { |
| 1117 FX_DWORD dwTemp; | |
| 1118 uint8_t cFlags; | 1015 uint8_t cFlags; |
| 1119 JBig2RegionInfo ri; | 1016 JBig2RegionInfo ri; |
| 1120 CJBig2_Segment* pSeg; | 1017 nonstd::unique_ptr<CJBig2_HTRDProc> pHRD(new CJBig2_HTRDProc); |
| 1121 CJBig2_PatternDict* pPatternDict; | 1018 if (parseRegionInfo(&ri) != JBIG2_SUCCESS || |
| 1122 JBig2ArithCtx* gbContext; | 1019 m_pStream->read1Byte(&cFlags) != 0 || |
| 1123 CJBig2_ArithDecoder* pArithDecoder; | 1020 m_pStream->readInteger(&pHRD->HGW) != 0 || |
| 1124 int32_t nRet; | 1021 m_pStream->readInteger(&pHRD->HGH) != 0 || |
| 1125 CJBig2_HTRDProc* pHRD = new CJBig2_HTRDProc(); | 1022 m_pStream->readInteger((FX_DWORD*)&pHRD->HGX) != 0 || |
| 1126 if ((parseRegionInfo(&ri) != JBIG2_SUCCESS) || | 1023 m_pStream->readInteger((FX_DWORD*)&pHRD->HGY) != 0 || |
| 1127 (m_pStream->read1Byte(&cFlags) != 0) || | 1024 m_pStream->readShortInteger(&pHRD->HRX) != 0 || |
| 1128 (m_pStream->readInteger(&pHRD->HGW) != 0) || | 1025 m_pStream->readShortInteger(&pHRD->HRY) != 0) { |
| 1129 (m_pStream->readInteger(&pHRD->HGH) != 0) || | 1026 return JBIG2_ERROR_TOO_SHORT; |
| 1130 (m_pStream->readInteger((FX_DWORD*)&pHRD->HGX) != 0) || | |
| 1131 (m_pStream->readInteger((FX_DWORD*)&pHRD->HGY) != 0) || | |
| 1132 (m_pStream->readShortInteger(&pHRD->HRX) != 0) || | |
| 1133 (m_pStream->readShortInteger(&pHRD->HRY) != 0)) { | |
| 1134 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 1135 goto failed; | |
| 1136 } | 1027 } |
| 1137 if (pHRD->HGW == 0 || pHRD->HGH == 0) { | 1028 |
| 1138 nRet = JBIG2_ERROR_FATAL; | 1029 if (pHRD->HGW == 0 || pHRD->HGH == 0) |
| 1139 goto failed; | 1030 return JBIG2_ERROR_FATAL; |
| 1140 } | |
| 1141 | 1031 |
| 1142 pHRD->HBW = ri.width; | 1032 pHRD->HBW = ri.width; |
| 1143 pHRD->HBH = ri.height; | 1033 pHRD->HBH = ri.height; |
| 1144 pHRD->HMMR = cFlags & 0x01; | 1034 pHRD->HMMR = cFlags & 0x01; |
| 1145 pHRD->HTEMPLATE = (cFlags >> 1) & 0x03; | 1035 pHRD->HTEMPLATE = (cFlags >> 1) & 0x03; |
| 1146 pHRD->HENABLESKIP = (cFlags >> 3) & 0x01; | 1036 pHRD->HENABLESKIP = (cFlags >> 3) & 0x01; |
| 1147 pHRD->HCOMBOP = (JBig2ComposeOp)((cFlags >> 4) & 0x07); | 1037 pHRD->HCOMBOP = (JBig2ComposeOp)((cFlags >> 4) & 0x07); |
| 1148 pHRD->HDEFPIXEL = (cFlags >> 7) & 0x01; | 1038 pHRD->HDEFPIXEL = (cFlags >> 7) & 0x01; |
| 1149 if (pSegment->m_nReferred_to_segment_count != 1) { | 1039 if (pSegment->m_nReferred_to_segment_count != 1) |
| 1150 nRet = JBIG2_ERROR_FATAL; | 1040 return JBIG2_ERROR_FATAL; |
| 1151 goto failed; | 1041 |
| 1152 } | 1042 CJBig2_Segment* pSeg = |
| 1153 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[0]); | 1043 findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[0]); |
| 1154 if ((pSeg == NULL) || (pSeg->m_cFlags.s.type != 16)) { | 1044 if (!pSeg || (pSeg->m_cFlags.s.type != 16)) |
| 1155 nRet = JBIG2_ERROR_FATAL; | 1045 return JBIG2_ERROR_FATAL; |
| 1156 goto failed; | 1046 |
| 1157 } | 1047 CJBig2_PatternDict* pPatternDict = pSeg->m_Result.pd; |
| 1158 pPatternDict = pSeg->m_Result.pd; | 1048 if (!pPatternDict || (pPatternDict->NUMPATS == 0)) |
| 1159 if ((pPatternDict == NULL) || (pPatternDict->NUMPATS == 0)) { | 1049 return JBIG2_ERROR_FATAL; |
| 1160 nRet = JBIG2_ERROR_FATAL; | 1050 |
| 1161 goto failed; | |
| 1162 } | |
| 1163 pHRD->HNUMPATS = pPatternDict->NUMPATS; | 1051 pHRD->HNUMPATS = pPatternDict->NUMPATS; |
| 1164 pHRD->HPATS = pPatternDict->HDPATS; | 1052 pHRD->HPATS = pPatternDict->HDPATS; |
| 1165 pHRD->HPW = pPatternDict->HDPATS[0]->m_nWidth; | 1053 pHRD->HPW = pPatternDict->HDPATS[0]->m_nWidth; |
| 1166 pHRD->HPH = pPatternDict->HDPATS[0]->m_nHeight; | 1054 pHRD->HPH = pPatternDict->HDPATS[0]->m_nHeight; |
| 1167 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; | 1055 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; |
| 1168 if (pHRD->HMMR == 0) { | 1056 if (pHRD->HMMR == 0) { |
| 1169 dwTemp = pHRD->HTEMPLATE == 0 ? 65536 : pHRD->HTEMPLATE == 1 ? 8192 : 1024; | 1057 const size_t size = GetHuffContextSize(pHRD->HTEMPLATE); |
| 1170 gbContext = FX_Alloc(JBig2ArithCtx, dwTemp); | 1058 nonstd::unique_ptr<JBig2ArithCtx, FxFreeDeleter> gbContext( |
| 1171 JBIG2_memset(gbContext, 0, sizeof(JBig2ArithCtx) * dwTemp); | 1059 FX_Alloc(JBig2ArithCtx, size)); |
| 1172 pArithDecoder = new CJBig2_ArithDecoder(m_pStream.get()); | 1060 JBIG2_memset(gbContext.get(), 0, sizeof(JBig2ArithCtx) * size); |
| 1061 nonstd::unique_ptr<CJBig2_ArithDecoder> pArithDecoder( |
| 1062 new CJBig2_ArithDecoder(m_pStream.get())); |
| 1173 pSegment->m_Result.im = | 1063 pSegment->m_Result.im = |
| 1174 pHRD->decode_Arith(pArithDecoder, gbContext, pPause); | 1064 pHRD->decode_Arith(pArithDecoder.get(), gbContext.get(), pPause); |
| 1175 delete pArithDecoder; | 1065 if (!pSegment->m_Result.im) |
| 1176 if (pSegment->m_Result.im == NULL) { | 1066 return JBIG2_ERROR_FATAL; |
| 1177 FX_Free(gbContext); | 1067 |
| 1178 nRet = JBIG2_ERROR_FATAL; | |
| 1179 goto failed; | |
| 1180 } | |
| 1181 FX_Free(gbContext); | |
| 1182 m_pStream->alignByte(); | 1068 m_pStream->alignByte(); |
| 1183 m_pStream->offset(2); | 1069 m_pStream->offset(2); |
| 1184 } else { | 1070 } else { |
| 1185 pSegment->m_Result.im = pHRD->decode_MMR(m_pStream.get(), pPause); | 1071 pSegment->m_Result.im = pHRD->decode_MMR(m_pStream.get(), pPause); |
| 1186 if (pSegment->m_Result.im == NULL) { | 1072 if (!pSegment->m_Result.im) |
| 1187 nRet = JBIG2_ERROR_FATAL; | 1073 return JBIG2_ERROR_FATAL; |
| 1188 goto failed; | |
| 1189 } | |
| 1190 m_pStream->alignByte(); | 1074 m_pStream->alignByte(); |
| 1191 } | 1075 } |
| 1192 if (pSegment->m_cFlags.s.type != 20) { | 1076 if (pSegment->m_cFlags.s.type != 20) { |
| 1193 if (!m_bBufSpecified) { | 1077 if (!m_bBufSpecified) { |
| 1194 JBig2PageInfo* pPageInfo = m_PageInfoList.back(); | 1078 JBig2PageInfo* pPageInfo = m_PageInfoList.back(); |
| 1195 if ((pPageInfo->m_bIsStriped == 1) && | 1079 if (pPageInfo->m_bIsStriped == 1 && |
| 1196 (ri.y + ri.height > m_pPage->m_nHeight)) { | 1080 ri.y + ri.height > m_pPage->m_nHeight) { |
| 1197 m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0); | 1081 m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0); |
| 1198 } | 1082 } |
| 1199 } | 1083 } |
| 1200 m_pPage->composeFrom(ri.x, ri.y, pSegment->m_Result.im, | 1084 m_pPage->composeFrom(ri.x, ri.y, pSegment->m_Result.im, |
| 1201 (JBig2ComposeOp)(ri.flags & 0x03)); | 1085 (JBig2ComposeOp)(ri.flags & 0x03)); |
| 1202 delete pSegment->m_Result.im; | 1086 delete pSegment->m_Result.im; |
| 1203 pSegment->m_Result.im = NULL; | 1087 pSegment->m_Result.im = NULL; |
| 1204 } | 1088 } |
| 1205 delete pHRD; | |
| 1206 return JBIG2_SUCCESS; | 1089 return JBIG2_SUCCESS; |
| 1207 failed: | |
| 1208 delete pHRD; | |
| 1209 return nRet; | |
| 1210 } | 1090 } |
| 1211 | 1091 |
| 1212 int32_t CJBig2_Context::parseGenericRegion(CJBig2_Segment* pSegment, | 1092 int32_t CJBig2_Context::parseGenericRegion(CJBig2_Segment* pSegment, |
| 1213 IFX_Pause* pPause) { | 1093 IFX_Pause* pPause) { |
| 1214 FX_DWORD dwTemp; | |
| 1215 uint8_t cFlags; | |
| 1216 int32_t i, nRet; | |
| 1217 if (!m_pGRD) { | 1094 if (!m_pGRD) { |
| 1218 m_pGRD.reset(new CJBig2_GRDProc); | 1095 nonstd::unique_ptr<CJBig2_GRDProc> pGRD(new CJBig2_GRDProc); |
| 1219 if ((parseRegionInfo(&m_ri) != JBIG2_SUCCESS) || | 1096 uint8_t cFlags; |
| 1220 (m_pStream->read1Byte(&cFlags) != 0)) { | 1097 if (parseRegionInfo(&m_ri) != JBIG2_SUCCESS || |
| 1221 nRet = JBIG2_ERROR_TOO_SHORT; | 1098 m_pStream->read1Byte(&cFlags) != 0) { |
| 1222 goto failed; | 1099 return JBIG2_ERROR_TOO_SHORT; |
| 1223 } | 1100 } |
| 1224 if (m_ri.height < 0 || m_ri.width < 0) { | 1101 if (m_ri.height < 0 || m_ri.width < 0) |
| 1225 nRet = JBIG2_FAILED; | 1102 return JBIG2_FAILED; |
| 1226 goto failed; | 1103 |
| 1227 } | 1104 pGRD->GBW = m_ri.width; |
| 1228 m_pGRD->GBW = m_ri.width; | 1105 pGRD->GBH = m_ri.height; |
| 1229 m_pGRD->GBH = m_ri.height; | 1106 pGRD->MMR = cFlags & 0x01; |
| 1230 m_pGRD->MMR = cFlags & 0x01; | 1107 pGRD->GBTEMPLATE = (cFlags >> 1) & 0x03; |
| 1231 m_pGRD->GBTEMPLATE = (cFlags >> 1) & 0x03; | 1108 pGRD->TPGDON = (cFlags >> 3) & 0x01; |
| 1232 m_pGRD->TPGDON = (cFlags >> 3) & 0x01; | 1109 if (pGRD->MMR == 0) { |
| 1233 if (m_pGRD->MMR == 0) { | 1110 if (pGRD->GBTEMPLATE == 0) { |
| 1234 if (m_pGRD->GBTEMPLATE == 0) { | 1111 for (int32_t i = 0; i < 8; ++i) { |
| 1235 for (i = 0; i < 8; i++) { | 1112 if (m_pStream->read1Byte((uint8_t*)&pGRD->GBAT[i]) != 0) { |
| 1236 if (m_pStream->read1Byte((uint8_t*)&m_pGRD->GBAT[i]) != 0) { | 1113 return JBIG2_ERROR_TOO_SHORT; |
| 1237 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 1238 goto failed; | |
| 1239 } | 1114 } |
| 1240 } | 1115 } |
| 1241 } else { | 1116 } else { |
| 1242 for (i = 0; i < 2; i++) { | 1117 for (int32_t i = 0; i < 2; ++i) { |
| 1243 if (m_pStream->read1Byte((uint8_t*)&m_pGRD->GBAT[i]) != 0) { | 1118 if (m_pStream->read1Byte((uint8_t*)&pGRD->GBAT[i]) != 0) { |
| 1244 nRet = JBIG2_ERROR_TOO_SHORT; | 1119 return JBIG2_ERROR_TOO_SHORT; |
| 1245 goto failed; | |
| 1246 } | 1120 } |
| 1247 } | 1121 } |
| 1248 } | 1122 } |
| 1249 } | 1123 } |
| 1250 m_pGRD->USESKIP = 0; | 1124 pGRD->USESKIP = 0; |
| 1125 m_pGRD = nonstd::move(pGRD); |
| 1251 } | 1126 } |
| 1252 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; | 1127 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; |
| 1253 if (m_pGRD->MMR == 0) { | 1128 if (m_pGRD->MMR == 0) { |
| 1254 dwTemp = | 1129 if (!m_gbContext) { |
| 1255 m_pGRD->GBTEMPLATE == 0 ? 65536 : m_pGRD->GBTEMPLATE == 1 ? 8192 : 1024; | 1130 const size_t size = GetHuffContextSize(m_pGRD->GBTEMPLATE); |
| 1256 if (m_gbContext == NULL) { | 1131 m_gbContext = FX_Alloc(JBig2ArithCtx, size); |
| 1257 m_gbContext = FX_Alloc(JBig2ArithCtx, dwTemp); | 1132 JBIG2_memset(m_gbContext, 0, sizeof(JBig2ArithCtx) * size); |
| 1258 JBIG2_memset(m_gbContext, 0, sizeof(JBig2ArithCtx) * dwTemp); | |
| 1259 } | 1133 } |
| 1260 if (m_pArithDecoder == NULL) { | 1134 if (!m_pArithDecoder) { |
| 1261 m_pArithDecoder = new CJBig2_ArithDecoder(m_pStream.get()); | 1135 m_pArithDecoder.reset(new CJBig2_ArithDecoder(m_pStream.get())); |
| 1262 m_ProcessingStatus = m_pGRD->Start_decode_Arith( | 1136 m_ProcessingStatus = m_pGRD->Start_decode_Arith( |
| 1263 &pSegment->m_Result.im, m_pArithDecoder, m_gbContext, pPause); | 1137 &pSegment->m_Result.im, m_pArithDecoder.get(), m_gbContext, pPause); |
| 1264 } else { | 1138 } else { |
| 1265 m_ProcessingStatus = m_pGRD->Continue_decode(pPause); | 1139 m_ProcessingStatus = m_pGRD->Continue_decode(pPause); |
| 1266 } | 1140 } |
| 1267 if (m_ProcessingStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) { | 1141 if (m_ProcessingStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) { |
| 1268 if (pSegment->m_cFlags.s.type != 36) { | 1142 if (pSegment->m_cFlags.s.type != 36) { |
| 1269 if (!m_bBufSpecified) { | 1143 if (!m_bBufSpecified) { |
| 1270 JBig2PageInfo* pPageInfo = m_PageInfoList.back(); | 1144 JBig2PageInfo* pPageInfo = m_PageInfoList.back(); |
| 1271 if ((pPageInfo->m_bIsStriped == 1) && | 1145 if ((pPageInfo->m_bIsStriped == 1) && |
| 1272 (m_ri.y + m_ri.height > m_pPage->m_nHeight)) { | 1146 (m_ri.y + m_ri.height > m_pPage->m_nHeight)) { |
| 1273 m_pPage->expand(m_ri.y + m_ri.height, | 1147 m_pPage->expand(m_ri.y + m_ri.height, |
| 1274 (pPageInfo->m_cFlags & 4) ? 1 : 0); | 1148 (pPageInfo->m_cFlags & 4) ? 1 : 0); |
| 1275 } | 1149 } |
| 1276 } | 1150 } |
| 1277 FX_RECT Rect = m_pGRD->GetReplaceRect(); | 1151 FX_RECT Rect = m_pGRD->GetReplaceRect(); |
| 1278 m_pPage->composeFrom(m_ri.x + Rect.left, m_ri.y + Rect.top, | 1152 m_pPage->composeFrom(m_ri.x + Rect.left, m_ri.y + Rect.top, |
| 1279 pSegment->m_Result.im, | 1153 pSegment->m_Result.im, |
| 1280 (JBig2ComposeOp)(m_ri.flags & 0x03), &Rect); | 1154 (JBig2ComposeOp)(m_ri.flags & 0x03), &Rect); |
| 1281 } | 1155 } |
| 1282 return JBIG2_SUCCESS; | 1156 return JBIG2_SUCCESS; |
| 1283 } else { | 1157 } else { |
| 1284 delete m_pArithDecoder; | 1158 m_pArithDecoder.reset(); |
| 1285 m_pArithDecoder = NULL; | |
| 1286 if (pSegment->m_Result.im == NULL) { | |
| 1287 FX_Free(m_gbContext); | |
| 1288 nRet = JBIG2_ERROR_FATAL; | |
| 1289 m_gbContext = NULL; | |
| 1290 m_ProcessingStatus = FXCODEC_STATUS_ERROR; | |
| 1291 goto failed; | |
| 1292 } | |
| 1293 FX_Free(m_gbContext); | 1159 FX_Free(m_gbContext); |
| 1294 m_gbContext = NULL; | 1160 m_gbContext = NULL; |
| 1161 if (!pSegment->m_Result.im) { |
| 1162 m_ProcessingStatus = FXCODEC_STATUS_ERROR; |
| 1163 m_pGRD.reset(); |
| 1164 return JBIG2_ERROR_FATAL; |
| 1165 } |
| 1295 m_pStream->alignByte(); | 1166 m_pStream->alignByte(); |
| 1296 m_pStream->offset(2); | 1167 m_pStream->offset(2); |
| 1297 } | 1168 } |
| 1298 } else { | 1169 } else { |
| 1299 FXCODEC_STATUS status = m_pGRD->Start_decode_MMR(&pSegment->m_Result.im, | 1170 FXCODEC_STATUS status = m_pGRD->Start_decode_MMR(&pSegment->m_Result.im, |
| 1300 m_pStream.get(), pPause); | 1171 m_pStream.get(), pPause); |
| 1301 while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) { | 1172 while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) { |
| 1302 m_pGRD->Continue_decode(pPause); | 1173 m_pGRD->Continue_decode(pPause); |
| 1303 } | 1174 } |
| 1304 if (pSegment->m_Result.im == NULL) { | 1175 if (!pSegment->m_Result.im) { |
| 1305 nRet = JBIG2_ERROR_FATAL; | 1176 m_pGRD.reset(); |
| 1306 goto failed; | 1177 return JBIG2_ERROR_FATAL; |
| 1307 } | 1178 } |
| 1308 m_pStream->alignByte(); | 1179 m_pStream->alignByte(); |
| 1309 } | 1180 } |
| 1310 if (pSegment->m_cFlags.s.type != 36) { | 1181 if (pSegment->m_cFlags.s.type != 36) { |
| 1311 if (!m_bBufSpecified) { | 1182 if (!m_bBufSpecified) { |
| 1312 JBig2PageInfo* pPageInfo = m_PageInfoList.back(); | 1183 JBig2PageInfo* pPageInfo = m_PageInfoList.back(); |
| 1313 if ((pPageInfo->m_bIsStriped == 1) && | 1184 if ((pPageInfo->m_bIsStriped == 1) && |
| 1314 (m_ri.y + m_ri.height > m_pPage->m_nHeight)) { | 1185 (m_ri.y + m_ri.height > m_pPage->m_nHeight)) { |
| 1315 m_pPage->expand(m_ri.y + m_ri.height, | 1186 m_pPage->expand(m_ri.y + m_ri.height, |
| 1316 (pPageInfo->m_cFlags & 4) ? 1 : 0); | 1187 (pPageInfo->m_cFlags & 4) ? 1 : 0); |
| 1317 } | 1188 } |
| 1318 } | 1189 } |
| 1319 FX_RECT Rect = m_pGRD->GetReplaceRect(); | 1190 FX_RECT Rect = m_pGRD->GetReplaceRect(); |
| 1320 m_pPage->composeFrom(m_ri.x + Rect.left, m_ri.y + Rect.top, | 1191 m_pPage->composeFrom(m_ri.x + Rect.left, m_ri.y + Rect.top, |
| 1321 pSegment->m_Result.im, | 1192 pSegment->m_Result.im, |
| 1322 (JBig2ComposeOp)(m_ri.flags & 0x03), &Rect); | 1193 (JBig2ComposeOp)(m_ri.flags & 0x03), &Rect); |
| 1323 delete pSegment->m_Result.im; | 1194 delete pSegment->m_Result.im; |
| 1324 pSegment->m_Result.im = NULL; | 1195 pSegment->m_Result.im = NULL; |
| 1325 } | 1196 } |
| 1326 m_pGRD.reset(); | 1197 m_pGRD.reset(); |
| 1327 return JBIG2_SUCCESS; | 1198 return JBIG2_SUCCESS; |
| 1328 failed: | |
| 1329 m_pGRD.reset(); | |
| 1330 return nRet; | |
| 1331 } | 1199 } |
| 1332 | 1200 |
| 1333 int32_t CJBig2_Context::parseGenericRefinementRegion(CJBig2_Segment* pSegment) { | 1201 int32_t CJBig2_Context::parseGenericRefinementRegion(CJBig2_Segment* pSegment) { |
| 1334 FX_DWORD dwTemp; | |
| 1335 JBig2RegionInfo ri; | 1202 JBig2RegionInfo ri; |
| 1336 CJBig2_Segment* pSeg; | |
| 1337 int32_t i, nRet; | |
| 1338 uint8_t cFlags; | 1203 uint8_t cFlags; |
| 1339 JBig2ArithCtx* grContext; | 1204 if (parseRegionInfo(&ri) != JBIG2_SUCCESS || |
| 1340 CJBig2_ArithDecoder* pArithDecoder; | 1205 m_pStream->read1Byte(&cFlags) != 0) { |
| 1341 CJBig2_GRRDProc* pGRRD = new CJBig2_GRRDProc(); | 1206 return JBIG2_ERROR_TOO_SHORT; |
| 1342 if ((parseRegionInfo(&ri) != JBIG2_SUCCESS) || | |
| 1343 (m_pStream->read1Byte(&cFlags) != 0)) { | |
| 1344 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 1345 goto failed; | |
| 1346 } | 1207 } |
| 1208 nonstd::unique_ptr<CJBig2_GRRDProc> pGRRD(new CJBig2_GRRDProc); |
| 1347 pGRRD->GRW = ri.width; | 1209 pGRRD->GRW = ri.width; |
| 1348 pGRRD->GRH = ri.height; | 1210 pGRRD->GRH = ri.height; |
| 1349 pGRRD->GRTEMPLATE = cFlags & 0x01; | 1211 pGRRD->GRTEMPLATE = cFlags & 0x01; |
| 1350 pGRRD->TPGRON = (cFlags >> 1) & 0x01; | 1212 pGRRD->TPGRON = (cFlags >> 1) & 0x01; |
| 1351 if (pGRRD->GRTEMPLATE == 0) { | 1213 if (pGRRD->GRTEMPLATE == 0) { |
| 1352 for (i = 0; i < 4; i++) { | 1214 for (int32_t i = 0; i < 4; ++i) { |
| 1353 if (m_pStream->read1Byte((uint8_t*)&pGRRD->GRAT[i]) != 0) { | 1215 if (m_pStream->read1Byte((uint8_t*)&pGRRD->GRAT[i]) != 0) |
| 1354 nRet = JBIG2_ERROR_TOO_SHORT; | 1216 return JBIG2_ERROR_TOO_SHORT; |
| 1355 goto failed; | |
| 1356 } | |
| 1357 } | 1217 } |
| 1358 } | 1218 } |
| 1359 pSeg = NULL; | 1219 CJBig2_Segment* pSeg = nullptr; |
| 1360 if (pSegment->m_nReferred_to_segment_count > 0) { | 1220 if (pSegment->m_nReferred_to_segment_count > 0) { |
| 1361 for (i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | 1221 int32_t i; |
| 1222 for (i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
| 1362 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[0]); | 1223 pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[0]); |
| 1363 if (pSeg == NULL) { | 1224 if (!pSeg) |
| 1364 nRet = JBIG2_ERROR_FATAL; | 1225 return JBIG2_ERROR_FATAL; |
| 1365 goto failed; | 1226 |
| 1366 } | 1227 if (pSeg->m_cFlags.s.type == 4 || pSeg->m_cFlags.s.type == 20 || |
| 1367 if ((pSeg->m_cFlags.s.type == 4) || (pSeg->m_cFlags.s.type == 20) || | 1228 pSeg->m_cFlags.s.type == 36 || pSeg->m_cFlags.s.type == 40) { |
| 1368 (pSeg->m_cFlags.s.type == 36) || (pSeg->m_cFlags.s.type == 40)) { | |
| 1369 break; | 1229 break; |
| 1370 } | 1230 } |
| 1371 } | 1231 } |
| 1372 if (i >= pSegment->m_nReferred_to_segment_count) { | 1232 if (i >= pSegment->m_nReferred_to_segment_count) |
| 1373 nRet = JBIG2_ERROR_FATAL; | 1233 return JBIG2_ERROR_FATAL; |
| 1374 goto failed; | 1234 |
| 1375 } | |
| 1376 pGRRD->GRREFERENCE = pSeg->m_Result.im; | 1235 pGRRD->GRREFERENCE = pSeg->m_Result.im; |
| 1377 } else { | 1236 } else { |
| 1378 pGRRD->GRREFERENCE = m_pPage.get(); | 1237 pGRRD->GRREFERENCE = m_pPage.get(); |
| 1379 } | 1238 } |
| 1380 pGRRD->GRREFERENCEDX = 0; | 1239 pGRRD->GRREFERENCEDX = 0; |
| 1381 pGRRD->GRREFERENCEDY = 0; | 1240 pGRRD->GRREFERENCEDY = 0; |
| 1382 dwTemp = pGRRD->GRTEMPLATE ? 1 << 10 : 1 << 13; | 1241 const size_t size = GetRefAggContextSize(pGRRD->GRTEMPLATE); |
| 1383 grContext = FX_Alloc(JBig2ArithCtx, dwTemp); | 1242 nonstd::unique_ptr<JBig2ArithCtx, FxFreeDeleter> grContext( |
| 1384 JBIG2_memset(grContext, 0, sizeof(JBig2ArithCtx) * dwTemp); | 1243 FX_Alloc(JBig2ArithCtx, size)); |
| 1385 pArithDecoder = new CJBig2_ArithDecoder(m_pStream.get()); | 1244 JBIG2_memset(grContext.get(), 0, sizeof(JBig2ArithCtx) * size); |
| 1245 nonstd::unique_ptr<CJBig2_ArithDecoder> pArithDecoder( |
| 1246 new CJBig2_ArithDecoder(m_pStream.get())); |
| 1386 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; | 1247 pSegment->m_nResultType = JBIG2_IMAGE_POINTER; |
| 1387 pSegment->m_Result.im = pGRRD->decode(pArithDecoder, grContext); | 1248 pSegment->m_Result.im = pGRRD->decode(pArithDecoder.get(), grContext.get()); |
| 1388 delete pArithDecoder; | 1249 if (!pSegment->m_Result.im) |
| 1389 if (pSegment->m_Result.im == NULL) { | 1250 return JBIG2_ERROR_FATAL; |
| 1390 FX_Free(grContext); | 1251 |
| 1391 nRet = JBIG2_ERROR_FATAL; | |
| 1392 goto failed; | |
| 1393 } | |
| 1394 FX_Free(grContext); | |
| 1395 m_pStream->alignByte(); | 1252 m_pStream->alignByte(); |
| 1396 m_pStream->offset(2); | 1253 m_pStream->offset(2); |
| 1397 if (pSegment->m_cFlags.s.type != 40) { | 1254 if (pSegment->m_cFlags.s.type != 40) { |
| 1398 if (!m_bBufSpecified) { | 1255 if (!m_bBufSpecified) { |
| 1399 JBig2PageInfo* pPageInfo = m_PageInfoList.back(); | 1256 JBig2PageInfo* pPageInfo = m_PageInfoList.back(); |
| 1400 if ((pPageInfo->m_bIsStriped == 1) && | 1257 if ((pPageInfo->m_bIsStriped == 1) && |
| 1401 (ri.y + ri.height > m_pPage->m_nHeight)) { | 1258 (ri.y + ri.height > m_pPage->m_nHeight)) { |
| 1402 m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0); | 1259 m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0); |
| 1403 } | 1260 } |
| 1404 } | 1261 } |
| 1405 m_pPage->composeFrom(ri.x, ri.y, pSegment->m_Result.im, | 1262 m_pPage->composeFrom(ri.x, ri.y, pSegment->m_Result.im, |
| 1406 (JBig2ComposeOp)(ri.flags & 0x03)); | 1263 (JBig2ComposeOp)(ri.flags & 0x03)); |
| 1407 delete pSegment->m_Result.im; | 1264 delete pSegment->m_Result.im; |
| 1408 pSegment->m_Result.im = NULL; | 1265 pSegment->m_Result.im = NULL; |
| 1409 } | 1266 } |
| 1410 delete pGRRD; | |
| 1411 return JBIG2_SUCCESS; | 1267 return JBIG2_SUCCESS; |
| 1412 failed: | |
| 1413 delete pGRRD; | |
| 1414 return nRet; | |
| 1415 } | 1268 } |
| 1269 |
| 1416 int32_t CJBig2_Context::parseTable(CJBig2_Segment* pSegment) { | 1270 int32_t CJBig2_Context::parseTable(CJBig2_Segment* pSegment) { |
| 1417 pSegment->m_nResultType = JBIG2_HUFFMAN_TABLE_POINTER; | 1271 pSegment->m_nResultType = JBIG2_HUFFMAN_TABLE_POINTER; |
| 1418 pSegment->m_Result.ht = new CJBig2_HuffmanTable(m_pStream.get()); | 1272 pSegment->m_Result.ht = new CJBig2_HuffmanTable(m_pStream.get()); |
| 1419 if (!pSegment->m_Result.ht->isOK()) { | 1273 if (!pSegment->m_Result.ht->isOK()) { |
| 1420 delete pSegment->m_Result.ht; | 1274 delete pSegment->m_Result.ht; |
| 1421 pSegment->m_Result.ht = NULL; | 1275 pSegment->m_Result.ht = NULL; |
| 1422 return JBIG2_ERROR_FATAL; | 1276 return JBIG2_ERROR_FATAL; |
| 1423 } | 1277 } |
| 1424 m_pStream->alignByte(); | 1278 m_pStream->alignByte(); |
| 1425 return JBIG2_SUCCESS; | 1279 return JBIG2_SUCCESS; |
| 1426 } | 1280 } |
| 1281 |
| 1427 int32_t CJBig2_Context::parseRegionInfo(JBig2RegionInfo* pRI) { | 1282 int32_t CJBig2_Context::parseRegionInfo(JBig2RegionInfo* pRI) { |
| 1428 if ((m_pStream->readInteger((FX_DWORD*)&pRI->width) != 0) || | 1283 if (m_pStream->readInteger((FX_DWORD*)&pRI->width) != 0 || |
| 1429 (m_pStream->readInteger((FX_DWORD*)&pRI->height) != 0) || | 1284 m_pStream->readInteger((FX_DWORD*)&pRI->height) != 0 || |
| 1430 (m_pStream->readInteger((FX_DWORD*)&pRI->x) != 0) || | 1285 m_pStream->readInteger((FX_DWORD*)&pRI->x) != 0 || |
| 1431 (m_pStream->readInteger((FX_DWORD*)&pRI->y) != 0) || | 1286 m_pStream->readInteger((FX_DWORD*)&pRI->y) != 0 || |
| 1432 (m_pStream->read1Byte(&pRI->flags) != 0)) { | 1287 m_pStream->read1Byte(&pRI->flags) != 0) { |
| 1433 return JBIG2_ERROR_TOO_SHORT; | 1288 return JBIG2_ERROR_TOO_SHORT; |
| 1434 } | 1289 } |
| 1435 return JBIG2_SUCCESS; | 1290 return JBIG2_SUCCESS; |
| 1436 } | 1291 } |
| 1292 |
| 1437 JBig2HuffmanCode* CJBig2_Context::decodeSymbolIDHuffmanTable( | 1293 JBig2HuffmanCode* CJBig2_Context::decodeSymbolIDHuffmanTable( |
| 1438 CJBig2_BitStream* pStream, | 1294 CJBig2_BitStream* pStream, |
| 1439 FX_DWORD SBNUMSYMS) { | 1295 FX_DWORD SBNUMSYMS) { |
| 1440 JBig2HuffmanCode* SBSYMCODES; | 1296 size_t kRunCodesSize = 35; |
| 1441 int32_t runcodes[35]; | 1297 int32_t runcodes[kRunCodesSize]; |
| 1442 int32_t runcodes_len[35]; | 1298 int32_t runcodes_len[kRunCodesSize]; |
| 1443 int32_t runcode; | 1299 for (int32_t i = 0; i < kRunCodesSize; ++i) { |
| 1444 int32_t i; | 1300 if (pStream->readNBits(4, &runcodes_len[i]) != 0) |
| 1445 int32_t j; | 1301 return nullptr; |
| 1446 int32_t nVal; | 1302 } |
| 1447 int32_t nBits; | 1303 huffman_assign_code(runcodes, runcodes_len, kRunCodesSize); |
| 1304 |
| 1305 nonstd::unique_ptr<JBig2HuffmanCode, FxFreeDeleter> SBSYMCODES( |
| 1306 FX_Alloc(JBig2HuffmanCode, SBNUMSYMS)); |
| 1448 int32_t run; | 1307 int32_t run; |
| 1449 FX_DWORD nTemp; | 1308 int32_t i = 0; |
| 1450 SBSYMCODES = FX_Alloc(JBig2HuffmanCode, SBNUMSYMS); | |
| 1451 for (i = 0; i < 35; i++) { | |
| 1452 if (pStream->readNBits(4, &runcodes_len[i]) != 0) { | |
| 1453 goto failed; | |
| 1454 } | |
| 1455 } | |
| 1456 huffman_assign_code(runcodes, runcodes_len, 35); | |
| 1457 i = 0; | |
| 1458 while (i < (int)SBNUMSYMS) { | 1309 while (i < (int)SBNUMSYMS) { |
| 1459 nVal = 0; | 1310 int32_t j; |
| 1460 nBits = 0; | 1311 int32_t nVal = 0; |
| 1461 for (;;) { | 1312 int32_t nBits = 0; |
| 1462 if (pStream->read1Bit(&nTemp) != 0) { | 1313 FX_DWORD nTemp; |
| 1463 goto failed; | 1314 while (true) { |
| 1464 } | 1315 if (pStream->read1Bit(&nTemp) != 0) |
| 1316 return nullptr; |
| 1317 |
| 1465 nVal = (nVal << 1) | nTemp; | 1318 nVal = (nVal << 1) | nTemp; |
| 1466 nBits++; | 1319 ++nBits; |
| 1467 for (j = 0; j < 35; j++) { | 1320 for (j = 0; j < kRunCodesSize; ++j) { |
| 1468 if ((nBits == runcodes_len[j]) && (nVal == runcodes[j])) { | 1321 if (nBits == runcodes_len[j] && nVal == runcodes[j]) { |
| 1469 break; | 1322 break; |
| 1470 } | 1323 } |
| 1471 } | 1324 } |
| 1472 if (j < 35) { | 1325 if (j < kRunCodesSize) { |
| 1473 break; | 1326 break; |
| 1474 } | 1327 } |
| 1475 } | 1328 } |
| 1476 runcode = j; | 1329 int32_t runcode = j; |
| 1477 if (runcode < 32) { | 1330 if (runcode < 32) { |
| 1478 SBSYMCODES[i].codelen = runcode; | 1331 SBSYMCODES.get()[i].codelen = runcode; |
| 1479 run = 0; | 1332 run = 0; |
| 1480 } else if (runcode == 32) { | 1333 } else if (runcode == 32) { |
| 1481 if (pStream->readNBits(2, &nTemp) != 0) { | 1334 if (pStream->readNBits(2, &nTemp) != 0) |
| 1482 goto failed; | 1335 return nullptr; |
| 1483 } | |
| 1484 run = nTemp + 3; | 1336 run = nTemp + 3; |
| 1485 } else if (runcode == 33) { | 1337 } else if (runcode == 33) { |
| 1486 if (pStream->readNBits(3, &nTemp) != 0) { | 1338 if (pStream->readNBits(3, &nTemp) != 0) |
| 1487 goto failed; | 1339 return nullptr; |
| 1488 } | |
| 1489 run = nTemp + 3; | 1340 run = nTemp + 3; |
| 1490 } else if (runcode == 34) { | 1341 } else if (runcode == 34) { |
| 1491 if (pStream->readNBits(7, &nTemp) != 0) { | 1342 if (pStream->readNBits(7, &nTemp) != 0) |
| 1492 goto failed; | 1343 return nullptr; |
| 1493 } | |
| 1494 run = nTemp + 11; | 1344 run = nTemp + 11; |
| 1495 } | 1345 } |
| 1496 if (run > 0) { | 1346 if (run > 0) { |
| 1497 if (i + run > (int)SBNUMSYMS) { | 1347 if (i + run > (int)SBNUMSYMS) |
| 1498 goto failed; | 1348 return nullptr; |
| 1499 } | 1349 for (j = 0; j < run; ++j) { |
| 1500 for (j = 0; j < run; j++) { | |
| 1501 if (runcode == 32 && i > 0) { | 1350 if (runcode == 32 && i > 0) { |
| 1502 SBSYMCODES[i + j].codelen = SBSYMCODES[i - 1].codelen; | 1351 SBSYMCODES.get()[i + j].codelen = SBSYMCODES.get()[i - 1].codelen; |
| 1503 } else { | 1352 } else { |
| 1504 SBSYMCODES[i + j].codelen = 0; | 1353 SBSYMCODES.get()[i + j].codelen = 0; |
| 1505 } | 1354 } |
| 1506 } | 1355 } |
| 1507 i += run; | 1356 i += run; |
| 1508 } else { | 1357 } else { |
| 1509 i++; | 1358 ++i; |
| 1510 } | 1359 } |
| 1511 } | 1360 } |
| 1512 huffman_assign_code(SBSYMCODES, SBNUMSYMS); | 1361 huffman_assign_code(SBSYMCODES.get(), SBNUMSYMS); |
| 1513 return SBSYMCODES; | 1362 return SBSYMCODES.release(); |
| 1514 failed: | |
| 1515 FX_Free(SBSYMCODES); | |
| 1516 return NULL; | |
| 1517 } | 1363 } |
| 1364 |
| 1518 void CJBig2_Context::huffman_assign_code(int* CODES, int* PREFLEN, int NTEMP) { | 1365 void CJBig2_Context::huffman_assign_code(int* CODES, int* PREFLEN, int NTEMP) { |
| 1366 // TODO(thestig) CJBig2_HuffmanTable::parseFromCodedBuffer() has similar code. |
| 1519 int CURLEN, LENMAX, CURCODE, CURTEMP, i; | 1367 int CURLEN, LENMAX, CURCODE, CURTEMP, i; |
| 1520 int* LENCOUNT; | 1368 int* LENCOUNT; |
| 1521 int* FIRSTCODE; | 1369 int* FIRSTCODE; |
| 1522 LENMAX = 0; | 1370 LENMAX = 0; |
| 1523 for (i = 0; i < NTEMP; i++) { | 1371 for (i = 0; i < NTEMP; ++i) { |
| 1524 if (PREFLEN[i] > LENMAX) { | 1372 if (PREFLEN[i] > LENMAX) { |
| 1525 LENMAX = PREFLEN[i]; | 1373 LENMAX = PREFLEN[i]; |
| 1526 } | 1374 } |
| 1527 } | 1375 } |
| 1528 LENCOUNT = FX_Alloc(int, LENMAX + 1); | 1376 LENCOUNT = FX_Alloc(int, LENMAX + 1); |
| 1529 JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1)); | 1377 JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1)); |
| 1530 FIRSTCODE = FX_Alloc(int, LENMAX + 1); | 1378 FIRSTCODE = FX_Alloc(int, LENMAX + 1); |
| 1531 for (i = 0; i < NTEMP; i++) { | 1379 for (i = 0; i < NTEMP; ++i) { |
| 1532 LENCOUNT[PREFLEN[i]]++; | 1380 ++LENCOUNT[PREFLEN[i]]; |
| 1533 } | 1381 } |
| 1534 CURLEN = 1; | 1382 CURLEN = 1; |
| 1535 FIRSTCODE[0] = 0; | 1383 FIRSTCODE[0] = 0; |
| 1536 LENCOUNT[0] = 0; | 1384 LENCOUNT[0] = 0; |
| 1537 while (CURLEN <= LENMAX) { | 1385 while (CURLEN <= LENMAX) { |
| 1538 FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1; | 1386 FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1; |
| 1539 CURCODE = FIRSTCODE[CURLEN]; | 1387 CURCODE = FIRSTCODE[CURLEN]; |
| 1540 CURTEMP = 0; | 1388 CURTEMP = 0; |
| 1541 while (CURTEMP < NTEMP) { | 1389 while (CURTEMP < NTEMP) { |
| 1542 if (PREFLEN[CURTEMP] == CURLEN) { | 1390 if (PREFLEN[CURTEMP] == CURLEN) { |
| 1543 CODES[CURTEMP] = CURCODE; | 1391 CODES[CURTEMP] = CURCODE; |
| 1544 CURCODE = CURCODE + 1; | 1392 CURCODE = CURCODE + 1; |
| 1545 } | 1393 } |
| 1546 CURTEMP = CURTEMP + 1; | 1394 CURTEMP = CURTEMP + 1; |
| 1547 } | 1395 } |
| 1548 CURLEN = CURLEN + 1; | 1396 CURLEN = CURLEN + 1; |
| 1549 } | 1397 } |
| 1550 FX_Free(LENCOUNT); | 1398 FX_Free(LENCOUNT); |
| 1551 FX_Free(FIRSTCODE); | 1399 FX_Free(FIRSTCODE); |
| 1552 } | 1400 } |
| 1553 void CJBig2_Context::huffman_assign_code(JBig2HuffmanCode* SBSYMCODES, | 1401 void CJBig2_Context::huffman_assign_code(JBig2HuffmanCode* SBSYMCODES, |
| 1554 int NTEMP) { | 1402 int NTEMP) { |
| 1555 int CURLEN, LENMAX, CURCODE, CURTEMP, i; | 1403 int CURLEN, LENMAX, CURCODE, CURTEMP, i; |
| 1556 int* LENCOUNT; | 1404 int* LENCOUNT; |
| 1557 int* FIRSTCODE; | 1405 int* FIRSTCODE; |
| 1558 LENMAX = 0; | 1406 LENMAX = 0; |
| 1559 for (i = 0; i < NTEMP; i++) { | 1407 for (i = 0; i < NTEMP; ++i) { |
| 1560 if (SBSYMCODES[i].codelen > LENMAX) { | 1408 if (SBSYMCODES[i].codelen > LENMAX) { |
| 1561 LENMAX = SBSYMCODES[i].codelen; | 1409 LENMAX = SBSYMCODES[i].codelen; |
| 1562 } | 1410 } |
| 1563 } | 1411 } |
| 1564 LENCOUNT = FX_Alloc(int, (LENMAX + 1)); | 1412 LENCOUNT = FX_Alloc(int, (LENMAX + 1)); |
| 1565 JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1)); | 1413 JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1)); |
| 1566 FIRSTCODE = FX_Alloc(int, (LENMAX + 1)); | 1414 FIRSTCODE = FX_Alloc(int, (LENMAX + 1)); |
| 1567 for (i = 0; i < NTEMP; i++) { | 1415 for (i = 0; i < NTEMP; ++i) { |
| 1568 LENCOUNT[SBSYMCODES[i].codelen]++; | 1416 ++LENCOUNT[SBSYMCODES[i].codelen]; |
| 1569 } | 1417 } |
| 1570 CURLEN = 1; | 1418 CURLEN = 1; |
| 1571 FIRSTCODE[0] = 0; | 1419 FIRSTCODE[0] = 0; |
| 1572 LENCOUNT[0] = 0; | 1420 LENCOUNT[0] = 0; |
| 1573 while (CURLEN <= LENMAX) { | 1421 while (CURLEN <= LENMAX) { |
| 1574 FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1; | 1422 FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1; |
| 1575 CURCODE = FIRSTCODE[CURLEN]; | 1423 CURCODE = FIRSTCODE[CURLEN]; |
| 1576 CURTEMP = 0; | 1424 CURTEMP = 0; |
| 1577 while (CURTEMP < NTEMP) { | 1425 while (CURTEMP < NTEMP) { |
| 1578 if (SBSYMCODES[CURTEMP].codelen == CURLEN) { | 1426 if (SBSYMCODES[CURTEMP].codelen == CURLEN) { |
| 1579 SBSYMCODES[CURTEMP].code = CURCODE; | 1427 SBSYMCODES[CURTEMP].code = CURCODE; |
| 1580 CURCODE = CURCODE + 1; | 1428 CURCODE = CURCODE + 1; |
| 1581 } | 1429 } |
| 1582 CURTEMP = CURTEMP + 1; | 1430 CURTEMP = CURTEMP + 1; |
| 1583 } | 1431 } |
| 1584 CURLEN = CURLEN + 1; | 1432 CURLEN = CURLEN + 1; |
| 1585 } | 1433 } |
| 1586 FX_Free(LENCOUNT); | 1434 FX_Free(LENCOUNT); |
| 1587 FX_Free(FIRSTCODE); | 1435 FX_Free(FIRSTCODE); |
| 1588 } | 1436 } |
| OLD | NEW |