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