blob: 1c56db984b31d9ac30eb29b82ad1dc1ac37b65ef [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 = FX_ArraySize(QeTable);
CJBig2_Image* CJBig2_GRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext) {
if (GBW == 0 || GBH == 0) {
return new CJBig2_Image(GBW, GBH);
}
if (GBTEMPLATE == 0) {
if ((GBAT[0] == 3) && (GBAT[1] == (int8_t)-1) && (GBAT[2] == (int8_t)-3) &&
(GBAT[3] == (int8_t)-1) && (GBAT[4] == 2) && (GBAT[5] == (int8_t)-2) &&
(GBAT[6] == (int8_t)-2) && (GBAT[7] == (int8_t)-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] == (int8_t)-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] == (int8_t)-1)) {
return decode_Arith_Template2_opt3(pArithDecoder, gbContext);
} else {
return decode_Arith_Template2_unopt(pArithDecoder, gbContext);
}
} else {
if ((GBAT[0] == 2) && (GBAT[1] == (int8_t)-1)) {
return decode_Arith_Template3_opt3(pArithDecoder, gbContext);
} else {
return decode_Arith_Template3_unopt(pArithDecoder, gbContext);
}
}
}
CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_opt3(
CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext) {
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
FX_DWORD line1, line2;
uint8_t *pLine, *pLine1, *pLine2, cVal;
int32_t nStride, nStride2, k;
int32_t nLineBytes, nBitsLeft, cc;
LTP = 0;
CJBig2_Image* GBREG = new CJBig2_Image(GBW, GBH);
if (GBREG->m_pData == NULL) {
delete GBREG;
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;
FX_DWORD line1, line2, line3;
LTP = 0;
CJBig2_Image* GBREG = new 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_opt3(
CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext) {
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
FX_DWORD line1, line2;
uint8_t *pLine, *pLine1, *pLine2, cVal;
int32_t nStride, nStride2, k;
int32_t nLineBytes, nBitsLeft, cc;
LTP = 0;
CJBig2_Image* GBREG = new CJBig2_Image(GBW, GBH);
if (GBREG->m_pData == NULL) {
delete GBREG;
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;
FX_DWORD line1, line2, line3;
LTP = 0;
CJBig2_Image* GBREG = new 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_opt3(
CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext) {
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
FX_DWORD line1, line2;
uint8_t *pLine, *pLine1, *pLine2, cVal;
int32_t nStride, nStride2, k;
int32_t nLineBytes, nBitsLeft, cc;
LTP = 0;
CJBig2_Image* GBREG = new CJBig2_Image(GBW, GBH);
if (GBREG->m_pData == NULL) {
delete GBREG;
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;
FX_DWORD line1, line2, line3;
LTP = 0;
CJBig2_Image* GBREG = new 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_opt3(
CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext) {
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
FX_DWORD line1;
uint8_t *pLine, *pLine1, cVal;
int32_t nStride, k;
int32_t nLineBytes, nBitsLeft, cc;
LTP = 0;
CJBig2_Image* GBREG = new CJBig2_Image(GBW, GBH);
if (GBREG->m_pData == NULL) {
delete GBREG;
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;
FX_DWORD line1, line2;
LTP = 0;
CJBig2_Image* GBREG = new 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_GRRDProc::decode(CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* grContext) {
if (GRW == 0 || GRH == 0) {
return new CJBig2_Image(GRW, GRH);
}
if (GRTEMPLATE == 0) {
if ((GRAT[0] == (int8_t)-1) && (GRAT[1] == (int8_t)-1) &&
(GRAT[2] == (int8_t)-1) && (GRAT[3] == (int8_t)-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;
FX_DWORD line1, line2, line3, line4, line5;
LTP = 0;
CJBig2_Image* GRREG = new 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) {
if (!GRREFERENCE->m_pData)
return nullptr;
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
FX_DWORD line1, line1_r, line2_r, line3_r;
uint8_t *pLine, *pLineR, cVal;
intptr_t nStride, nStrideR, nOffset;
int32_t k, nBits;
int32_t GRWR, GRHR;
int32_t GRW, GRH;
GRW = (int32_t)CJBig2_GRRDProc::GRW;
GRH = (int32_t)CJBig2_GRRDProc::GRH;
LTP = 0;
CJBig2_Image* GRREG = new CJBig2_Image(GRW, GRH);
if (GRREG->m_pData == NULL) {
delete GRREG;
return NULL;
}
pLine = GRREG->m_pData;
pLineR = GRREFERENCE->m_pData;
nStride = GRREG->m_nStride;
nStrideR = GRREFERENCE->m_nStride;
GRWR = (int32_t)GRREFERENCE->m_nWidth;
GRHR = (int32_t)GRREFERENCE->m_nHeight;
if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
GRREFERENCEDY = 0;
}
nOffset = -GRREFERENCEDY * nStrideR;
for (int32_t h = 0; h < GRH; h++) {
if (TPGRON) {
SLTP = pArithDecoder->DECODE(&grContext[0x0010]);
LTP = LTP ^ SLTP;
}
line1 = (h > 0) ? pLine[-nStride] << 4 : 0;
int32_t 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 (int32_t 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 (int32_t 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;
FX_DWORD line1, line2, line3, line4, line5;
LTP = 0;
CJBig2_Image* GRREG = new 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) {
if (!GRREFERENCE->m_pData)
return nullptr;
FX_BOOL LTP, SLTP, bVal;
FX_DWORD CONTEXT;
FX_DWORD line1, line1_r, line2_r, line3_r;
uint8_t *pLine, *pLineR, cVal;
intptr_t nStride, nStrideR, nOffset;
int32_t k, nBits;
int32_t GRWR, GRHR;
int32_t GRW, GRH;
GRW = (int32_t)CJBig2_GRRDProc::GRW;
GRH = (int32_t)CJBig2_GRRDProc::GRH;
LTP = 0;
CJBig2_Image* GRREG = new CJBig2_Image(GRW, GRH);
if (GRREG->m_pData == NULL) {
delete GRREG;
return NULL;
}
pLine = GRREG->m_pData;
pLineR = GRREFERENCE->m_pData;
nStride = GRREG->m_nStride;
nStrideR = GRREFERENCE->m_nStride;
GRWR = (int32_t)GRREFERENCE->m_nWidth;
GRHR = (int32_t)GRREFERENCE->m_nHeight;
if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
GRREFERENCEDY = 0;
}
nOffset = -GRREFERENCEDY * nStrideR;
for (int32_t h = 0; h < GRH; h++) {
if (TPGRON) {
SLTP = pArithDecoder->DECODE(&grContext[0x0008]);
LTP = LTP ^ SLTP;
}
line1 = (h > 0) ? pLine[-nStride] << 1 : 0;
int32_t 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 (int32_t 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 (int32_t 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_TRDProc::decode_Huffman(CJBig2_BitStream* pStream,
JBig2ArithCtx* grContext) {
int32_t STRIPT, FIRSTS;
FX_DWORD NINSTANCES;
int32_t DT, DFS, CURS;
uint8_t CURT;
int32_t SI, TI;
FX_DWORD IDI;
CJBig2_Image* IBI;
FX_DWORD WI, HI;
int32_t IDS;
FX_BOOL RI;
int32_t RDWI, RDHI, RDXI, RDYI;
CJBig2_Image* IBOI;
FX_DWORD WOI, HOI;
FX_BOOL bFirst;
FX_DWORD nTmp;
int32_t nVal, nBits;
CJBig2_GRRDProc* pGRRD;
CJBig2_ArithDecoder* pArithDecoder;
CJBig2_HuffmanDecoder* pHuffmanDecoder = new CJBig2_HuffmanDecoder(pStream);
CJBig2_Image* SBREG = new CJBig2_Image(SBW, SBH);
SBREG->fill(SBDEFPIXEL);
if (pHuffmanDecoder->decodeAValue(SBHUFFDT, &STRIPT) != 0) {
goto failed;
}
STRIPT *= SBSTRIPS;
STRIPT = -STRIPT;
FIRSTS = 0;
NINSTANCES = 0;
while (NINSTANCES < SBNUMINSTANCES) {
if (pHuffmanDecoder->decodeAValue(SBHUFFDT, &DT) != 0) {
goto failed;
}
DT *= SBSTRIPS;
STRIPT = STRIPT + DT;
bFirst = TRUE;
for (;;) {
if (bFirst) {
if (pHuffmanDecoder->decodeAValue(SBHUFFFS, &DFS) != 0) {
goto failed;
}
FIRSTS = FIRSTS + DFS;
CURS = FIRSTS;
bFirst = FALSE;
} else {
nVal = pHuffmanDecoder->decodeAValue(SBHUFFDS, &IDS);
if (nVal == JBIG2_OOB) {
break;
} else if (nVal != 0) {
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) {
goto failed;
}
CURT = nVal;
}
TI = STRIPT + CURT;
nVal = 0;
nBits = 0;
for (;;) {
if (pStream->read1Bit(&nTmp) != 0) {
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) {
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) ||
(pHuffmanDecoder->decodeAValue(SBHUFFRDY, &RDYI) != 0) ||
(pHuffmanDecoder->decodeAValue(SBHUFFRSIZE, &nVal) != 0)) {
goto failed;
}
pStream->alignByte();
nTmp = pStream->getOffset();
IBOI = SBSYMS[IDI];
if (!IBOI) {
goto failed;
}
WOI = IBOI->m_nWidth;
HOI = IBOI->m_nHeight;
if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) {
goto failed;
}
pGRRD = new CJBig2_GRRDProc();
pGRRD->GRW = WOI + RDWI;
pGRRD->GRH = HOI + RDHI;
pGRRD->GRTEMPLATE = SBRTEMPLATE;
pGRRD->GRREFERENCE = IBOI;
pGRRD->GRREFERENCEDX = (RDWI >> 2) + RDXI;
pGRRD->GRREFERENCEDY = (RDHI >> 2) + RDYI;
pGRRD->TPGRON = 0;
pGRRD->GRAT[0] = SBRAT[0];
pGRRD->GRAT[1] = SBRAT[1];
pGRRD->GRAT[2] = SBRAT[2];
pGRRD->GRAT[3] = SBRAT[3];
pArithDecoder = new CJBig2_ArithDecoder(pStream);
IBI = pGRRD->decode(pArithDecoder, grContext);
if (IBI == NULL) {
delete pGRRD;
delete pArithDecoder;
goto failed;
}
delete pArithDecoder;
pStream->alignByte();
pStream->offset(2);
if ((FX_DWORD)nVal != (pStream->getOffset() - nTmp)) {
delete IBI;
delete pGRRD;
goto failed;
}
delete pGRRD;
}
if (!IBI) {
continue;
}
WI = IBI->m_nWidth;
HI = IBI->m_nHeight;
if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) ||
(REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
CURS = CURS + WI - 1;
} else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT) ||
(REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
CURS = CURS + HI - 1;
}
SI = CURS;
if (TRANSPOSED == 0) {
switch (REFCORNER) {
case JBIG2_CORNER_TOPLEFT:
SBREG->composeFrom(SI, TI, IBI, SBCOMBOP);
break;
case JBIG2_CORNER_TOPRIGHT:
SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP);
break;
case JBIG2_CORNER_BOTTOMLEFT:
SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP);
break;
case JBIG2_CORNER_BOTTOMRIGHT:
SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP);
break;
}
} else {
switch (REFCORNER) {
case JBIG2_CORNER_TOPLEFT:
SBREG->composeFrom(TI, SI, IBI, SBCOMBOP);
break;
case JBIG2_CORNER_TOPRIGHT:
SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP);
break;
case JBIG2_CORNER_BOTTOMLEFT:
SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP);
break;
case JBIG2_CORNER_BOTTOMRIGHT:
SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP);
break;
}
}
if (RI != 0) {
delete IBI;
}
if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
(REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) {
CURS = CURS + WI - 1;
} else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
(REFCORNER == JBIG2_CORNER_TOPRIGHT))) {
CURS = CURS + HI - 1;
}
NINSTANCES = NINSTANCES + 1;
}
}
delete pHuffmanDecoder;
return SBREG;
failed:
delete pHuffmanDecoder;
delete SBREG;
return NULL;
}
CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* grContext,
JBig2IntDecoderState* pIDS) {
int32_t STRIPT, FIRSTS;
FX_DWORD NINSTANCES;
int32_t DT, DFS, CURS;
int32_t CURT;
int32_t SI, TI;
FX_DWORD IDI;
CJBig2_Image* IBI;
FX_DWORD WI, HI;
int32_t IDS;
int RI;
int32_t RDWI, RDHI, RDXI, RDYI;
CJBig2_Image* IBOI;
FX_DWORD WOI, HOI;
CJBig2_Image* SBREG;
FX_BOOL bFirst;
int32_t nRet, nVal;
int32_t bRetained;
CJBig2_ArithIntDecoder *IADT, *IAFS, *IADS, *IAIT, *IARI, *IARDW, *IARDH,
*IARDX, *IARDY;
CJBig2_ArithIaidDecoder* IAID;
CJBig2_GRRDProc* pGRRD;
if (pIDS) {
IADT = pIDS->IADT;
IAFS = pIDS->IAFS;
IADS = pIDS->IADS;
IAIT = pIDS->IAIT;
IARI = pIDS->IARI;
IARDW = pIDS->IARDW;
IARDH = pIDS->IARDH;
IARDX = pIDS->IARDX;
IARDY = pIDS->IARDY;
IAID = pIDS->IAID;
bRetained = TRUE;
} else {
IADT = new CJBig2_ArithIntDecoder();
IAFS = new CJBig2_ArithIntDecoder();
IADS = new CJBig2_ArithIntDecoder();
IAIT = new CJBig2_ArithIntDecoder();
IARI = new CJBig2_ArithIntDecoder();
IARDW = new CJBig2_ArithIntDecoder();
IARDH = new CJBig2_ArithIntDecoder();
IARDX = new CJBig2_ArithIntDecoder();
IARDY = new CJBig2_ArithIntDecoder();
IAID = new CJBig2_ArithIaidDecoder(SBSYMCODELEN);
bRetained = FALSE;
}
SBREG = new CJBig2_Image(SBW, SBH);
SBREG->fill(SBDEFPIXEL);
if (IADT->decode(pArithDecoder, &STRIPT) == -1) {
goto failed;
}
STRIPT *= SBSTRIPS;
STRIPT = -STRIPT;
FIRSTS = 0;
NINSTANCES = 0;
while (NINSTANCES < SBNUMINSTANCES) {
if (IADT->decode(pArithDecoder, &DT) == -1) {
goto failed;
}
DT *= SBSTRIPS;
STRIPT = STRIPT + DT;
bFirst = TRUE;
for (;;) {
if (bFirst) {
if (IAFS->decode(pArithDecoder, &DFS) == -1) {
goto failed;
}
FIRSTS = FIRSTS + DFS;
CURS = FIRSTS;
bFirst = FALSE;
} else {
nRet = IADS->decode(pArithDecoder, &IDS);
if (nRet == JBIG2_OOB) {
break;
} else if (nRet != 0) {
goto failed;
} else {
CURS = CURS + IDS + SBDSOFFSET;
}
}
if (NINSTANCES >= SBNUMINSTANCES) {
break;
}
if (SBSTRIPS == 1) {
CURT = 0;
} else {
if (IAIT->decode(pArithDecoder, &nVal) == -1) {
goto failed;
}
CURT = nVal;
}
TI = STRIPT + CURT;
if (IAID->decode(pArithDecoder, &nVal) == -1) {
goto failed;
}
IDI = nVal;
if (IDI >= SBNUMSYMS) {
goto failed;
}
if (SBREFINE == 0) {
RI = 0;
} else {
if (IARI->decode(pArithDecoder, &RI) == -1) {
goto failed;
}
}
if (!SBSYMS[IDI]) {
goto failed;
}
if (RI == 0) {
IBI = SBSYMS[IDI];
} else {
if ((IARDW->decode(pArithDecoder, &RDWI) == -1) ||
(IARDH->decode(pArithDecoder, &RDHI) == -1) ||
(IARDX->decode(pArithDecoder, &RDXI) == -1) ||
(IARDY->decode(pArithDecoder, &RDYI) == -1)) {
goto failed;
}
IBOI = SBSYMS[IDI];
WOI = IBOI->m_nWidth;
HOI = IBOI->m_nHeight;
if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) {
goto failed;
}
pGRRD = new CJBig2_GRRDProc();
pGRRD->GRW = WOI + RDWI;
pGRRD->GRH = HOI + RDHI;
pGRRD->GRTEMPLATE = SBRTEMPLATE;
pGRRD->GRREFERENCE = IBOI;
pGRRD->GRREFERENCEDX = (RDWI >> 1) + RDXI;
pGRRD->GRREFERENCEDY = (RDHI >> 1) + RDYI;
pGRRD->TPGRON = 0;
pGRRD->GRAT[0] = SBRAT[0];
pGRRD->GRAT[1] = SBRAT[1];
pGRRD->GRAT[2] = SBRAT[2];
pGRRD->GRAT[3] = SBRAT[3];
IBI = pGRRD->decode(pArithDecoder, grContext);
if (IBI == NULL) {
delete pGRRD;
goto failed;
}
delete pGRRD;
}
WI = IBI->m_nWidth;
HI = IBI->m_nHeight;
if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) ||
(REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
CURS = CURS + WI - 1;
} else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT) ||
(REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
CURS = CURS + HI - 1;
}
SI = CURS;
if (TRANSPOSED == 0) {
switch (REFCORNER) {
case JBIG2_CORNER_TOPLEFT:
SBREG->composeFrom(SI, TI, IBI, SBCOMBOP);
break;
case JBIG2_CORNER_TOPRIGHT:
SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP);
break;
case JBIG2_CORNER_BOTTOMLEFT:
SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP);
break;
case JBIG2_CORNER_BOTTOMRIGHT:
SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP);
break;
}
} else {
switch (REFCORNER) {
case JBIG2_CORNER_TOPLEFT:
SBREG->composeFrom(TI, SI, IBI, SBCOMBOP);
break;
case JBIG2_CORNER_TOPRIGHT:
SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP);
break;
case JBIG2_CORNER_BOTTOMLEFT:
SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP);
break;
case JBIG2_CORNER_BOTTOMRIGHT:
SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP);
break;
}
}
if (RI != 0) {
delete IBI;
}
if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
(REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) {
CURS = CURS + WI - 1;
} else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
(REFCORNER == JBIG2_CORNER_TOPRIGHT))) {
CURS = CURS + HI - 1;
}
NINSTANCES = NINSTANCES + 1;
}
}
if (bRetained == FALSE) {
delete IADT;
delete IAFS;
delete IADS;
delete IAIT;
delete IARI;
delete IARDW;
delete IARDH;
delete IARDX;
delete IARDY;
delete IAID;
}
return SBREG;
failed:
if (bRetained == FALSE) {
delete IADT;
delete IAFS;
delete IADS;
delete IAIT;
delete IARI;
delete IARDW;
delete IARDH;
delete IARDX;
delete IARDY;
delete IAID;
}
delete SBREG;
return NULL;
}
CJBig2_SymbolDict* CJBig2_SDDProc::decode_Arith(
CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext,
JBig2ArithCtx* grContext) {
CJBig2_Image** SDNEWSYMS;
FX_DWORD HCHEIGHT, NSYMSDECODED;
int32_t HCDH;
FX_DWORD SYMWIDTH, TOTWIDTH;
int32_t DW;
CJBig2_Image* BS;
FX_DWORD I, J, REFAGGNINST;
FX_BOOL* EXFLAGS;
FX_DWORD EXINDEX;
FX_BOOL CUREXFLAG;
FX_DWORD EXRUNLENGTH;
int32_t nVal;
FX_DWORD nTmp;
FX_DWORD SBNUMSYMS;
uint8_t SBSYMCODELEN;
FX_DWORD IDI;
int32_t RDXI, RDYI;
CJBig2_Image** SBSYMS;
CJBig2_HuffmanTable *SBHUFFFS, *SBHUFFDS, *SBHUFFDT, *SBHUFFRDW, *SBHUFFRDH,
*SBHUFFRDX, *SBHUFFRDY, *SBHUFFRSIZE;
CJBig2_GRRDProc* pGRRD;
CJBig2_GRDProc* pGRD;
CJBig2_ArithIntDecoder *IADH, *IADW, *IAAI, *IARDX, *IARDY, *IAEX, *IADT,
*IAFS, *IADS, *IAIT, *IARI, *IARDW, *IARDH;
CJBig2_ArithIaidDecoder* IAID;
CJBig2_SymbolDict* pDict;
IADH = new CJBig2_ArithIntDecoder();
IADW = new CJBig2_ArithIntDecoder();
IAAI = new CJBig2_ArithIntDecoder();
IARDX = new CJBig2_ArithIntDecoder();
IARDY = new CJBig2_ArithIntDecoder();
IAEX = new CJBig2_ArithIntDecoder();
IADT = new CJBig2_ArithIntDecoder();
IAFS = new CJBig2_ArithIntDecoder();
IADS = new CJBig2_ArithIntDecoder();
IAIT = new CJBig2_ArithIntDecoder();
IARI = new CJBig2_ArithIntDecoder();
IARDW = new CJBig2_ArithIntDecoder();
IARDH = new CJBig2_ArithIntDecoder();
nTmp = 0;
while ((FX_DWORD)(1 << nTmp) < (SDNUMINSYMS + SDNUMNEWSYMS)) {
nTmp++;
}
IAID = new CJBig2_ArithIaidDecoder((uint8_t)nTmp);
SDNEWSYMS = FX_Alloc(CJBig2_Image*, SDNUMNEWSYMS);
FXSYS_memset(SDNEWSYMS, 0, SDNUMNEWSYMS * sizeof(CJBig2_Image*));
HCHEIGHT = 0;
NSYMSDECODED = 0;
while (NSYMSDECODED < SDNUMNEWSYMS) {
BS = NULL;
if (IADH->decode(pArithDecoder, &HCDH) == -1) {
goto failed;
}
HCHEIGHT = HCHEIGHT + HCDH;
if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > JBIG2_MAX_IMAGE_SIZE) {
goto failed;
}
SYMWIDTH = 0;
TOTWIDTH = 0;
for (;;) {
nVal = IADW->decode(pArithDecoder, &DW);
if (nVal == JBIG2_OOB) {
break;
} else if (nVal != 0) {
goto failed;
} else {
if (NSYMSDECODED >= SDNUMNEWSYMS) {
goto failed;
}
SYMWIDTH = SYMWIDTH + DW;
if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > JBIG2_MAX_IMAGE_SIZE) {
goto failed;
} else if (HCHEIGHT == 0 || SYMWIDTH == 0) {
TOTWIDTH = TOTWIDTH + SYMWIDTH;
SDNEWSYMS[NSYMSDECODED] = NULL;
NSYMSDECODED = NSYMSDECODED + 1;
continue;
}
TOTWIDTH = TOTWIDTH + SYMWIDTH;
}
if (SDREFAGG == 0) {
pGRD = new CJBig2_GRDProc();
pGRD->MMR = 0;
pGRD->GBW = SYMWIDTH;
pGRD->GBH = HCHEIGHT;
pGRD->GBTEMPLATE = SDTEMPLATE;
pGRD->TPGDON = 0;
pGRD->USESKIP = 0;
pGRD->GBAT[0] = SDAT[0];
pGRD->GBAT[1] = SDAT[1];
pGRD->GBAT[2] = SDAT[2];
pGRD->GBAT[3] = SDAT[3];
pGRD->GBAT[4] = SDAT[4];
pGRD->GBAT[5] = SDAT[5];
pGRD->GBAT[6] = SDAT[6];
pGRD->GBAT[7] = SDAT[7];
BS = pGRD->decode_Arith(pArithDecoder, gbContext);
if (BS == NULL) {
delete pGRD;
goto failed;
}
delete pGRD;
} else {
if (IAAI->decode(pArithDecoder, (int*)&REFAGGNINST) == -1) {
goto failed;
}
if (REFAGGNINST > 1) {
CJBig2_TRDProc* pDecoder;
pDecoder = new CJBig2_TRDProc();
pDecoder->SBHUFF = SDHUFF;
pDecoder->SBREFINE = 1;
pDecoder->SBW = SYMWIDTH;
pDecoder->SBH = HCHEIGHT;
pDecoder->SBNUMINSTANCES = REFAGGNINST;
pDecoder->SBSTRIPS = 1;
pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
SBNUMSYMS = pDecoder->SBNUMSYMS;
nTmp = 0;
while ((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
nTmp++;
}
SBSYMCODELEN = (uint8_t)nTmp;
pDecoder->SBSYMCODELEN = SBSYMCODELEN;
SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS);
JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS,
NSYMSDECODED * sizeof(CJBig2_Image*));
pDecoder->SBSYMS = SBSYMS;
pDecoder->SBDEFPIXEL = 0;
pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR;
pDecoder->TRANSPOSED = 0;
pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT;
pDecoder->SBDSOFFSET = 0;
SBHUFFFS = new CJBig2_HuffmanTable(HuffmanTable_B6,
FX_ArraySize(HuffmanTable_B6),
HuffmanTable_HTOOB_B6);
SBHUFFDS = new CJBig2_HuffmanTable(HuffmanTable_B8,
FX_ArraySize(HuffmanTable_B8),
HuffmanTable_HTOOB_B8);
SBHUFFDT = new CJBig2_HuffmanTable(HuffmanTable_B11,
FX_ArraySize(HuffmanTable_B11),
HuffmanTable_HTOOB_B11);
SBHUFFRDW = new CJBig2_HuffmanTable(HuffmanTable_B15,
FX_ArraySize(HuffmanTable_B15),
HuffmanTable_HTOOB_B15);
SBHUFFRDH = new CJBig2_HuffmanTable(HuffmanTable_B15,
FX_ArraySize(HuffmanTable_B15),
HuffmanTable_HTOOB_B15);
SBHUFFRDX = new CJBig2_HuffmanTable(HuffmanTable_B15,
FX_ArraySize(HuffmanTable_B15),
HuffmanTable_HTOOB_B15);
SBHUFFRDY = new CJBig2_HuffmanTable(HuffmanTable_B15,
FX_ArraySize(HuffmanTable_B15),
HuffmanTable_HTOOB_B15);
SBHUFFRSIZE = new CJBig2_HuffmanTable(HuffmanTable_B1,
FX_ArraySize(HuffmanTable_B1),
HuffmanTable_HTOOB_B1);
pDecoder->SBHUFFFS = SBHUFFFS;
pDecoder->SBHUFFDS = SBHUFFDS;
pDecoder->SBHUFFDT = SBHUFFDT;
pDecoder->SBHUFFRDW = SBHUFFRDW;
pDecoder->SBHUFFRDH = SBHUFFRDH;
pDecoder->SBHUFFRDX = SBHUFFRDX;
pDecoder->SBHUFFRDY = SBHUFFRDY;
pDecoder->SBHUFFRSIZE = SBHUFFRSIZE;
pDecoder->SBRTEMPLATE = SDRTEMPLATE;
pDecoder->SBRAT[0] = SDRAT[0];
pDecoder->SBRAT[1] = SDRAT[1];
pDecoder->SBRAT[2] = SDRAT[2];
pDecoder->SBRAT[3] = SDRAT[3];
JBig2IntDecoderState ids;
ids.IADT = IADT;
ids.IAFS = IAFS;
ids.IADS = IADS;
ids.IAIT = IAIT;
ids.IARI = IARI;
ids.IARDW = IARDW;
ids.IARDH = IARDH;
ids.IARDX = IARDX;
ids.IARDY = IARDY;
ids.IAID = IAID;
BS = pDecoder->decode_Arith(pArithDecoder, grContext, &ids);
if (BS == NULL) {
FX_Free(SBSYMS);
delete SBHUFFFS;
delete SBHUFFDS;
delete SBHUFFDT;
delete SBHUFFRDW;
delete SBHUFFRDH;
delete SBHUFFRDX;
delete SBHUFFRDY;
delete SBHUFFRSIZE;
delete pDecoder;
goto failed;
}
FX_Free(SBSYMS);
delete SBHUFFFS;
delete SBHUFFDS;
delete SBHUFFDT;
delete SBHUFFRDW;
delete SBHUFFRDH;
delete SBHUFFRDX;
delete SBHUFFRDY;
delete SBHUFFRSIZE;
delete pDecoder;
} else if (REFAGGNINST == 1) {
SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
if (IAID->decode(pArithDecoder, (int*)&IDI) == -1) {
goto failed;
}
if ((IARDX->decode(pArithDecoder, &RDXI) == -1) ||
(IARDY->decode(pArithDecoder, &RDYI) == -1)) {
goto failed;
}
if (IDI >= SBNUMSYMS) {
goto failed;
}
SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS);
JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS,
NSYMSDECODED * sizeof(CJBig2_Image*));
if (!SBSYMS[IDI]) {
FX_Free(SBSYMS);
goto failed;
}
pGRRD = new CJBig2_GRRDProc();
pGRRD->GRW = SYMWIDTH;
pGRRD->GRH = HCHEIGHT;
pGRRD->GRTEMPLATE = SDRTEMPLATE;
pGRRD->GRREFERENCE = SBSYMS[IDI];
pGRRD->GRREFERENCEDX = RDXI;
pGRRD->GRREFERENCEDY = RDYI;
pGRRD->TPGRON = 0;
pGRRD->GRAT[0] = SDRAT[0];
pGRRD->GRAT[1] = SDRAT[1];
pGRRD->GRAT[2] = SDRAT[2];
pGRRD->GRAT[3] = SDRAT[3];
BS = pGRRD->decode(pArithDecoder, grContext);
if (BS == NULL) {
FX_Free(SBSYMS);
delete pGRRD;
goto failed;
}
FX_Free(SBSYMS);
delete pGRRD;
}
}
SDNEWSYMS[NSYMSDECODED] = BS;
BS = NULL;
NSYMSDECODED = NSYMSDECODED + 1;
}
}
EXINDEX = 0;
CUREXFLAG = 0;
EXFLAGS = FX_Alloc(FX_BOOL, SDNUMINSYMS + SDNUMNEWSYMS);
while (EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) {
if (IAEX->decode(pArithDecoder, (int*)&EXRUNLENGTH) == -1) {
FX_Free(EXFLAGS);
goto failed;
}
if (EXINDEX + EXRUNLENGTH > SDNUMINSYMS + SDNUMNEWSYMS) {
FX_Free(EXFLAGS);
goto failed;
}
if (EXRUNLENGTH != 0) {
for (I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) {
EXFLAGS[I] = CUREXFLAG;
}
}
EXINDEX = EXINDEX + EXRUNLENGTH;
CUREXFLAG = !CUREXFLAG;
}
pDict = new CJBig2_SymbolDict();
pDict->SDNUMEXSYMS = SDNUMEXSYMS;
pDict->SDEXSYMS = FX_Alloc(CJBig2_Image*, SDNUMEXSYMS);
I = J = 0;
for (I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) {
if (EXFLAGS[I] && J < SDNUMEXSYMS) {
if (I < SDNUMINSYMS) {
pDict->SDEXSYMS[J] = new CJBig2_Image(*SDINSYMS[I]);
} else {
pDict->SDEXSYMS[J] = SDNEWSYMS[I - SDNUMINSYMS];
}
J = J + 1;
} else if (!EXFLAGS[I] && I >= SDNUMINSYMS) {
delete SDNEWSYMS[I - SDNUMINSYMS];
}
}
if (J < SDNUMEXSYMS) {
pDict->SDNUMEXSYMS = J;
}
FX_Free(EXFLAGS);
FX_Free(SDNEWSYMS);
delete IADH;
delete IADW;
delete IAAI;
delete IARDX;
delete IARDY;
delete IAEX;
delete IAID;
delete IADT;
delete IAFS;
delete IADS;
delete IAIT;
delete IARI;
delete IARDW;
delete IARDH;
return pDict;
failed:
for (I = 0; I < NSYMSDECODED; I++) {
if (SDNEWSYMS[I]) {
delete SDNEWSYMS[I];
SDNEWSYMS[I] = NULL;
}
}
FX_Free(SDNEWSYMS);
delete IADH;
delete IADW;
delete IAAI;
delete IARDX;
delete IARDY;
delete IAEX;
delete IAID;
delete IADT;
delete IAFS;
delete IADS;
delete IAIT;
delete IARI;
delete IARDW;
delete IARDH;
return NULL;
}
CJBig2_SymbolDict* CJBig2_SDDProc::decode_Huffman(CJBig2_BitStream* pStream,
JBig2ArithCtx* gbContext,
JBig2ArithCtx* grContext,
IFX_Pause* pPause) {
CJBig2_Image** SDNEWSYMS;
FX_DWORD* SDNEWSYMWIDTHS;
FX_DWORD HCHEIGHT, NSYMSDECODED;
int32_t HCDH;
FX_DWORD SYMWIDTH, TOTWIDTH, HCFIRSTSYM;
int32_t DW;
CJBig2_Image *BS, *BHC;
FX_DWORD I, J, REFAGGNINST;
FX_BOOL* EXFLAGS;
FX_DWORD EXINDEX;
FX_BOOL CUREXFLAG;
FX_DWORD EXRUNLENGTH;
int32_t nVal, nBits;
FX_DWORD nTmp;
FX_DWORD SBNUMSYMS;
uint8_t SBSYMCODELEN;
JBig2HuffmanCode* SBSYMCODES;
FX_DWORD IDI;
int32_t RDXI, RDYI;
FX_DWORD BMSIZE;
FX_DWORD stride;
CJBig2_Image** SBSYMS;
CJBig2_HuffmanTable *SBHUFFFS, *SBHUFFDS, *SBHUFFDT, *SBHUFFRDW, *SBHUFFRDH,
*SBHUFFRDX, *SBHUFFRDY, *SBHUFFRSIZE, *pTable;
CJBig2_HuffmanDecoder* pHuffmanDecoder;
CJBig2_GRRDProc* pGRRD;
CJBig2_ArithDecoder* pArithDecoder;
CJBig2_GRDProc* pGRD;
CJBig2_SymbolDict* pDict;
pHuffmanDecoder = new CJBig2_HuffmanDecoder(pStream);
SDNEWSYMS = FX_Alloc(CJBig2_Image*, SDNUMNEWSYMS);
FXSYS_memset(SDNEWSYMS, 0, SDNUMNEWSYMS * sizeof(CJBig2_Image*));
SDNEWSYMWIDTHS = NULL;
BHC = NULL;
if (SDREFAGG == 0) {
SDNEWSYMWIDTHS = FX_Alloc(FX_DWORD, SDNUMNEWSYMS);
FXSYS_memset(SDNEWSYMWIDTHS, 0, SDNUMNEWSYMS * sizeof(FX_DWORD));
}
HCHEIGHT = 0;
NSYMSDECODED = 0;
BS = NULL;
while (NSYMSDECODED < SDNUMNEWSYMS) {
if (pHuffmanDecoder->decodeAValue(SDHUFFDH, &HCDH) != 0) {
goto failed;
}
HCHEIGHT = HCHEIGHT + HCDH;
if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > JBIG2_MAX_IMAGE_SIZE) {
goto failed;
}
SYMWIDTH = 0;
TOTWIDTH = 0;
HCFIRSTSYM = NSYMSDECODED;
for (;;) {
nVal = pHuffmanDecoder->decodeAValue(SDHUFFDW, &DW);
if (nVal == JBIG2_OOB) {
break;
} else if (nVal != 0) {
goto failed;
} else {
if (NSYMSDECODED >= SDNUMNEWSYMS) {
goto failed;
}
SYMWIDTH = SYMWIDTH + DW;
if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > JBIG2_MAX_IMAGE_SIZE) {
goto failed;
} else if (HCHEIGHT == 0 || SYMWIDTH == 0) {
TOTWIDTH = TOTWIDTH + SYMWIDTH;
SDNEWSYMS[NSYMSDECODED] = NULL;
NSYMSDECODED = NSYMSDECODED + 1;
continue;
}
TOTWIDTH = TOTWIDTH + SYMWIDTH;
}
if (SDREFAGG == 1) {
if (pHuffmanDecoder->decodeAValue(SDHUFFAGGINST, (int*)&REFAGGNINST) !=
0) {
goto failed;
}
BS = NULL;
if (REFAGGNINST > 1) {
CJBig2_TRDProc* pDecoder = new CJBig2_TRDProc();
pDecoder->SBHUFF = SDHUFF;
pDecoder->SBREFINE = 1;
pDecoder->SBW = SYMWIDTH;
pDecoder->SBH = HCHEIGHT;
pDecoder->SBNUMINSTANCES = REFAGGNINST;
pDecoder->SBSTRIPS = 1;
pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
SBNUMSYMS = pDecoder->SBNUMSYMS;
SBSYMCODES = FX_Alloc(JBig2HuffmanCode, SBNUMSYMS);
nTmp = 1;
while ((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
nTmp++;
}
for (I = 0; I < SBNUMSYMS; I++) {
SBSYMCODES[I].codelen = nTmp;
SBSYMCODES[I].code = I;
}
pDecoder->SBSYMCODES = SBSYMCODES;
SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS);
JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS,
NSYMSDECODED * sizeof(CJBig2_Image*));
pDecoder->SBSYMS = SBSYMS;
pDecoder->SBDEFPIXEL = 0;
pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR;
pDecoder->TRANSPOSED = 0;
pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT;
pDecoder->SBDSOFFSET = 0;
SBHUFFFS = new CJBig2_HuffmanTable(HuffmanTable_B6,
FX_ArraySize(HuffmanTable_B6),
HuffmanTable_HTOOB_B6);
SBHUFFDS = new CJBig2_HuffmanTable(HuffmanTable_B8,
FX_ArraySize(HuffmanTable_B8),
HuffmanTable_HTOOB_B8);
SBHUFFDT = new CJBig2_HuffmanTable(HuffmanTable_B11,
FX_ArraySize(HuffmanTable_B11),
HuffmanTable_HTOOB_B11);
SBHUFFRDW = new CJBig2_HuffmanTable(HuffmanTable_B15,
FX_ArraySize(HuffmanTable_B15),
HuffmanTable_HTOOB_B15);
SBHUFFRDH = new CJBig2_HuffmanTable(HuffmanTable_B15,
FX_ArraySize(HuffmanTable_B15),
HuffmanTable_HTOOB_B15);
SBHUFFRDX = new CJBig2_HuffmanTable(HuffmanTable_B15,
FX_ArraySize(HuffmanTable_B15),
HuffmanTable_HTOOB_B15);
SBHUFFRDY = new CJBig2_HuffmanTable(HuffmanTable_B15,
FX_ArraySize(HuffmanTable_B15),
HuffmanTable_HTOOB_B15);
SBHUFFRSIZE = new CJBig2_HuffmanTable(HuffmanTable_B1,
FX_ArraySize(HuffmanTable_B1),
HuffmanTable_HTOOB_B1);
pDecoder->SBHUFFFS = SBHUFFFS;
pDecoder->SBHUFFDS = SBHUFFDS;
pDecoder->SBHUFFDT = SBHUFFDT;
pDecoder->SBHUFFRDW = SBHUFFRDW;
pDecoder->SBHUFFRDH = SBHUFFRDH;
pDecoder->SBHUFFRDX = SBHUFFRDX;
pDecoder->SBHUFFRDY = SBHUFFRDY;
pDecoder->SBHUFFRSIZE = SBHUFFRSIZE;
pDecoder->SBRTEMPLATE = SDRTEMPLATE;
pDecoder->SBRAT[0] = SDRAT[0];
pDecoder->SBRAT[1] = SDRAT[1];
pDecoder->SBRAT[2] = SDRAT[2];
pDecoder->SBRAT[3] = SDRAT[3];
BS = pDecoder->decode_Huffman(pStream, grContext);
if (BS == NULL) {
FX_Free(SBSYMCODES);
FX_Free(SBSYMS);
delete SBHUFFFS;
delete SBHUFFDS;
delete SBHUFFDT;
delete SBHUFFRDW;
delete SBHUFFRDH;
delete SBHUFFRDX;
delete SBHUFFRDY;
delete SBHUFFRSIZE;
delete pDecoder;
goto failed;
}
FX_Free(SBSYMCODES);
FX_Free(SBSYMS);
delete SBHUFFFS;
delete SBHUFFDS;
delete SBHUFFDT;
delete SBHUFFRDW;
delete SBHUFFRDH;
delete SBHUFFRDX;
delete SBHUFFRDY;
delete SBHUFFRSIZE;
delete pDecoder;
} else if (REFAGGNINST == 1) {
SBNUMSYMS = SDNUMINSYMS + SDNUMNEWSYMS;
nTmp = 1;
while ((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
nTmp++;
}
SBSYMCODELEN = (uint8_t)nTmp;
SBSYMCODES = FX_Alloc(JBig2HuffmanCode, SBNUMSYMS);
for (I = 0; I < SBNUMSYMS; I++) {
SBSYMCODES[I].codelen = SBSYMCODELEN;
SBSYMCODES[I].code = I;
}
nVal = 0;
nBits = 0;
for (;;) {
if (pStream->read1Bit(&nTmp) != 0) {
FX_Free(SBSYMCODES);
goto failed;
}
nVal = (nVal << 1) | nTmp;
for (IDI = 0; IDI < SBNUMSYMS; IDI++) {
if ((nVal == SBSYMCODES[IDI].code) &&
(nBits == SBSYMCODES[IDI].codelen)) {
break;
}
}
if (IDI < SBNUMSYMS) {
break;
}
}
FX_Free(SBSYMCODES);
SBHUFFRDX = new CJBig2_HuffmanTable(HuffmanTable_B15,
FX_ArraySize(HuffmanTable_B15),
HuffmanTable_HTOOB_B15);
SBHUFFRSIZE = new CJBig2_HuffmanTable(HuffmanTable_B1,
FX_ArraySize(HuffmanTable_B1),
HuffmanTable_HTOOB_B1);
if ((pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDXI) != 0) ||
(pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDYI) != 0) ||
(pHuffmanDecoder->decodeAValue(SBHUFFRSIZE, &nVal) != 0)) {
delete SBHUFFRDX;
delete SBHUFFRSIZE;
goto failed;
}
delete SBHUFFRDX;
delete SBHUFFRSIZE;
pStream->alignByte();
nTmp = pStream->getOffset();
SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS);
JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS,
NSYMSDECODED * sizeof(CJBig2_Image*));
pGRRD = new CJBig2_GRRDProc();
pGRRD->GRW = SYMWIDTH;
pGRRD->GRH = HCHEIGHT;
pGRRD->GRTEMPLATE = SDRTEMPLATE;
pGRRD->GRREFERENCE = SBSYMS[IDI];
pGRRD->GRREFERENCEDX = RDXI;
pGRRD->GRREFERENCEDY = RDYI;
pGRRD->TPGRON = 0;
pGRRD->GRAT[0] = SDRAT[0];
pGRRD->GRAT[1] = SDRAT[1];
pGRRD->GRAT[2] = SDRAT[2];
pGRRD->GRAT[3] = SDRAT[3];
pArithDecoder = new CJBig2_ArithDecoder(pStream);
BS = pGRRD->decode(pArithDecoder, grContext);
if (BS == NULL) {
FX_Free(SBSYMS);
delete pGRRD;
delete pArithDecoder;
goto failed;
}
pStream->alignByte();
pStream->offset(2);
if ((FX_DWORD)nVal != (pStream->getOffset() - nTmp)) {
delete BS;
FX_Free(SBSYMS);
delete pGRRD;
delete pArithDecoder;
goto failed;
}
FX_Free(SBSYMS);
delete pGRRD;
delete pArithDecoder;
}
SDNEWSYMS[NSYMSDECODED] = BS;
}
if (SDREFAGG == 0) {
SDNEWSYMWIDTHS[NSYMSDECODED] = SYMWIDTH;
}
NSYMSDECODED = NSYMSDECODED + 1;
}
if (SDREFAGG == 0) {
if (pHuffmanDecoder->decodeAValue(SDHUFFBMSIZE, (int32_t*)&BMSIZE) != 0) {
goto failed;
}
pStream->alignByte();
if (BMSIZE == 0) {
stride = (TOTWIDTH + 7) >> 3;
if (pStream->getByteLeft() >= stride * HCHEIGHT) {
BHC = new CJBig2_Image(TOTWIDTH, HCHEIGHT);
for (I = 0; I < HCHEIGHT; I++) {
JBIG2_memcpy(BHC->m_pData + I * BHC->m_nStride,
pStream->getPointer(), stride);
pStream->offset(stride);
}
} else {
goto failed;
}
} else {
pGRD = new CJBig2_GRDProc();
pGRD->MMR = 1;
pGRD->GBW = TOTWIDTH;
pGRD->GBH = HCHEIGHT;
FXCODEC_STATUS status = pGRD->Start_decode_MMR(&BHC, pStream);
while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
pGRD->Continue_decode(pPause);
}
delete pGRD;
pStream->alignByte();
}
nTmp = 0;
if (!BHC) {
continue;
}
for (I = HCFIRSTSYM; I < NSYMSDECODED; I++) {
SDNEWSYMS[I] = BHC->subImage(nTmp, 0, SDNEWSYMWIDTHS[I], HCHEIGHT);
nTmp += SDNEWSYMWIDTHS[I];
}
delete BHC;
BHC = NULL;
}
}
EXINDEX = 0;
CUREXFLAG = 0;
pTable = new CJBig2_HuffmanTable(
HuffmanTable_B1, FX_ArraySize(HuffmanTable_B1), HuffmanTable_HTOOB_B1);
EXFLAGS = FX_Alloc(FX_BOOL, SDNUMINSYMS + SDNUMNEWSYMS);
while (EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) {
if (pHuffmanDecoder->decodeAValue(pTable, (int*)&EXRUNLENGTH) != 0) {
delete pTable;
FX_Free(EXFLAGS);
goto failed;
}
if (EXINDEX + EXRUNLENGTH > SDNUMINSYMS + SDNUMNEWSYMS) {
delete pTable;
FX_Free(EXFLAGS);
goto failed;
}
if (EXRUNLENGTH != 0) {
for (I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) {
EXFLAGS[I] = CUREXFLAG;
}
}
EXINDEX = EXINDEX + EXRUNLENGTH;
CUREXFLAG = !CUREXFLAG;
}
delete pTable;
pDict = new CJBig2_SymbolDict();
pDict->SDNUMEXSYMS = SDNUMEXSYMS;
pDict->SDEXSYMS = FX_Alloc(CJBig2_Image*, SDNUMEXSYMS);
I = J = 0;
for (I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) {
if (EXFLAGS[I] && J < SDNUMEXSYMS) {
if (I < SDNUMINSYMS) {
pDict->SDEXSYMS[J] = new CJBig2_Image(*SDINSYMS[I]);
} else {
pDict->SDEXSYMS[J] = SDNEWSYMS[I - SDNUMINSYMS];
}
J = J + 1;
} else if (!EXFLAGS[I] && I >= SDNUMINSYMS) {
delete SDNEWSYMS[I - SDNUMINSYMS];
}
}
if (J < SDNUMEXSYMS) {
pDict->SDNUMEXSYMS = J;
}
FX_Free(EXFLAGS);
FX_Free(SDNEWSYMS);
if (SDREFAGG == 0) {
FX_Free(SDNEWSYMWIDTHS);
}
delete pHuffmanDecoder;
return pDict;
failed:
for (I = 0; I < NSYMSDECODED; I++) {
delete SDNEWSYMS[I];
}
FX_Free(SDNEWSYMS);
if (SDREFAGG == 0) {
FX_Free(SDNEWSYMWIDTHS);
}
delete pHuffmanDecoder;
return NULL;
}
CJBig2_Image* CJBig2_HTRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext,
IFX_Pause* pPause) {
FX_DWORD ng, mg;
int32_t x, y;
FX_DWORD HBPP;
FX_DWORD* GI;
CJBig2_Image* HSKIP = nullptr;
CJBig2_Image* HTREG = new CJBig2_Image(HBW, HBH);
HTREG->fill(HDEFPIXEL);
if (HENABLESKIP == 1) {
HSKIP = new CJBig2_Image(HGW, HGH);
for (mg = 0; mg < HGH; mg++) {
for (ng = 0; ng < HGW; ng++) {
x = (HGX + mg * HRY + ng * HRX) >> 8;
y = (HGY + mg * HRX - ng * HRY) >> 8;
if ((x + HPW <= 0) | (x >= (int32_t)HBW) | (y + HPH <= 0) |
(y >= (int32_t)HPH)) {
HSKIP->setPixel(ng, mg, 1);
} else {
HSKIP->setPixel(ng, mg, 0);
}
}
}
}
HBPP = 1;
while ((FX_DWORD)(1 << HBPP) < HNUMPATS) {
HBPP++;
}
CJBig2_GSIDProc* pGID = new CJBig2_GSIDProc();
pGID->GSMMR = HMMR;
pGID->GSW = HGW;
pGID->GSH = HGH;
pGID->GSBPP = (uint8_t)HBPP;
pGID->GSUSESKIP = HENABLESKIP;
pGID->GSKIP = HSKIP;
pGID->GSTEMPLATE = HTEMPLATE;
GI = pGID->decode_Arith(pArithDecoder, gbContext, pPause);
if (GI == NULL) {
goto failed;
}
for (mg = 0; mg < HGH; mg++) {
for (ng = 0; ng < HGW; ng++) {
x = (HGX + mg * HRY + ng * HRX) >> 8;
y = (HGY + mg * HRX - ng * HRY) >> 8;
FX_DWORD pat_index = GI[mg * HGW + ng];
if (pat_index >= HNUMPATS) {
pat_index = HNUMPATS - 1;
}
HTREG->composeFrom(x, y, HPATS[pat_index], HCOMBOP);
}
}
FX_Free(GI);
delete HSKIP;
delete pGID;
return HTREG;
failed:
delete HSKIP;
delete pGID;
delete HTREG;
return NULL;
}
CJBig2_Image* CJBig2_HTRDProc::decode_MMR(CJBig2_BitStream* pStream,
IFX_Pause* pPause) {
FX_DWORD ng, mg;
int32_t x, y;
FX_DWORD* GI;
CJBig2_Image* HTREG = new CJBig2_Image(HBW, HBH);
HTREG->fill(HDEFPIXEL);
FX_DWORD HBPP = 1;
while ((FX_DWORD)(1 << HBPP) < HNUMPATS) {
HBPP++;
}
CJBig2_GSIDProc* pGID = new CJBig2_GSIDProc();
pGID->GSMMR = HMMR;
pGID->GSW = HGW;
pGID->GSH = HGH;
pGID->GSBPP = (uint8_t)HBPP;
pGID->GSUSESKIP = 0;
GI = pGID->decode_MMR(pStream, pPause);
if (GI == NULL) {
goto failed;
}
for (mg = 0; mg < HGH; mg++) {
for (ng = 0; ng < HGW; ng++) {
x = (HGX + mg * HRY + ng * HRX) >> 8;
y = (HGY + mg * HRX - ng * HRY) >> 8;
FX_DWORD pat_index = GI[mg * HGW + ng];
if (pat_index >= HNUMPATS) {
pat_index = HNUMPATS - 1;
}
HTREG->composeFrom(x, y, HPATS[pat_index], HCOMBOP);
}
}
FX_Free(GI);
delete pGID;
return HTREG;
failed:
delete pGID;
delete HTREG;
return NULL;
}
CJBig2_PatternDict* CJBig2_PDDProc::decode_Arith(
CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext,
IFX_Pause* pPause) {
FX_DWORD GRAY;
CJBig2_Image* BHDC = NULL;
CJBig2_PatternDict* pDict = new CJBig2_PatternDict();
pDict->NUMPATS = GRAYMAX + 1;
pDict->HDPATS = FX_Alloc(CJBig2_Image*, pDict->NUMPATS);
JBIG2_memset(pDict->HDPATS, 0, sizeof(CJBig2_Image*) * pDict->NUMPATS);
CJBig2_GRDProc* pGRD = new CJBig2_GRDProc();
pGRD->MMR = HDMMR;
pGRD->GBW = (GRAYMAX + 1) * HDPW;
pGRD->GBH = HDPH;
pGRD->GBTEMPLATE = HDTEMPLATE;
pGRD->TPGDON = 0;
pGRD->USESKIP = 0;
pGRD->GBAT[0] = -(int32_t)HDPW;
pGRD->GBAT[1] = 0;
if (pGRD->GBTEMPLATE == 0) {
pGRD->GBAT[2] = -3;
pGRD->GBAT[3] = -1;
pGRD->GBAT[4] = 2;
pGRD->GBAT[5] = -2;
pGRD->GBAT[6] = -2;
pGRD->GBAT[7] = -2;
}
FXCODEC_STATUS status =
pGRD->Start_decode_Arith(&BHDC, pArithDecoder, gbContext);
while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
pGRD->Continue_decode(pPause);
}
if (BHDC == NULL) {
delete pGRD;
goto failed;
}
delete pGRD;
GRAY = 0;
while (GRAY <= GRAYMAX) {
pDict->HDPATS[GRAY] = BHDC->subImage(HDPW * GRAY, 0, HDPW, HDPH);
GRAY = GRAY + 1;
}
delete BHDC;
return pDict;
failed:
delete pDict;
return NULL;
}
CJBig2_PatternDict* CJBig2_PDDProc::decode_MMR(CJBig2_BitStream* pStream,
IFX_Pause* pPause) {
FX_DWORD GRAY;
CJBig2_Image* BHDC = NULL;
CJBig2_PatternDict* pDict = new CJBig2_PatternDict();
pDict->NUMPATS = GRAYMAX + 1;
pDict->HDPATS = FX_Alloc(CJBig2_Image*, pDict->NUMPATS);
JBIG2_memset(pDict->HDPATS, 0, sizeof(CJBig2_Image*) * pDict->NUMPATS);
CJBig2_GRDProc* pGRD = new CJBig2_GRDProc();
pGRD->MMR = HDMMR;
pGRD->GBW = (GRAYMAX + 1) * HDPW;
pGRD->GBH = HDPH;
FXCODEC_STATUS status = pGRD->Start_decode_MMR(&BHDC, pStream);
while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
pGRD->Continue_decode(pPause);
}
if (BHDC == NULL) {
delete pGRD;
goto failed;
}
delete pGRD;
GRAY = 0;
while (GRAY <= GRAYMAX) {
pDict->HDPATS[GRAY] = BHDC->subImage(HDPW * GRAY, 0, HDPW, HDPH);
GRAY = GRAY + 1;
}
delete BHDC;
return pDict;
failed:
delete pDict;
return NULL;
}
FX_DWORD* CJBig2_GSIDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext,
IFX_Pause* pPause) {
CJBig2_Image** GSPLANES;
int32_t J, K;
FX_DWORD x, y;
FX_DWORD* GSVALS;
GSPLANES = FX_Alloc(CJBig2_Image*, GSBPP);
if (!GSPLANES) {
return NULL;
}
GSVALS = FX_Alloc2D(FX_DWORD, GSW, GSH);
if (!GSVALS) {
FX_Free(GSPLANES);
return NULL;
}
JBIG2_memset(GSPLANES, 0, sizeof(CJBig2_Image*) * GSBPP);
JBIG2_memset(GSVALS, 0, sizeof(FX_DWORD) * GSW * GSH);
CJBig2_GRDProc* pGRD = new CJBig2_GRDProc();
pGRD->MMR = GSMMR;
pGRD->GBW = GSW;
pGRD->GBH = GSH;
pGRD->GBTEMPLATE = GSTEMPLATE;
pGRD->TPGDON = 0;
pGRD->USESKIP = GSUSESKIP;
pGRD->SKIP = GSKIP;
if (GSTEMPLATE <= 1) {
pGRD->GBAT[0] = 3;
} else {
pGRD->GBAT[0] = 2;
}
pGRD->GBAT[1] = -1;
if (pGRD->GBTEMPLATE == 0) {
pGRD->GBAT[2] = -3;
pGRD->GBAT[3] = -1;
pGRD->GBAT[4] = 2;
pGRD->GBAT[5] = -2;
pGRD->GBAT[6] = -2;
pGRD->GBAT[7] = -2;
}
FXCODEC_STATUS status =
pGRD->Start_decode_Arith(&GSPLANES[GSBPP - 1], pArithDecoder, gbContext);
while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
pGRD->Continue_decode(pPause);
}
if (GSPLANES[GSBPP - 1] == NULL) {
goto failed;
}
J = GSBPP - 2;
while (J >= 0) {
FXCODEC_STATUS status =
pGRD->Start_decode_Arith(&GSPLANES[J], pArithDecoder, gbContext);
while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
pGRD->Continue_decode(pPause);
}
if (GSPLANES[J] == NULL) {
for (K = GSBPP - 1; K > J; K--) {
delete GSPLANES[K];
goto failed;
}
}
GSPLANES[J]->composeFrom(0, 0, GSPLANES[J + 1], JBIG2_COMPOSE_XOR);
J = J - 1;
}
for (y = 0; y < GSH; y++) {
for (x = 0; x < GSW; x++) {
for (J = 0; J < GSBPP; J++) {
GSVALS[y * GSW + x] |= GSPLANES[J]->getPixel(x, y) << J;
}
}
}
for (J = 0; J < GSBPP; J++) {
delete GSPLANES[J];
}
FX_Free(GSPLANES);
delete pGRD;
return GSVALS;
failed:
FX_Free(GSPLANES);
delete pGRD;
FX_Free(GSVALS);
return NULL;
}
FX_DWORD* CJBig2_GSIDProc::decode_MMR(CJBig2_BitStream* pStream,
IFX_Pause* pPause) {
CJBig2_Image** GSPLANES;
int32_t J, K;
FX_DWORD x, y;
FX_DWORD* GSVALS;
GSPLANES = FX_Alloc(CJBig2_Image*, GSBPP);
if (!GSPLANES) {
return NULL;
}
GSVALS = FX_Alloc2D(FX_DWORD, GSW, GSH);
if (!GSVALS) {
FX_Free(GSPLANES);
return NULL;
}
JBIG2_memset(GSPLANES, 0, sizeof(CJBig2_Image*) * GSBPP);
JBIG2_memset(GSVALS, 0, sizeof(FX_DWORD) * GSW * GSH);
CJBig2_GRDProc* pGRD = new CJBig2_GRDProc();
pGRD->MMR = GSMMR;
pGRD->GBW = GSW;
pGRD->GBH = GSH;
FXCODEC_STATUS status = pGRD->Start_decode_MMR(&GSPLANES[GSBPP - 1], pStream);
while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
pGRD->Continue_decode(pPause);
}
if (GSPLANES[GSBPP - 1] == NULL) {
goto failed;
}
pStream->alignByte();
pStream->offset(3);
J = GSBPP - 2;
while (J >= 0) {
FXCODEC_STATUS status = pGRD->Start_decode_MMR(&GSPLANES[J], pStream);
while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
pGRD->Continue_decode(pPause);
}
if (GSPLANES[J] == NULL) {
for (K = GSBPP - 1; K > J; K--) {
delete GSPLANES[K];
goto failed;
}
}
pStream->alignByte();
pStream->offset(3);
GSPLANES[J]->composeFrom(0, 0, GSPLANES[J + 1], JBIG2_COMPOSE_XOR);
J = J - 1;
}
for (y = 0; y < GSH; y++) {
for (x = 0; x < GSW; x++) {
for (J = 0; J < GSBPP; J++) {
GSVALS[y * GSW + x] |= GSPLANES[J]->getPixel(x, y) << J;
}
}
}
for (J = 0; J < GSBPP; J++) {
delete GSPLANES[J];
}
FX_Free(GSPLANES);
delete pGRD;
return GSVALS;
failed:
FX_Free(GSPLANES);
delete pGRD;
FX_Free(GSVALS);
return NULL;
}
FXCODEC_STATUS CJBig2_GRDProc::Start_decode_Arith(
CJBig2_Image** pImage,
CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext,
IFX_Pause* pPause) {
if (GBW == 0 || GBH == 0) {
m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
return FXCODEC_STATUS_DECODE_FINISH;
}
m_ProssiveStatus = FXCODEC_STATUS_DECODE_READY;
m_pPause = pPause;
if (!*pImage)
*pImage = new CJBig2_Image(GBW, GBH);
if ((*pImage)->m_pData == NULL) {
delete *pImage;
*pImage = NULL;
m_ProssiveStatus = FXCODEC_STATUS_ERROR;
return FXCODEC_STATUS_ERROR;
}
m_DecodeType = 1;
m_pImage = pImage;
(*m_pImage)->fill(0);
m_pArithDecoder = pArithDecoder;
m_gbContext = gbContext;
LTP = 0;
m_pLine = NULL;
m_loopIndex = 0;
return decode_Arith(pPause);
}
FXCODEC_STATUS CJBig2_GRDProc::decode_Arith(IFX_Pause* pPause) {
int iline = m_loopIndex;
CJBig2_Image* pImage = *m_pImage;
if (GBTEMPLATE == 0) {
if ((GBAT[0] == 3) && (GBAT[1] == (int8_t)-1) && (GBAT[2] == (int8_t)-3) &&
(GBAT[3] == (int8_t)-1) && (GBAT[4] == 2) && (GBAT[5] == (int8_t)-2) &&
(GBAT[6] == (int8_t)-2) && (GBAT[7] == (int8_t)-2)) {
m_ProssiveStatus = decode_Arith_Template0_opt3(pImage, m_pArithDecoder,
m_gbContext, pPause);
} else {
m_ProssiveStatus = decode_Arith_Template0_unopt(pImage, m_pArithDecoder,
m_gbContext, pPause);
}
} else if (GBTEMPLATE == 1) {
if ((GBAT[0] == 3) && (GBAT[1] == (int8_t)-1)) {
m_ProssiveStatus = decode_Arith_Template1_opt3(pImage, m_pArithDecoder,
m_gbContext, pPause);
} else {
m_ProssiveStatus = decode_Arith_Template1_unopt(pImage, m_pArithDecoder,
m_gbContext, pPause);
}
} else if (GBTEMPLATE == 2) {
if ((GBAT[0] == 2) && (GBAT[1] == (int8_t)-1)) {
m_ProssiveStatus = decode_Arith_Template2_opt3(pImage, m_pArithDecoder,
m_gbContext, pPause);
} else {
m_ProssiveStatus = decode_Arith_Template2_unopt(pImage, m_pArithDecoder,
m_gbContext, pPause);
}
} else {
if ((GBAT[0] == 2) && (GBAT[1] == (int8_t)-1)) {
m_ProssiveStatus = decode_Arith_Template3_opt3(pImage, m_pArithDecoder,
m_gbContext, pPause);
} else {
m_ProssiveStatus = decode_Arith_Template3_unopt(pImage, m_pArithDecoder,
m_gbContext, pPause);
}
}
m_ReplaceRect.left = 0;
m_ReplaceRect.right = pImage->m_nWidth;
m_ReplaceRect.top = iline;
m_ReplaceRect.bottom = m_loopIndex;
if (m_ProssiveStatus == FXCODEC_STATUS_DECODE_FINISH) {
m_loopIndex = 0;
}
return m_ProssiveStatus;
}
FXCODEC_STATUS CJBig2_GRDProc::Start_decode_MMR(CJBig2_Image** pImage,
CJBig2_BitStream* pStream,
IFX_Pause* pPause) {
int bitpos, i;
*pImage = new CJBig2_Image(GBW, GBH);
if ((*pImage)->m_pData == NULL) {
delete (*pImage);
(*pImage) = NULL;
m_ProssiveStatus = FXCODEC_STATUS_ERROR;
return m_ProssiveStatus;
}
bitpos = (int)pStream->getBitPos();
_FaxG4Decode(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];
}
m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
return m_ProssiveStatus;
}
FXCODEC_STATUS CJBig2_GRDProc::Continue_decode(IFX_Pause* pPause) {
if (m_ProssiveStatus != FXCODEC_STATUS_DECODE_TOBECONTINUE)
return m_ProssiveStatus;
if (m_DecodeType != 1) {
m_ProssiveStatus = FXCODEC_STATUS_ERROR;
return m_ProssiveStatus;
}
return decode_Arith(pPause);
}
FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_opt3(
CJBig2_Image* pImage,
CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext,
IFX_Pause* pPause) {
FX_BOOL SLTP, bVal;
FX_DWORD CONTEXT;
FX_DWORD line1, line2;
uint8_t *pLine1, *pLine2, cVal;
int32_t nStride, nStride2, k;
int32_t nLineBytes, nBitsLeft, cc;
if (m_pLine == NULL) {
m_pLine = pImage->m_pData;
}
nStride = pImage->m_nStride;
nStride2 = nStride << 1;
nLineBytes = ((GBW + 7) >> 3) - 1;
nBitsLeft = GBW - (nLineBytes << 3);
FX_DWORD height = GBH & 0x7fffffff;
for (; m_loopIndex < height; m_loopIndex++) {
if (TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
LTP = LTP ^ SLTP;
}
if (LTP == 1) {
pImage->copyLine(m_loopIndex, m_loopIndex - 1);
} else {
if (m_loopIndex > 1) {
pLine1 = m_pLine - nStride2;
pLine2 = m_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));
}
m_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));
}
m_pLine[nLineBytes] = cVal;
} else {
pLine2 = m_pLine - nStride;
line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
CONTEXT = (line2 & 0x07f0);
for (cc = 0; cc < nLineBytes; cc++) {
if (m_loopIndex & 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));
}
m_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));
}
m_pLine[nLineBytes] = cVal;
}
}
m_pLine += nStride;
if (pPause && pPause->NeedToPauseNow()) {
m_loopIndex++;
m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
return FXCODEC_STATUS_DECODE_TOBECONTINUE;
}
}
m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
return FXCODEC_STATUS_DECODE_FINISH;
}
FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_unopt(
CJBig2_Image* pImage,
CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext,
IFX_Pause* pPause) {
FX_BOOL SLTP, bVal;
FX_DWORD CONTEXT;
FX_DWORD line1, line2, line3;
for (; m_loopIndex < GBH; m_loopIndex++) {
if (TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
LTP = LTP ^ SLTP;
}
if (LTP == 1) {
pImage->copyLine(m_loopIndex, m_loopIndex - 1);
} else {
line1 = pImage->getPixel(1, m_loopIndex - 2);
line1 |= pImage->getPixel(0, m_loopIndex - 2) << 1;
line2 = pImage->getPixel(2, m_loopIndex - 1);
line2 |= pImage->getPixel(1, m_loopIndex - 1) << 1;
line2 |= pImage->getPixel(0, m_loopIndex - 1) << 2;
line3 = 0;
for (FX_DWORD w = 0; w < GBW; w++) {
if (USESKIP && SKIP->getPixel(w, m_loopIndex)) {
bVal = 0;
} else {
CONTEXT = line3;
CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
CONTEXT |= line2 << 5;
CONTEXT |= pImage->getPixel(w + GBAT[2], m_loopIndex + GBAT[3]) << 10;
CONTEXT |= pImage->getPixel(w + GBAT[4], m_loopIndex + GBAT[5]) << 11;
CONTEXT |= line1 << 12;
CONTEXT |= pImage->getPixel(w + GBAT[6], m_loopIndex + GBAT[7]) << 15;
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
if (bVal) {
pImage->setPixel(w, m_loopIndex, bVal);
}
line1 =
((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 2)) & 0x07;
line2 =
((line2 << 1) | pImage->getPixel(w + 3, m_loopIndex - 1)) & 0x1f;
line3 = ((line3 << 1) | bVal) & 0x0f;
}
}
if (pPause && pPause->NeedToPauseNow()) {
m_loopIndex++;
m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
return FXCODEC_STATUS_DECODE_TOBECONTINUE;
}
}
m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
return FXCODEC_STATUS_DECODE_FINISH;
}
FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_opt3(
CJBig2_Image* pImage,
CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext,
IFX_Pause* pPause) {
FX_BOOL SLTP, bVal;
FX_DWORD CONTEXT;
FX_DWORD line1, line2;
uint8_t *pLine1, *pLine2, cVal;
int32_t nStride, nStride2, k;
int32_t nLineBytes, nBitsLeft, cc;
if (!m_pLine) {
m_pLine = pImage->m_pData;
}
nStride = pImage->m_nStride;
nStride2 = nStride << 1;
nLineBytes = ((GBW + 7) >> 3) - 1;
nBitsLeft = GBW - (nLineBytes << 3);
for (; m_loopIndex < GBH; m_loopIndex++) {
if (TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
LTP = LTP ^ SLTP;
}
if (LTP == 1) {
pImage->copyLine(m_loopIndex, m_loopIndex - 1);
} else {
if (m_loopIndex > 1) {
pLine1 = m_pLine - nStride2;
pLine2 = m_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);
}
m_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);
}
m_pLine[nLineBytes] = cVal;
} else {
pLine2 = m_pLine - nStride;
line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
CONTEXT = (line2 >> 1) & 0x01f8;
for (cc = 0; cc < nLineBytes; cc++) {
if (m_loopIndex & 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);
}
m_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);
}
m_pLine[nLineBytes] = cVal;
}
}
m_pLine += nStride;
if (pPause && pPause->NeedToPauseNow()) {
m_loopIndex++;
m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
return FXCODEC_STATUS_DECODE_TOBECONTINUE;
}
}
m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
return FXCODEC_STATUS_DECODE_FINISH;
}
FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_unopt(
CJBig2_Image* pImage,
CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext,
IFX_Pause* pPause) {
FX_BOOL SLTP, bVal;
FX_DWORD CONTEXT;
FX_DWORD line1, line2, line3;
for (FX_DWORD h = 0; h < GBH; h++) {
if (TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
LTP = LTP ^ SLTP;
}
if (LTP == 1) {
pImage->copyLine(h, h - 1);
} else {
line1 = pImage->getPixel(2, h - 2);
line1 |= pImage->getPixel(1, h - 2) << 1;
line1 |= pImage->getPixel(0, h - 2) << 2;
line2 = pImage->getPixel(2, h - 1);
line2 |= pImage->getPixel(1, h - 1) << 1;
line2 |= pImage->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 |= pImage->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
CONTEXT |= line2 << 4;
CONTEXT |= line1 << 9;
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
if (bVal) {
pImage->setPixel(w, h, bVal);
}
line1 = ((line1 << 1) | pImage->getPixel(w + 3, h - 2)) & 0x0f;
line2 = ((line2 << 1) | pImage->getPixel(w + 3, h - 1)) & 0x1f;
line3 = ((line3 << 1) | bVal) & 0x07;
}
}
if (pPause && pPause->NeedToPauseNow()) {
m_loopIndex++;
m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
return FXCODEC_STATUS_DECODE_TOBECONTINUE;
}
}
m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
return FXCODEC_STATUS_DECODE_FINISH;
}
FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_opt3(
CJBig2_Image* pImage,
CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext,
IFX_Pause* pPause) {
FX_BOOL SLTP, bVal;
FX_DWORD CONTEXT;
FX_DWORD line1, line2;
uint8_t *pLine1, *pLine2, cVal;
int32_t nStride, nStride2, k;
int32_t nLineBytes, nBitsLeft, cc;
if (!m_pLine) {
m_pLine = pImage->m_pData;
}
nStride = pImage->m_nStride;
nStride2 = nStride << 1;
nLineBytes = ((GBW + 7) >> 3) - 1;
nBitsLeft = GBW - (nLineBytes << 3);
for (; m_loopIndex < GBH; m_loopIndex++) {
if (TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
LTP = LTP ^ SLTP;
}
if (LTP == 1) {
pImage->copyLine(m_loopIndex, m_loopIndex - 1);
} else {
if (m_loopIndex > 1) {
pLine1 = m_pLine - nStride2;
pLine2 = m_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);
}
m_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);
}
m_pLine[nLineBytes] = cVal;
} else {
pLine2 = m_pLine - nStride;
line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
CONTEXT = (line2 >> 3) & 0x007c;
for (cc = 0; cc < nLineBytes; cc++) {
if (m_loopIndex & 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);
}
m_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);
}
m_pLine[nLineBytes] = cVal;
}
}
m_pLine += nStride;
if (pPause && m_loopIndex % 50 == 0 && pPause->NeedToPauseNow()) {
m_loopIndex++;
m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
return FXCODEC_STATUS_DECODE_TOBECONTINUE;
}
}
m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
return FXCODEC_STATUS_DECODE_FINISH;
}
FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_unopt(
CJBig2_Image* pImage,
CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext,
IFX_Pause* pPause) {
FX_BOOL SLTP, bVal;
FX_DWORD CONTEXT;
FX_DWORD line1, line2, line3;
for (; m_loopIndex < GBH; m_loopIndex++) {
if (TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
LTP = LTP ^ SLTP;
}
if (LTP == 1) {
pImage->copyLine(m_loopIndex, m_loopIndex - 1);
} else {
line1 = pImage->getPixel(1, m_loopIndex - 2);
line1 |= pImage->getPixel(0, m_loopIndex - 2) << 1;
line2 = pImage->getPixel(1, m_loopIndex - 1);
line2 |= pImage->getPixel(0, m_loopIndex - 1) << 1;
line3 = 0;
for (FX_DWORD w = 0; w < GBW; w++) {
if (USESKIP && SKIP->getPixel(w, m_loopIndex)) {
bVal = 0;
} else {
CONTEXT = line3;
CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 2;
CONTEXT |= line2 << 3;
CONTEXT |= line1 << 7;
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
if (bVal) {
pImage->setPixel(w, m_loopIndex, bVal);
}
line1 =
((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 2)) & 0x07;
line2 =
((line2 << 1) | pImage->getPixel(w + 2, m_loopIndex - 1)) & 0x0f;
line3 = ((line3 << 1) | bVal) & 0x03;
}
}
if (pPause && pPause->NeedToPauseNow()) {
m_loopIndex++;
m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
return FXCODEC_STATUS_DECODE_TOBECONTINUE;
}
}
m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
return FXCODEC_STATUS_DECODE_FINISH;
}
FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_opt3(
CJBig2_Image* pImage,
CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext,
IFX_Pause* pPause) {
FX_BOOL SLTP, bVal;
FX_DWORD CONTEXT;
FX_DWORD line1;
uint8_t *pLine1, cVal;
int32_t nStride, k;
int32_t nLineBytes, nBitsLeft, cc;
if (!m_pLine) {
m_pLine = pImage->m_pData;
}
nStride = pImage->m_nStride;
nLineBytes = ((GBW + 7) >> 3) - 1;
nBitsLeft = GBW - (nLineBytes << 3);
for (; m_loopIndex < GBH; m_loopIndex++) {
if (TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
LTP = LTP ^ SLTP;
}
if (LTP == 1) {
pImage->copyLine(m_loopIndex, m_loopIndex - 1);
} else {
if (m_loopIndex > 0) {
pLine1 = m_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);
}
m_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);
}
m_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;
}
m_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;
}
m_pLine[nLineBytes] = cVal;
}
}
m_pLine += nStride;
if (pPause && pPause->NeedToPauseNow()) {
m_loopIndex++;
m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
return FXCODEC_STATUS_DECODE_TOBECONTINUE;
}
}
m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
return FXCODEC_STATUS_DECODE_FINISH;
}
FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_unopt(
CJBig2_Image* pImage,
CJBig2_ArithDecoder* pArithDecoder,
JBig2ArithCtx* gbContext,
IFX_Pause* pPause) {
FX_BOOL SLTP, bVal;
FX_DWORD CONTEXT;
FX_DWORD line1, line2;
for (; m_loopIndex < GBH; m_loopIndex++) {
if (TPGDON) {
SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
LTP = LTP ^ SLTP;
}
if (LTP == 1) {
pImage->copyLine(m_loopIndex, m_loopIndex - 1);
} else {
line1 = pImage->getPixel(1, m_loopIndex - 1);
line1 |= pImage->getPixel(0, m_loopIndex - 1) << 1;
line2 = 0;
for (FX_DWORD w = 0; w < GBW; w++) {
if (USESKIP && SKIP->getPixel(w, m_loopIndex)) {
bVal = 0;
} else {
CONTEXT = line2;
CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
CONTEXT |= line1 << 5;
bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
}
if (bVal) {
pImage->setPixel(w, m_loopIndex, bVal);
}
line1 =
((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 1)) & 0x1f;
line2 = ((line2 << 1) | bVal) & 0x0f;
}
}
if (pPause && pPause->NeedToPauseNow()) {
m_loopIndex++;
m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
return FXCODEC_STATUS_DECODE_TOBECONTINUE;
}
}
m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
return FXCODEC_STATUS_DECODE_FINISH;
}