Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(397)

Side by Side Diff: core/src/fxcodec/jbig2/JBig2_Context.cpp

Issue 1382613003: Remove gotos in JBig2 code. (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: address comments Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/src/fxcodec/jbig2/JBig2_Context.h ('k') | core/src/fxcodec/jbig2/JBig2_GsidProc.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « core/src/fxcodec/jbig2/JBig2_Context.h ('k') | core/src/fxcodec/jbig2/JBig2_GsidProc.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698