blob: 53faab4a464599ee057a9543cafa260bf6ecfe7b [file] [log] [blame]
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#include "JBig2_GeneralDecoder.h"
#include "JBig2_ArithDecoder.h"
#include "JBig2_ArithIntDecoder.h"
#include "JBig2_HuffmanDecoder.h"
#include "JBig2_HuffmanTable.h"
#include "JBig2_PatternDict.h"
extern const JBig2ArithQe QeTable[] = {
{ 0x5601, 1, 1, 1 },
{ 0x3401, 2, 6, 0 },
{ 0x1801, 3, 9, 0 },
{ 0x0AC1, 4, 12, 0 },
{ 0x0521, 5, 29, 0 },
{ 0x0221, 38, 33, 0 },
{ 0x5601, 7, 6, 1 },
{ 0x5401, 8, 14, 0 },
{ 0x4801, 9, 14, 0 },
{ 0x3801, 10, 14, 0 },
{ 0x3001, 11, 17, 0 },
{ 0x2401, 12, 18, 0 },
{ 0x1C01, 13, 20, 0 },
{ 0x1601, 29, 21, 0 },
{ 0x5601, 15, 14, 1 },
{ 0x5401, 16, 14, 0 },
{ 0x5101, 17, 15, 0 },
{ 0x4801, 18, 16, 0 },
{ 0x3801, 19, 17, 0 },
{ 0x3401, 20, 18, 0 },
{ 0x3001, 21, 19, 0 },
{ 0x2801, 22, 19, 0 },
{ 0x2401, 23, 20, 0 },
{ 0x2201, 24, 21, 0 },
{ 0x1C01, 25, 22, 0 },
{ 0x1801, 26, 23, 0 },
{ 0x1601, 27, 24, 0 },
{ 0x1401, 28, 25, 0 },
{ 0x1201, 29, 26, 0 },
{ 0x1101, 30, 27, 0 },
{ 0x0AC1, 31, 28, 0 },
{ 0x09C1, 32, 29, 0 },
{ 0x08A1, 33, 30, 0 },
{ 0x0521, 34, 31, 0 },
{ 0x0441, 35, 32, 0 },
{ 0x02A1, 36, 33, 0 },
{ 0x0221, 37, 34, 0 },
{ 0x0141, 38, 35, 0 },
{ 0x0111, 39, 36, 0 },
{ 0x0085, 40, 37, 0 },
{ 0x0049, 41, 38, 0 },
{ 0x0025, 42, 39, 0 },
{ 0x0015, 43, 40, 0 },
{ 0x0009, 44, 41, 0 },
{ 0x0005, 45, 42, 0 },
{ 0x0001, 45, 43, 0 },
{ 0x5601, 46, 46, 0 }
};
extern const unsigned int JBIG2_QE_NUM = sizeof(QeTable) / sizeof(JBig2ArithQe);
CJBig2_Image *CJBig2_GRDProc::decode_Arith(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
if (GBW == 0 || GBH == 0) {
CJBig2_Image* pImage;
JBIG2_ALLOC(pImage, CJBig2_Image(GBW, GBH));
return pImage;
}
if(GBTEMPLATE == 0) {
if((GBAT[0] == 3) && (GBAT[1] == (signed char) - 1)
&& (GBAT[2] == (signed char) - 3) && (GBAT[3] == (signed char) - 1)
&& (GBAT[4] == 2) && (GBAT[5] == (signed char) - 2)
&& (GBAT[6] == (signed char) - 2) && (GBAT[7] == (signed char) - 2)) {
return decode_Arith_Template0_opt3(pArithDecoder, gbContext);
} else {
return decode_Arith_Template0_unopt(pArithDecoder, gbContext);
}
} else if(GBTEMPLATE == 1) {
if((GBAT[0] == 3) && (GBAT[1] == (signed char) - 1)) {
return decode_Arith_Template1_opt3(pArithDecoder, gbContext);
} else {
return decode_Arith_Template1_unopt(pArithDecoder, gbContext);
}
} else if(GBTEMPLATE == 2) {
if((GBAT[0] == 2) && (GBAT[1] == (signed char) - 1)) {
return decode_Arith_Template2_opt3(pArithDecoder, gbContext);
} else {
return decode_Arith_Template2_unopt(pArithDecoder, gbContext);
}
} else {
if((GBAT[0] == 2) && (GBAT[1] == (signed char) - 1)) {
return decode_Arith_Template3_opt3(pArithDecoder, gbContext);
} else {
return decode_Arith_Template3_unopt(pArithDecoder, gbContext);
}
}
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template0_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1, line2, line3;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
GBREG->fill(0);
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
line1 = GBREG->getPixel(2, h - 2);
line1 |= GBREG->getPixel(1, h - 2) << 1;
line1 |= GBREG->getPixel(0, h - 2) << 2;
line2 = GBREG->getPixel(3, h - 1);
line2 |= GBREG->getPixel(2, h - 1) << 1;
line2 |= GBREG->getPixel(1, h - 1) << 2;
line2 |= GBREG->getPixel(0, h - 1) << 3;
line3 = 0;
for(FX_DWORD w = 0; w < GBW; w++) {
if(USESKIP && SKIP->getPixel(w, h)) {
bVal = 0;
} else {
CONTEXT = line3;
CONTEXT |= line2 << 4;
CONTEXT |= line1 << 11;
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
if(bVal) {
GBREG->setPixel(w, h, bVal);
}
line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 2)) & 0x1f;
line2 = ((line2 << 1) | GBREG->getPixel(w + 4, h - 1)) & 0x7f;
line3 = ((line3 << 1) | bVal) & 0x0f;
}
}
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template0_opt2(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1, line2;
FX_BYTE *pLine, cVal;
FX_INTPTR nStride, nStride2;
FX_INT32 nBits, k;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
if (GBREG->m_pData == NULL) {
delete GBREG;
m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
return NULL;
}
pLine = GBREG->m_pData;
nStride = GBREG->m_nStride;
nStride2 = nStride << 1;
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
line1 = (h > 1) ? pLine[-nStride2] << 6 : 0;
line2 = (h > 0) ? pLine[-nStride] : 0;
CONTEXT = (line1 & 0xf800) | (line2 & 0x07f0);
for(FX_DWORD w = 0; w < GBW; w += 8) {
if(w + 8 < GBW) {
nBits = 8;
if(h > 1) {
line1 = (line1 << 8) | (pLine[-nStride2 + (w >> 3) + 1] << 6);
}
if(h > 0) {
line2 = (line2 << 8) | (pLine[-nStride + (w >> 3) + 1]);
}
} else {
nBits = GBW - w;
if(h > 1) {
line1 <<= 8;
}
if(h > 0) {
line2 <<= 8;
}
}
cVal = 0;
for(k = 0; k < nBits; k++) {
if(USESKIP && SKIP->getPixel(w, h)) {
bVal = 0;
} else {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
cVal |= bVal << (7 - k);
CONTEXT = ((CONTEXT & 0x7bf7) << 1) | bVal
| ((line1 >> (7 - k)) & 0x0800)
| ((line2 >> (7 - k)) & 0x0010);
}
pLine[w >> 3] = cVal;
}
}
pLine += nStride;
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template0_opt3(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1, line2;
FX_BYTE *pLine, *pLine1, *pLine2, cVal;
FX_INT32 nStride, nStride2, k;
FX_INT32 nLineBytes, nBitsLeft, cc;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
if (GBREG->m_pData == NULL) {
delete GBREG;
m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
return NULL;
}
pLine = GBREG->m_pData;
nStride = GBREG->m_nStride;
nStride2 = nStride << 1;
nLineBytes = ((GBW + 7) >> 3) - 1;
nBitsLeft = GBW - (nLineBytes << 3);
FX_DWORD height = GBH & 0x7fffffff;
for(FX_DWORD h = 0; h < height; h++) {
if(TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
if(h > 1) {
pLine1 = pLine - nStride2;
pLine2 = pLine - nStride;
line1 = (*pLine1++) << 6;
line2 = *pLine2++;
CONTEXT = ((line1 & 0xf800) | (line2 & 0x07f0));
for(cc = 0; cc < nLineBytes; cc++) {
line1 = (line1 << 8) | ((*pLine1++) << 6);
line2 = (line2 << 8) | (*pLine2++);
cVal = 0;
for(k = 7; k >= 0; k--) {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
cVal |= bVal << k;
CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
| ((line1 >> k) & 0x0800)
| ((line2 >> k) & 0x0010));
}
pLine[cc] = cVal;
}
line1 <<= 8;
line2 <<= 8;
cVal = 0;
for(k = 0; k < nBitsLeft; k++) {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
cVal |= bVal << (7 - k);
CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
| ((line1 >> (7 - k)) & 0x0800)
| ((line2 >> (7 - k)) & 0x0010));
}
pLine[nLineBytes] = cVal;
} else {
pLine2 = pLine - nStride;
line2 = (h & 1) ? (*pLine2++) : 0;
CONTEXT = (line2 & 0x07f0);
for(cc = 0; cc < nLineBytes; cc++) {
if(h & 1) {
line2 = (line2 << 8) | (*pLine2++);
}
cVal = 0;
for(k = 7; k >= 0; k--) {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
cVal |= bVal << k;
CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
| ((line2 >> k) & 0x0010));
}
pLine[cc] = cVal;
}
line2 <<= 8;
cVal = 0;
for(k = 0; k < nBitsLeft; k++) {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
cVal |= bVal << (7 - k);
CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
| (((line2 >> (7 - k))) & 0x0010));
}
pLine[nLineBytes] = cVal;
}
}
pLine += nStride;
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template0_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1, line2, line3;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
GBREG->fill(0);
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
line1 = GBREG->getPixel(1, h - 2);
line1 |= GBREG->getPixel(0, h - 2) << 1;
line2 = GBREG->getPixel(2, h - 1);
line2 |= GBREG->getPixel(1, h - 1) << 1;
line2 |= GBREG->getPixel(0, h - 1) << 2;
line3 = 0;
for(FX_DWORD w = 0; w < GBW; w++) {
if(USESKIP && SKIP->getPixel(w, h)) {
bVal = 0;
} else {
CONTEXT = line3;
CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
CONTEXT |= line2 << 5;
CONTEXT |= GBREG->getPixel(w + GBAT[2], h + GBAT[3]) << 10;
CONTEXT |= GBREG->getPixel(w + GBAT[4], h + GBAT[5]) << 11;
CONTEXT |= line1 << 12;
CONTEXT |= GBREG->getPixel(w + GBAT[6], h + GBAT[7]) << 15;
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
if(bVal) {
GBREG->setPixel(w, h, bVal);
}
line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
line3 = ((line3 << 1) | bVal) & 0x0f;
}
}
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template1_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1, line2, line3;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
GBREG->fill(0);
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
line1 = GBREG->getPixel(2, h - 2);
line1 |= GBREG->getPixel(1, h - 2) << 1;
line1 |= GBREG->getPixel(0, h - 2) << 2;
line2 = GBREG->getPixel(3, h - 1);
line2 |= GBREG->getPixel(2, h - 1) << 1;
line2 |= GBREG->getPixel(1, h - 1) << 2;
line2 |= GBREG->getPixel(0, h - 1) << 3;
line3 = 0;
for(FX_DWORD w = 0; w < GBW; w++) {
if(USESKIP && SKIP->getPixel(w, h)) {
bVal = 0;
} else {
CONTEXT = line3;
CONTEXT |= line2 << 3;
CONTEXT |= line1 << 9;
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
if(bVal) {
GBREG->setPixel(w, h, bVal);
}
line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 2)) & 0x0f;
line2 = ((line2 << 1) | GBREG->getPixel(w + 4, h - 1)) & 0x3f;
line3 = ((line3 << 1) | bVal) & 0x07;
}
}
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template1_opt2(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1, line2;
FX_BYTE *pLine, cVal;
FX_INTPTR nStride, nStride2;
FX_INT32 nBits, k;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
if (GBREG->m_pData == NULL) {
delete GBREG;
m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
return NULL;
}
pLine = GBREG->m_pData;
nStride = GBREG->m_nStride;
nStride2 = nStride << 1;
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
line1 = (h > 1) ? pLine[-nStride2] << 4 : 0;
line2 = (h > 0) ? pLine[-nStride] : 0;
CONTEXT = (line1 & 0x1e00) | ((line2 >> 1) & 0x01f8);
for(FX_DWORD w = 0; w < GBW; w += 8) {
if(w + 8 < GBW) {
nBits = 8;
if(h > 1) {
line1 = (line1 << 8) | (pLine[-nStride2 + (w >> 3) + 1] << 4);
}
if(h > 0) {
line2 = (line2 << 8) | (pLine[-nStride + (w >> 3) + 1]);
}
} else {
nBits = GBW - w;
if(h > 1) {
line1 <<= 8;
}
if(h > 0) {
line2 <<= 8;
}
}
cVal = 0;
for(k = 0; k < nBits; k++) {
if(USESKIP && SKIP->getPixel(w, h)) {
bVal = 0;
} else {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
cVal |= bVal << (7 - k);
CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
| ((line1 >> (7 - k)) & 0x0200)
| ((line2 >> (8 - k)) & 0x0008);
}
pLine[w >> 3] = cVal;
}
}
pLine += nStride;
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template1_opt3(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1, line2;
FX_BYTE *pLine, *pLine1, *pLine2, cVal;
FX_INT32 nStride, nStride2, k;
FX_INT32 nLineBytes, nBitsLeft, cc;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
if (GBREG->m_pData == NULL) {
delete GBREG;
m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
return NULL;
}
pLine = GBREG->m_pData;
nStride = GBREG->m_nStride;
nStride2 = nStride << 1;
nLineBytes = ((GBW + 7) >> 3) - 1;
nBitsLeft = GBW - (nLineBytes << 3);
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
if(h > 1) {
pLine1 = pLine - nStride2;
pLine2 = pLine - nStride;
line1 = (*pLine1++) << 4;
line2 = *pLine2++;
CONTEXT = (line1 & 0x1e00) | ((line2 >> 1) & 0x01f8);
for(cc = 0; cc < nLineBytes; cc++) {
line1 = (line1 << 8) | ((*pLine1++) << 4);
line2 = (line2 << 8) | (*pLine2++);
cVal = 0;
for(k = 7; k >= 0; k--) {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
cVal |= bVal << k;
CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
| ((line1 >> k) & 0x0200)
| ((line2 >> (k + 1)) & 0x0008);
}
pLine[cc] = cVal;
}
line1 <<= 8;
line2 <<= 8;
cVal = 0;
for(k = 0; k < nBitsLeft; k++) {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
cVal |= bVal << (7 - k);
CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
| ((line1 >> (7 - k)) & 0x0200)
| ((line2 >> (8 - k)) & 0x0008);
}
pLine[nLineBytes] = cVal;
} else {
pLine2 = pLine - nStride;
line2 = (h & 1) ? (*pLine2++) : 0;
CONTEXT = (line2 >> 1) & 0x01f8;
for(cc = 0; cc < nLineBytes; cc++) {
if(h & 1) {
line2 = (line2 << 8) | (*pLine2++);
}
cVal = 0;
for(k = 7; k >= 0; k--) {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
cVal |= bVal << k;
CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
| ((line2 >> (k + 1)) & 0x0008);
}
pLine[cc] = cVal;
}
line2 <<= 8;
cVal = 0;
for(k = 0; k < nBitsLeft; k++) {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
cVal |= bVal << (7 - k);
CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
| ((line2 >> (8 - k)) & 0x0008);
}
pLine[nLineBytes] = cVal;
}
}
pLine += nStride;
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template1_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1, line2, line3;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
GBREG->fill(0);
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
line1 = GBREG->getPixel(2, h - 2);
line1 |= GBREG->getPixel(1, h - 2) << 1;
line1 |= GBREG->getPixel(0, h - 2) << 2;
line2 = GBREG->getPixel(2, h - 1);
line2 |= GBREG->getPixel(1, h - 1) << 1;
line2 |= GBREG->getPixel(0, h - 1) << 2;
line3 = 0;
for(FX_DWORD w = 0; w < GBW; w++) {
if(USESKIP && SKIP->getPixel(w, h)) {
bVal = 0;
} else {
CONTEXT = line3;
CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
CONTEXT |= line2 << 4;
CONTEXT |= line1 << 9;
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
if(bVal) {
GBREG->setPixel(w, h, bVal);
}
line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 2)) & 0x0f;
line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
line3 = ((line3 << 1) | bVal) & 0x07;
}
}
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template2_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1, line2, line3;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
GBREG->fill(0);
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
line1 = GBREG->getPixel(1, h - 2);
line1 |= GBREG->getPixel(0, h - 2) << 1;
line2 = GBREG->getPixel(2, h - 1);
line2 |= GBREG->getPixel(1, h - 1) << 1;
line2 |= GBREG->getPixel(0, h - 1) << 2;
line3 = 0;
for(FX_DWORD w = 0; w < GBW; w++) {
if(USESKIP && SKIP->getPixel(w, h)) {
bVal = 0;
} else {
CONTEXT = line3;
CONTEXT |= line2 << 2;
CONTEXT |= line1 << 7;
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
if(bVal) {
GBREG->setPixel(w, h, bVal);
}
line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
line3 = ((line3 << 1) | bVal) & 0x03;
}
}
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template2_opt2(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1, line2;
FX_BYTE *pLine, cVal;
FX_INTPTR nStride, nStride2;
FX_INT32 nBits, k;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
if (GBREG->m_pData == NULL) {
delete GBREG;
m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
return NULL;
}
pLine = GBREG->m_pData;
nStride = GBREG->m_nStride;
nStride2 = nStride << 1;
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
line1 = (h > 1) ? pLine[-nStride2] << 1 : 0;
line2 = (h > 0) ? pLine[-nStride] : 0;
CONTEXT = (line1 & 0x0380) | ((line2 >> 3) & 0x007c);
for(FX_DWORD w = 0; w < GBW; w += 8) {
if(w + 8 < GBW) {
nBits = 8;
if(h > 1) {
line1 = (line1 << 8) | (pLine[-nStride2 + (w >> 3) + 1] << 1);
}
if(h > 0) {
line2 = (line2 << 8) | (pLine[-nStride + (w >> 3) + 1]);
}
} else {
nBits = GBW - w;
if(h > 1) {
line1 <<= 8;
}
if(h > 0) {
line2 <<= 8;
}
}
cVal = 0;
for(k = 0; k < nBits; k++) {
if(USESKIP && SKIP->getPixel(w, h)) {
bVal = 0;
} else {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
cVal |= bVal << (7 - k);
CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
| ((line1 >> (7 - k)) & 0x0080)
| ((line2 >> (10 - k)) & 0x0004);
}
pLine[w >> 3] = cVal;
}
}
pLine += nStride;
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template2_opt3(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1, line2;
FX_BYTE *pLine, *pLine1, *pLine2, cVal;
FX_INT32 nStride, nStride2, k;
FX_INT32 nLineBytes, nBitsLeft, cc;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
if (GBREG->m_pData == NULL) {
delete GBREG;
m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
return NULL;
}
pLine = GBREG->m_pData;
nStride = GBREG->m_nStride;
nStride2 = nStride << 1;
nLineBytes = ((GBW + 7) >> 3) - 1;
nBitsLeft = GBW - (nLineBytes << 3);
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
if(h > 1) {
pLine1 = pLine - nStride2;
pLine2 = pLine - nStride;
line1 = (*pLine1++) << 1;
line2 = *pLine2++;
CONTEXT = (line1 & 0x0380) | ((line2 >> 3) & 0x007c);
for(cc = 0; cc < nLineBytes; cc++) {
line1 = (line1 << 8) | ((*pLine1++) << 1);
line2 = (line2 << 8) | (*pLine2++);
cVal = 0;
for(k = 7; k >= 0; k--) {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
cVal |= bVal << k;
CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
| ((line1 >> k) & 0x0080)
| ((line2 >> (k + 3)) & 0x0004);
}
pLine[cc] = cVal;
}
line1 <<= 8;
line2 <<= 8;
cVal = 0;
for(k = 0; k < nBitsLeft; k++) {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
cVal |= bVal << (7 - k);
CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
| ((line1 >> (7 - k)) & 0x0080)
| ((line2 >> (10 - k)) & 0x0004);
}
pLine[nLineBytes] = cVal;
} else {
pLine2 = pLine - nStride;
line2 = (h & 1) ? (*pLine2++) : 0;
CONTEXT = (line2 >> 3) & 0x007c;
for(cc = 0; cc < nLineBytes; cc++) {
if(h & 1) {
line2 = (line2 << 8) | (*pLine2++);
}
cVal = 0;
for(k = 7; k >= 0; k--) {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
cVal |= bVal << k;
CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
| ((line2 >> (k + 3)) & 0x0004);
}
pLine[cc] = cVal;
}
line2 <<= 8;
cVal = 0;
for(k = 0; k < nBitsLeft; k++) {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
cVal |= bVal << (7 - k);
CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
| (((line2 >> (10 - k))) & 0x0004);
}
pLine[nLineBytes] = cVal;
}
}
pLine += nStride;
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template2_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1, line2, line3;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
GBREG->fill(0);
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
line1 = GBREG->getPixel(1, h - 2);
line1 |= GBREG->getPixel(0, h - 2) << 1;
line2 = GBREG->getPixel(1, h - 1);
line2 |= GBREG->getPixel(0, h - 1) << 1;
line3 = 0;
for(FX_DWORD w = 0; w < GBW; w++) {
if(USESKIP && SKIP->getPixel(w, h)) {
bVal = 0;
} else {
CONTEXT = line3;
CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 2;
CONTEXT |= line2 << 3;
CONTEXT |= line1 << 7;
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
if(bVal) {
GBREG->setPixel(w, h, bVal);
}
line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
line2 = ((line2 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x0f;
line3 = ((line3 << 1) | bVal) & 0x03;
}
}
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template3_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1, line2;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
GBREG->fill(0);
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
line1 = GBREG->getPixel(2, h - 1);
line1 |= GBREG->getPixel(1, h - 1) << 1;
line1 |= GBREG->getPixel(0, h - 1) << 2;
line2 = 0;
for(FX_DWORD w = 0; w < GBW; w++) {
if(USESKIP && SKIP->getPixel(w, h)) {
bVal = 0;
} else {
CONTEXT = line2;
CONTEXT |= line1 << 4;
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
if(bVal) {
GBREG->setPixel(w, h, bVal);
}
line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x3f;
line2 = ((line2 << 1) | bVal) & 0x0f;
}
}
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template3_opt2(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1;
FX_BYTE *pLine, cVal;
FX_INTPTR nStride, nStride2;
FX_INT32 nBits, k;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
if (GBREG->m_pData == NULL) {
delete GBREG;
m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
return NULL;
}
pLine = GBREG->m_pData;
nStride = GBREG->m_nStride;
nStride2 = nStride << 1;
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
line1 = (h > 0) ? pLine[-nStride] : 0;
CONTEXT = (line1 >> 1) & 0x03f0;
for(FX_DWORD w = 0; w < GBW; w += 8) {
if(w + 8 < GBW) {
nBits = 8;
if(h > 0) {
line1 = (line1 << 8) | (pLine[-nStride + (w >> 3) + 1]);
}
} else {
nBits = GBW - w;
if(h > 0) {
line1 <<= 8;
}
}
cVal = 0;
for(k = 0; k < nBits; k++) {
if(USESKIP && SKIP->getPixel(w, h)) {
bVal = 0;
} else {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
cVal |= bVal << (7 - k);
CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal
| ((line1 >> (8 - k)) & 0x0010);
}
pLine[w >> 3] = cVal;
}
}
pLine += nStride;
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template3_opt3(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1;
FX_BYTE *pLine, *pLine1, cVal;
FX_INT32 nStride, k;
FX_INT32 nLineBytes, nBitsLeft, cc;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
if (GBREG->m_pData == NULL) {
delete GBREG;
m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
return NULL;
}
pLine = GBREG->m_pData;
nStride = GBREG->m_nStride;
nLineBytes = ((GBW + 7) >> 3) - 1;
nBitsLeft = GBW - (nLineBytes << 3);
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
if(h > 0) {
pLine1 = pLine - nStride;
line1 = *pLine1++;
CONTEXT = (line1 >> 1) & 0x03f0;
for(cc = 0; cc < nLineBytes; cc++) {
line1 = (line1 << 8) | (*pLine1++);
cVal = 0;
for(k = 7; k >= 0; k--) {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
cVal |= bVal << k;
CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal
| ((line1 >> (k + 1)) & 0x0010);
}
pLine[cc] = cVal;
}
line1 <<= 8;
cVal = 0;
for(k = 0; k < nBitsLeft; k++) {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
cVal |= bVal << (7 - k);
CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal
| ((line1 >> (8 - k)) & 0x0010);
}
pLine[nLineBytes] = cVal;
} else {
CONTEXT = 0;
for(cc = 0; cc < nLineBytes; cc++) {
cVal = 0;
for(k = 7; k >= 0; k--) {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
cVal |= bVal << k;
CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
}
pLine[cc] = cVal;
}
cVal = 0;
for(k = 0; k < nBitsLeft; k++) {
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
cVal |= bVal << (7 - k);
CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
}
pLine[nLineBytes] = cVal;
}
}
pLine += nStride;
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template3_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1, line2;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
GBREG->fill(0);
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
line1 = GBREG->getPixel(1, h - 1);
line1 |= GBREG->getPixel(0, h - 1) << 1;
line2 = 0;
for(FX_DWORD w = 0; w < GBW; w++) {
if(USESKIP && SKIP->getPixel(w, h)) {
bVal = 0;
} else {
CONTEXT = line2;
CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
CONTEXT |= line1 << 5;
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
if(bVal) {
GBREG->setPixel(w, h, bVal);
}
line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x1f;
line2 = ((line2 << 1) | bVal) & 0x0f;
}
}
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_V2(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GBREG;
FX_DWORD line1, line2, line3;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
GBREG->fill(0);
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
switch(GBTEMPLATE) {
case 0:
CONTEXT = 0x9b25;
break;
case 1:
CONTEXT = 0x0795;
break;
case 2:
CONTEXT = 0x00e5;
break;
case 3:
CONTEXT = 0x0195;
break;
}
SLTP = pArithDecoder->DECODE(&gbContext[CONTEXT]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
GBREG->copyLine(h, h - 1);
} else {
switch(GBTEMPLATE) {
case 0: {
line1 = GBREG->getPixel(1, h - 2);
line1 |= GBREG->getPixel(0, h - 2) << 1;
line2 = GBREG->getPixel(2, h - 1);
line2 |= GBREG->getPixel(1, h - 1) << 1;
line2 |= GBREG->getPixel(0, h - 1) << 2;
line3 = 0;
for(FX_DWORD w = 0; w < GBW; w++) {
if(USESKIP && SKIP->getPixel(w, h)) {
bVal = 0;
} else {
CONTEXT = line3;
CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
CONTEXT |= line2 << 5;
CONTEXT |= GBREG->getPixel(w + GBAT[2], h + GBAT[3]) << 10;
CONTEXT |= GBREG->getPixel(w + GBAT[4], h + GBAT[5]) << 11;
CONTEXT |= line1 << 12;
CONTEXT |= GBREG->getPixel(w + GBAT[6], h + GBAT[7]) << 15;
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
if(bVal) {
GBREG->setPixel(w, h, bVal);
}
line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
line3 = ((line3 << 1) | bVal) & 0x0f;
}
}
break;
case 1: {
line1 = GBREG->getPixel(2, h - 2);
line1 |= GBREG->getPixel(1, h - 2) << 1;
line1 |= GBREG->getPixel(0, h - 2) << 2;
line2 = GBREG->getPixel(2, h - 1);
line2 |= GBREG->getPixel(1, h - 1) << 1;
line2 |= GBREG->getPixel(0, h - 1) << 2;
line3 = 0;
for(FX_DWORD w = 0; w < GBW; w++) {
if(USESKIP && SKIP->getPixel(w, h)) {
bVal = 0;
} else {
CONTEXT = line3;
CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
CONTEXT |= line2 << 4;
CONTEXT |= line1 << 9;
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
if(bVal) {
GBREG->setPixel(w, h, bVal);
}
line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 2)) & 0x0f;
line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
line3 = ((line3 << 1) | bVal) & 0x07;
}
}
break;
case 2: {
line1 = GBREG->getPixel(1, h - 2);
line1 |= GBREG->getPixel(0, h - 2) << 1;
line2 = GBREG->getPixel(1, h - 1);
line2 |= GBREG->getPixel(0, h - 1) << 1;
line3 = 0;
for(FX_DWORD w = 0; w < GBW; w++) {
if(USESKIP && SKIP->getPixel(w, h)) {
bVal = 0;
} else {
CONTEXT = line3;
CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 2;
CONTEXT |= line2 << 3;
CONTEXT |= line1 << 7;
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
if(bVal) {
GBREG->setPixel(w, h, bVal);
}
line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
line2 = ((line2 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x0f;
line3 = ((line3 << 1) | bVal) & 0x03;
}
}
break;
case 3: {
line1 = GBREG->getPixel(1, h - 1);
line1 |= GBREG->getPixel(0, h - 1) << 1;
line2 = 0;
for(FX_DWORD w = 0; w < GBW; w++) {
if(USESKIP && SKIP->getPixel(w, h)) {
bVal = 0;
} else {
CONTEXT = line2;
CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
CONTEXT |= line1 << 5;
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
if(bVal) {
GBREG->setPixel(w, h, bVal);
}
line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x1f;
line2 = ((line2 << 1) | bVal) & 0x0f;
}
}
break;
}
}
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_Arith_V1(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT = 0;
CJBig2_Image *GBREG;
LTP = 0;
JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
GBREG->fill(0);
for(FX_DWORD h = 0; h < GBH; h++) {
if(TPGDON) {
switch(GBTEMPLATE) {
case 0:
CONTEXT = 0x9b25;
break;
case 1:
CONTEXT = 0x0795;
break;
case 2:
CONTEXT = 0x00e5;
break;
case 3:
CONTEXT = 0x0195;
break;
}
SLTP = pArithDecoder->DECODE(&gbContext[CONTEXT]);
LTP = LTP ^ SLTP;
}
if(LTP == 1) {
for(FX_DWORD w = 0; w < GBW; w++) {
GBREG->setPixel(w, h, GBREG->getPixel(w, h - 1));
}
} else {
for(FX_DWORD w = 0; w < GBW; w++) {
if(USESKIP && SKIP->getPixel(w, h)) {
GBREG->setPixel(w, h, 0);
} else {
CONTEXT = 0;
switch(GBTEMPLATE) {
case 0:
CONTEXT |= GBREG->getPixel(w - 1, h);
CONTEXT |= GBREG->getPixel(w - 2, h) << 1;
CONTEXT |= GBREG->getPixel(w - 3, h) << 2;
CONTEXT |= GBREG->getPixel(w - 4, h) << 3;
CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
CONTEXT |= GBREG->getPixel(w + 2, h - 1) << 5;
CONTEXT |= GBREG->getPixel(w + 1, h - 1) << 6;
CONTEXT |= GBREG->getPixel(w, h - 1) << 7;
CONTEXT |= GBREG->getPixel(w - 1, h - 1) << 8;
CONTEXT |= GBREG->getPixel(w - 2, h - 1) << 9;
CONTEXT |= GBREG->getPixel(w + GBAT[2], h + GBAT[3]) << 10;
CONTEXT |= GBREG->getPixel(w + GBAT[4], h + GBAT[5]) << 11;
CONTEXT |= GBREG->getPixel(w + 1, h - 2) << 12;
CONTEXT |= GBREG->getPixel(w, h - 2) << 13;
CONTEXT |= GBREG->getPixel(w - 1, h - 2) << 14;
CONTEXT |= GBREG->getPixel(w + GBAT[6], h + GBAT[7]) << 15;
break;
case 1:
CONTEXT |= GBREG->getPixel(w - 1, h);
CONTEXT |= GBREG->getPixel(w - 2, h) << 1;
CONTEXT |= GBREG->getPixel(w - 3, h) << 2;
CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
CONTEXT |= GBREG->getPixel(w + 2, h - 1) << 4;
CONTEXT |= GBREG->getPixel(w + 1, h - 1) << 5;
CONTEXT |= GBREG->getPixel(w, h - 1) << 6;
CONTEXT |= GBREG->getPixel(w - 1, h - 1) << 7;
CONTEXT |= GBREG->getPixel(w - 2, h - 1) << 8;
CONTEXT |= GBREG->getPixel(w + 2, h - 2) << 9;
CONTEXT |= GBREG->getPixel(w + 1, h - 2) << 10;
CONTEXT |= GBREG->getPixel(w, h - 2) << 11;
CONTEXT |= GBREG->getPixel(w - 1, h - 2) << 12;
break;
case 2:
CONTEXT |= GBREG->getPixel(w - 1, h);
CONTEXT |= GBREG->getPixel(w - 2, h) << 1;
CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 2;
CONTEXT |= GBREG->getPixel(w + 1, h - 1) << 3;
CONTEXT |= GBREG->getPixel(w, h - 1) << 4;
CONTEXT |= GBREG->getPixel(w - 1, h - 1) << 5;
CONTEXT |= GBREG->getPixel(w - 2, h - 1) << 6;
CONTEXT |= GBREG->getPixel(w + 1, h - 2) << 7;
CONTEXT |= GBREG->getPixel(w, h - 2) << 8;
CONTEXT |= GBREG->getPixel(w - 1, h - 2) << 9;
break;
case 3:
CONTEXT |= GBREG->getPixel(w - 1, h);
CONTEXT |= GBREG->getPixel(w - 2, h) << 1;
CONTEXT |= GBREG->getPixel(w - 3, h) << 2;
CONTEXT |= GBREG->getPixel(w - 4, h) << 3;
CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
CONTEXT |= GBREG->getPixel(w + 1, h - 1) << 5;
CONTEXT |= GBREG->getPixel(w, h - 1) << 6;
CONTEXT |= GBREG->getPixel(w - 1, h - 1) << 7;
CONTEXT |= GBREG->getPixel(w - 2, h - 1) << 8;
CONTEXT |= GBREG->getPixel(w - 3, h - 1) << 9;
break;
}
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
GBREG->setPixel(w, h, bVal);
}
}
}
}
return GBREG;
}
CJBig2_Image *CJBig2_GRDProc::decode_MMR(CJBig2_BitStream *pStream)
{
int bitpos, i;
CJBig2_Image *pImage;
JBIG2_ALLOC(pImage, CJBig2_Image(GBW, GBH));
if (pImage->m_pData == NULL) {
delete pImage;
m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
return NULL;
}
bitpos = (int)pStream->getBitPos();
_FaxG4Decode(m_pModule, pStream->getBuf(), pStream->getLength(), &bitpos, pImage->m_pData, GBW, GBH, pImage->m_nStride);
pStream->setBitPos(bitpos);
for(i = 0; (FX_DWORD)i < pImage->m_nStride * GBH; i++) {
pImage->m_pData[i] = ~pImage->m_pData[i];
}
return pImage;
}
CJBig2_Image *CJBig2_GRRDProc::decode(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
{
if (GRW == 0 || GRH == 0) {
CJBig2_Image* pImage;
JBIG2_ALLOC(pImage, CJBig2_Image(GRW, GRH));
return pImage;
}
if(GRTEMPLATE == 0) {
if((GRAT[0] == (signed char) - 1) && (GRAT[1] == (signed char) - 1)
&& (GRAT[2] == (signed char) - 1) && (GRAT[3] == (signed char) - 1)
&& (GRREFERENCEDX == 0) && (GRW == (FX_DWORD)GRREFERENCE->m_nWidth)) {
return decode_Template0_opt(pArithDecoder, grContext);
} else {
return decode_Template0_unopt(pArithDecoder, grContext);
}
} else {
if((GRREFERENCEDX == 0) && (GRW == (FX_DWORD)GRREFERENCE->m_nWidth)) {
return decode_Template1_opt(pArithDecoder, grContext);
} else {
return decode_Template1_unopt(pArithDecoder, grContext);
}
}
}
CJBig2_Image *CJBig2_GRRDProc::decode_Template0_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GRREG;
FX_DWORD line1, line2, line3, line4, line5;
LTP = 0;
JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
GRREG->fill(0);
for(FX_DWORD h = 0; h < GRH; h++) {
if(TPGRON) {
SLTP = pArithDecoder->DECODE(&grContext[0x0010]);
LTP = LTP ^ SLTP;
}
if(LTP == 0) {
line1 = GRREG->getPixel(1, h - 1);
line1 |= GRREG->getPixel(0, h - 1) << 1;
line2 = 0;
line3 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY - 1);
line3 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1) << 1;
line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) << 2;
line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) << 2;
for(FX_DWORD w = 0; w < GRW; w++) {
CONTEXT = line5;
CONTEXT |= line4 << 3;
CONTEXT |= line3 << 6;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], h - GRREFERENCEDY + GRAT[3]) << 8;
CONTEXT |= line2 << 9;
CONTEXT |= line1 << 10;
CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
GRREG->setPixel(w, h, bVal);
line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x03;
line2 = ((line2 << 1) | bVal) & 0x01;
line3 = ((line3 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY - 1)) & 0x03;
line4 = ((line4 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 0x07;
line5 = ((line5 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY + 1)) & 0x07;
}
} else {
line1 = GRREG->getPixel(1, h - 1);
line1 |= GRREG->getPixel(0, h - 1) << 1;
line2 = 0;
line3 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY - 1);
line3 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1) << 1;
line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) << 2;
line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) << 2;
for(FX_DWORD w = 0; w < GRW; w++) {
bVal = GRREFERENCE->getPixel(w, h);
if(!(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1))
&& (bVal == GRREFERENCE->getPixel(w, h - 1))
&& (bVal == GRREFERENCE->getPixel(w + 1, h - 1))
&& (bVal == GRREFERENCE->getPixel(w - 1, h))
&& (bVal == GRREFERENCE->getPixel(w + 1, h))
&& (bVal == GRREFERENCE->getPixel(w - 1, h + 1))
&& (bVal == GRREFERENCE->getPixel(w, h + 1))
&& (bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) {
CONTEXT = line5;
CONTEXT |= line4 << 3;
CONTEXT |= line3 << 6;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], h - GRREFERENCEDY + GRAT[3]) << 8;
CONTEXT |= line2 << 9;
CONTEXT |= line1 << 10;
CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
}
GRREG->setPixel(w, h, bVal);
line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x03;
line2 = ((line2 << 1) | bVal) & 0x01;
line3 = ((line3 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY - 1)) & 0x03;
line4 = ((line4 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 0x07;
line5 = ((line5 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY + 1)) & 0x07;
}
}
}
return GRREG;
}
CJBig2_Image *CJBig2_GRRDProc::decode_Template0_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GRREG;
FX_DWORD line1, line1_r, line2_r, line3_r;
FX_BYTE *pLine, *pLineR, cVal;
FX_INTPTR nStride, nStrideR, nOffset;
FX_INT32 k, nBits;
FX_INT32 GRWR, GRHR;
FX_INT32 GRW, GRH;
GRW = (FX_INT32)CJBig2_GRRDProc::GRW;
GRH = (FX_INT32)CJBig2_GRRDProc::GRH;
LTP = 0;
JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
if (GRREG->m_pData == NULL) {
delete GRREG;
m_pModule->JBig2_Error("Generic refinement region decoding procedure: Create Image Failed with width = %d, height = %d\n", GRW, GRH);
return NULL;
}
pLine = GRREG->m_pData;
pLineR = GRREFERENCE->m_pData;
nStride = GRREG->m_nStride;
nStrideR = GRREFERENCE->m_nStride;
GRWR = (FX_INT32)GRREFERENCE->m_nWidth;
GRHR = (FX_INT32)GRREFERENCE->m_nHeight;
if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
GRREFERENCEDY = 0;
}
nOffset = -GRREFERENCEDY * nStrideR;
for (FX_INT32 h = 0; h < GRH; h++) {
if(TPGRON) {
SLTP = pArithDecoder->DECODE(&grContext[0x0010]);
LTP = LTP ^ SLTP;
}
line1 = (h > 0) ? pLine[-nStride] << 4 : 0;
FX_INT32 reference_h = h - GRREFERENCEDY;
FX_BOOL line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1);
FX_BOOL line2_r_ok = (reference_h > -1 && reference_h < GRHR);
FX_BOOL line3_r_ok = (reference_h > -2 && reference_h < GRHR - 1);
line1_r = line1_r_ok ? pLineR[nOffset - nStrideR] : 0;
line2_r = line2_r_ok ? pLineR[nOffset] : 0;
line3_r = line3_r_ok ? pLineR[nOffset + nStrideR] : 0;
if(LTP == 0) {
CONTEXT = (line1 & 0x1c00) | (line1_r & 0x01c0)
| ((line2_r >> 3) & 0x0038) | ((line3_r >> 6) & 0x0007);
for (FX_INT32 w = 0; w < GRW; w += 8) {
nBits = GRW - w > 8 ? 8 : GRW - w;
if (h > 0)
line1 = (line1 << 8) |
(w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 4 : 0);
if (h > GRHR + GRREFERENCEDY + 1) {
line1_r = 0;
line2_r = 0;
line3_r = 0;
} else {
if(line1_r_ok)
line1_r = (line1_r << 8) |
(w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
if(line2_r_ok)
line2_r = (line2_r << 8) |
(w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
if(line3_r_ok)
line3_r = (line3_r << 8) |
(w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
else {
line3_r = 0;
}
}
cVal = 0;
for (k = 0; k < nBits; k++) {
bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
cVal |= bVal << (7 - k);
CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) |
((line1 >> (7 - k)) & 0x0400) |
((line1_r >> (7 - k)) & 0x0040) |
((line2_r >> (10 - k)) & 0x0008) |
((line3_r >> (13 - k)) & 0x0001);
}
pLine[w >> 3] = cVal;
}
} else {
CONTEXT = (line1 & 0x1c00) | (line1_r & 0x01c0)
| ((line2_r >> 3) & 0x0038) | ((line3_r >> 6) & 0x0007);
for (FX_INT32 w = 0; w < GRW; w += 8) {
nBits = GRW - w > 8 ? 8 : GRW - w;
if (h > 0)
line1 = (line1 << 8) |
(w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 4 : 0);
if(line1_r_ok)
line1_r = (line1_r << 8) |
(w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
if(line2_r_ok)
line2_r = (line2_r << 8) |
(w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
if(line3_r_ok)
line3_r = (line3_r << 8) |
(w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
else {
line3_r = 0;
}
cVal = 0;
for (k = 0; k < nBits; k++) {
bVal = GRREFERENCE->getPixel(w + k, h);
if(!(TPGRON && (bVal == GRREFERENCE->getPixel(w + k - 1, h - 1))
&& (bVal == GRREFERENCE->getPixel(w + k, h - 1))
&& (bVal == GRREFERENCE->getPixel(w + k + 1, h - 1))
&& (bVal == GRREFERENCE->getPixel(w + k - 1, h))
&& (bVal == GRREFERENCE->getPixel(w + k + 1, h))
&& (bVal == GRREFERENCE->getPixel(w + k - 1, h + 1))
&& (bVal == GRREFERENCE->getPixel(w + k, h + 1))
&& (bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) {
bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
}
cVal |= bVal << (7 - k);
CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) |
((line1 >> (7 - k)) & 0x0400) |
((line1_r >> (7 - k)) & 0x0040) |
((line2_r >> (10 - k)) & 0x0008) |
((line3_r >> (13 - k)) & 0x0001);
}
pLine[w >> 3] = cVal;
}
}
pLine += nStride;
if (h < GRHR + GRREFERENCEDY) {
pLineR += nStrideR;
}
}
return GRREG;
}
CJBig2_Image *CJBig2_GRRDProc::decode_Template1_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GRREG;
FX_DWORD line1, line2, line3, line4, line5;
LTP = 0;
JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
GRREG->fill(0);
for(FX_DWORD h = 0; h < GRH; h++) {
if(TPGRON) {
SLTP = pArithDecoder->DECODE(&grContext[0x0008]);
LTP = LTP ^ SLTP;
}
if(LTP == 0) {
line1 = GRREG->getPixel(1, h - 1);
line1 |= GRREG->getPixel(0, h - 1) << 1;
line1 |= GRREG->getPixel(-1, h - 1) << 2;
line2 = 0;
line3 = GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1);
line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) << 2;
line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
for(FX_DWORD w = 0; w < GRW; w++) {
CONTEXT = line5;
CONTEXT |= line4 << 2;
CONTEXT |= line3 << 5;
CONTEXT |= line2 << 6;
CONTEXT |= line1 << 7;
bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
GRREG->setPixel(w, h, bVal);
line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07;
line2 = ((line2 << 1) | bVal) & 0x01;
line3 = ((line3 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY - 1)) & 0x01;
line4 = ((line4 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 0x07;
line5 = ((line5 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY + 1)) & 0x03;
}
} else {
line1 = GRREG->getPixel(1, h - 1);
line1 |= GRREG->getPixel(0, h - 1) << 1;
line1 |= GRREG->getPixel(-1, h - 1) << 2;
line2 = 0;
line3 = GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1);
line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) << 2;
line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
for(FX_DWORD w = 0; w < GRW; w++) {
bVal = GRREFERENCE->getPixel(w, h);
if(!(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1))
&& (bVal == GRREFERENCE->getPixel(w, h - 1))
&& (bVal == GRREFERENCE->getPixel(w + 1, h - 1))
&& (bVal == GRREFERENCE->getPixel(w - 1, h))
&& (bVal == GRREFERENCE->getPixel(w + 1, h))
&& (bVal == GRREFERENCE->getPixel(w - 1, h + 1))
&& (bVal == GRREFERENCE->getPixel(w, h + 1))
&& (bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) {
CONTEXT = line5;
CONTEXT |= line4 << 2;
CONTEXT |= line3 << 5;
CONTEXT |= line2 << 6;
CONTEXT |= line1 << 7;
bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
}
GRREG->setPixel(w, h, bVal);
line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07;
line2 = ((line2 << 1) | bVal) & 0x01;
line3 = ((line3 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY - 1)) & 0x01;
line4 = ((line4 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 0x07;
line5 = ((line5 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY + 1)) & 0x03;
}
}
}
return GRREG;
}
CJBig2_Image *CJBig2_GRRDProc::decode_Template1_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
CJBig2_Image *GRREG;
FX_DWORD line1, line1_r, line2_r, line3_r;
FX_BYTE *pLine, *pLineR, cVal;
FX_INTPTR nStride, nStrideR, nOffset;
FX_INT32 k, nBits;
FX_INT32 GRWR, GRHR;
FX_INT32 GRW, GRH;
GRW = (FX_INT32)CJBig2_GRRDProc::GRW;
GRH = (FX_INT32)CJBig2_GRRDProc::GRH;
LTP = 0;
JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
if (GRREG->m_pData == NULL) {
delete GRREG;
m_pModule->JBig2_Error("Generic refinement region decoding procedure: Create Image Failed with width = %d, height = %d\n", GRW, GRH);
return NULL;
}
pLine = GRREG->m_pData;
pLineR = GRREFERENCE->m_pData;
nStride = GRREG->m_nStride;
nStrideR = GRREFERENCE->m_nStride;
GRWR = (FX_INT32)GRREFERENCE->m_nWidth;
GRHR = (FX_INT32)GRREFERENCE->m_nHeight;
if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
GRREFERENCEDY = 0;
}
nOffset = -GRREFERENCEDY * nStrideR;
for (FX_INT32 h = 0; h < GRH; h++) {
if(TPGRON) {
SLTP = pArithDecoder->DECODE(&grContext[0x0008]);
LTP = LTP ^ SLTP;
}
line1 = (h > 0) ? pLine[-nStride] << 1 : 0;
FX_INT32 reference_h = h - GRREFERENCEDY;
FX_BOOL line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1);
FX_BOOL line2_r_ok = (reference_h > -1 && reference_h < GRHR);
FX_BOOL line3_r_ok = (reference_h > -2 && reference_h < GRHR - 1);
line1_r = line1_r_ok ? pLineR[nOffset - nStrideR] : 0;
line2_r = line2_r_ok ? pLineR[nOffset] : 0;
line3_r = line3_r_ok ? pLineR[nOffset + nStrideR] : 0;
if(LTP == 0) {
CONTEXT = (line1 & 0x0380) | ((line1_r >> 2) & 0x0020)
| ((line2_r >> 4) & 0x001c) | ((line3_r >> 6) & 0x0003);
for (FX_INT32 w = 0; w < GRW; w += 8) {
nBits = GRW - w > 8 ? 8 : GRW - w;
if (h > 0)
line1 = (line1 << 8) |
(w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 1 : 0);
if(line1_r_ok)
line1_r = (line1_r << 8) |
(w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
if(line2_r_ok)
line2_r = (line2_r << 8) |
(w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
if(line3_r_ok)
line3_r = (line3_r << 8) |
(w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
else {
line3_r = 0;
}
cVal = 0;
for (k = 0; k < nBits; k++) {
bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
cVal |= bVal << (7 - k);
CONTEXT = ((CONTEXT & 0x018d) << 1) | (bVal << 6) |
((line1 >> (7 - k)) & 0x0080) |
((line1_r >> (9 - k)) & 0x0020) |
((line2_r >> (11 - k)) & 0x0004) |
((line3_r >> (13 - k)) & 0x0001);
}
pLine[w >> 3] = cVal;
}
} else {
CONTEXT = (line1 & 0x0380) | ((line1_r >> 2) & 0x0020)
| ((line2_r >> 4) & 0x001c) | ((line3_r >> 6) & 0x0003);
for (FX_INT32 w = 0; w < GRW; w += 8) {
nBits = GRW - w > 8 ? 8 : GRW - w;
if (h > 0)
line1 = (line1 << 8) |
(w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 1 : 0);
if(line1_r_ok)
line1_r = (line1_r << 8) |
(w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
if(line2_r_ok)
line2_r = (line2_r << 8) |
(w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
if(line3_r_ok)
line3_r = (line3_r << 8) |
(w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
else {
line3_r = 0;
}
cVal = 0;
for (k = 0; k < nBits; k++) {
bVal = GRREFERENCE->getPixel(w + k, h);
if(!(TPGRON && (bVal == GRREFERENCE->getPixel(w + k - 1, h - 1))
&& (bVal == GRREFERENCE->getPixel(w + k, h - 1))
&& (bVal == GRREFERENCE->getPixel(w + k + 1, h - 1))
&& (bVal == GRREFERENCE->getPixel(w + k - 1, h))
&& (bVal == GRREFERENCE->getPixel(w + k + 1, h))
&& (bVal == GRREFERENCE->getPixel(w + k - 1, h + 1))
&& (bVal == GRREFERENCE->getPixel(w + k, h + 1))
&& (bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) {
bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
}
cVal |= bVal << (7 - k);
CONTEXT = ((CONTEXT & 0x018d) << 1) | (bVal << 6) |
((line1 >> (7 - k)) & 0x0080) |
((line1_r >> (9 - k)) & 0x0020) |
((line2_r >> (11 - k)) & 0x0004) |
((line3_r >> (13 - k)) & 0x0001);
}
pLine[w >> 3] = cVal;
}
}
pLine += nStride;
if (h < GRHR + GRREFERENCEDY) {
pLineR += nStrideR;
}
}
return GRREG;
}
CJBig2_Image *CJBig2_GRRDProc::decode_V1(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
{
FX_BOOL LTP, SLTP, bVal;
FX_BOOL TPGRPIX, TPGRVAL;
FX_DWORD CONTEXT;
CJBig2_Image *GRREG;
LTP = 0;
JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
GRREG->fill(0);
for(FX_DWORD h = 0; h < GRH; h++) {
if(TPGRON) {
switch(GRTEMPLATE) {
case 0:
CONTEXT = 0x0010;
break;
case 1:
CONTEXT = 0x0008;
break;
}
SLTP = pArithDecoder->DECODE(&grContext[CONTEXT]);
LTP = LTP ^ SLTP;
}
if(LTP == 0) {
for(FX_DWORD w = 0; w < GRW; w++) {
CONTEXT = 0;
switch(GRTEMPLATE) {
case 0:
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) << 2;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY) << 3;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY) << 4;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY) << 5;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY - 1) << 6;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY - 1) << 7;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], h - GRREFERENCEDY + GRAT[3]) << 8;
CONTEXT |= GRREG->getPixel(w - 1, h) << 9;
CONTEXT |= GRREG->getPixel(w + 1, h - 1) << 10;
CONTEXT |= GRREG->getPixel(w, h - 1) << 11;
CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
break;
case 1:
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY) << 2;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY) << 3;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY) << 4;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY - 1) << 5;
CONTEXT |= GRREG->getPixel(w - 1, h) << 6;
CONTEXT |= GRREG->getPixel(w + 1, h - 1) << 7;
CONTEXT |= GRREG->getPixel(w, h - 1) << 8;
CONTEXT |= GRREG->getPixel(w - 1, h - 1) << 9;
break;
}
bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
GRREG->setPixel(w, h, bVal);
}
} else {
for(FX_DWORD w = 0; w < GRW; w++) {
bVal = GRREFERENCE->getPixel(w, h);
if(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1))
&& (bVal == GRREFERENCE->getPixel(w, h - 1))
&& (bVal == GRREFERENCE->getPixel(w + 1, h - 1))
&& (bVal == GRREFERENCE->getPixel(w - 1, h))
&& (bVal == GRREFERENCE->getPixel(w + 1, h))
&& (bVal == GRREFERENCE->getPixel(w - 1, h + 1))
&& (bVal == GRREFERENCE->getPixel(w, h + 1))
&& (bVal == GRREFERENCE->getPixel(w + 1, h + 1))) {
TPGRPIX = 1;
TPGRVAL = bVal;
} else {
TPGRPIX = 0;
}
if(TPGRPIX) {
GRREG->setPixel(w, h, TPGRVAL);
} else {
CONTEXT = 0;
switch(GRTEMPLATE) {
case 0:
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) << 2;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY) << 3;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY) << 4;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY) << 5;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY - 1) << 6;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY - 1) << 7;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], h - GRREFERENCEDY + GRAT[3]) << 8;
CONTEXT |= GRREG->getPixel(w - 1, h) << 9;
CONTEXT |= GRREG->getPixel(w + 1, h - 1) << 10;
CONTEXT |= GRREG->getPixel(w, h - 1) << 11;
CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
break;
case 1:
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY) << 2;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY) << 3;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY) << 4;
CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY - 1) << 5;
CONTEXT |= GRREG->getPixel(w - 1, h) << 6;
CONTEXT |= GRREG->getPixel(w + 1, h - 1) << 7;
CONTEXT |= GRREG->getPixel(w, h - 1) << 8;
CONTEXT |= GRREG->getPixel(w - 1, h - 1) << 9;
break;
}
bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
GRREG->setPixel(w, h, bVal);
}
}
}
}
return GRREG;
}
CJBig2_Image *CJBig2_TRDProc::decode_Huffman(CJBig2_BitStream *pStream, JBig2ArithCtx *grContext)
{
FX_INT32 STRIPT, FIRSTS;
FX_DWORD NINSTANCES;
FX_INT32 DT, DFS, CURS;
FX_BYTE CURT;
FX_INT32 SI, TI;
FX_DWORD IDI;
CJBig2_Image *IBI;
FX_DWORD WI, HI;
FX_INT32 IDS;
FX_BOOL RI;
FX_INT32 RDWI, RDHI, RDXI, RDYI;
CJBig2_Image *IBOI;
FX_DWORD WOI, HOI;
CJBig2_Image *SBREG;
FX_BOOL bFirst;
FX_DWORD nTmp;
FX_INT32 nVal, nBits;
CJBig2_HuffmanDecoder *pHuffmanDecoder;
CJBig2_GRRDProc *pGRRD;
CJBig2_ArithDecoder *pArithDecoder;
JBIG2_ALLOC(pHuffmanDecoder, CJBig2_HuffmanDecoder(pStream));
JBIG2_ALLOC(SBREG, CJBig2_Image(SBW, SBH));
SBREG->fill(SBDEFPIXEL);
if(pHuffmanDecoder->decodeAValue(SBHUFFDT, &STRIPT) != 0) {
m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
goto failed;
}
STRIPT *= SBSTRIPS;
STRIPT = -STRIPT;
FIRSTS = 0;
NINSTANCES = 0;
while(NINSTANCES < SBNUMINSTANCES) {
if(pHuffmanDecoder->decodeAValue(SBHUFFDT, &DT) != 0) {
m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
goto failed;
}
DT *= SBSTRIPS;
STRIPT = STRIPT + DT;
bFirst = TRUE;
for(;;) {
if(bFirst) {
if(pHuffmanDecoder->decodeAValue(SBHUFFFS, &DFS) != 0) {
m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
goto failed;
}
FIRSTS = FIRSTS + DFS;
CURS = FIRSTS;
bFirst = FALSE;
} else {
nVal = pHuffmanDecoder->decodeAValue(SBHUFFDS, &IDS);
if(nVal == JBIG2_OOB) {
break;
} else if(nVal != 0) {
m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
goto failed;
} else {
CURS = CURS + IDS + SBDSOFFSET;
}
}
if(SBSTRIPS == 1) {
CURT = 0;
} else {
nTmp = 1;
while((FX_DWORD)(1 << nTmp) < SBSTRIPS) {
nTmp ++;
}
if(pStream->readNBits(nTmp, &nVal) != 0) {
m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
goto failed;
}
CURT = nVal;
}
TI = STRIPT + CURT;
nVal = 0;
nBits = 0;
for(;;) {
if(pStream->read1Bit(&nTmp) != 0) {
m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
goto failed;
}
nVal = (nVal << 1) | nTmp;
nBits ++;
for(IDI = 0; IDI < SBNUMSYMS; IDI++) {
if((nBits == SBSYMCODES[IDI].codelen) && (nVal == SBSYMCODES[IDI].code)) {
break;
}
}
if(IDI < SBNUMSYMS) {
break;
}
}
if(SBREFINE == 0) {
RI = 0;
} else {
if(pStream->read1Bit(&RI) != 0) {
m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
goto failed;
}
}
if(RI == 0) {
IBI = SBSYMS[IDI];
} else {
if((pHuffmanDecoder->decodeAValue(SBHUFFRDW, &RDWI) != 0)
|| (pHuffmanDecoder->decodeAValue(SBHUFFRDH, &RDHI) != 0)
|| (pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDXI) != 0)
||<