blob: d23f7ea3887868882f9eedd989b66d70bda48632 [file] [log] [blame]
//========================================================================
//
// JArithmeticDecoder.cc
//
// Copyright 2002-2004 Glyph & Cog, LLC
//
//========================================================================
#include <config.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include "Object.h"
#include "Stream.h"
#include "JArithmeticDecoder.h"
//------------------------------------------------------------------------
// JArithmeticDecoderStates
//------------------------------------------------------------------------
JArithmeticDecoderStats::JArithmeticDecoderStats(int contextSizeA) {
contextSize = contextSizeA;
cxTab = (Guchar *)gmallocn(contextSize, sizeof(Guchar));
reset();
}
JArithmeticDecoderStats::~JArithmeticDecoderStats() {
gfree(cxTab);
}
JArithmeticDecoderStats *JArithmeticDecoderStats::copy() {
JArithmeticDecoderStats *stats;
stats = new JArithmeticDecoderStats(contextSize);
memcpy(stats->cxTab, cxTab, contextSize);
return stats;
}
void JArithmeticDecoderStats::reset() {
memset(cxTab, 0, contextSize);
}
void JArithmeticDecoderStats::copyFrom(JArithmeticDecoderStats *stats) {
memcpy(cxTab, stats->cxTab, contextSize);
}
void JArithmeticDecoderStats::setEntry(Guint cx, int i, int mps) {
cxTab[cx] = (i << 1) + mps;
}
//------------------------------------------------------------------------
// JArithmeticDecoder
//------------------------------------------------------------------------
Guint JArithmeticDecoder::qeTab[47] = {
0x56010000, 0x34010000, 0x18010000, 0x0AC10000,
0x05210000, 0x02210000, 0x56010000, 0x54010000,
0x48010000, 0x38010000, 0x30010000, 0x24010000,
0x1C010000, 0x16010000, 0x56010000, 0x54010000,
0x51010000, 0x48010000, 0x38010000, 0x34010000,
0x30010000, 0x28010000, 0x24010000, 0x22010000,
0x1C010000, 0x18010000, 0x16010000, 0x14010000,
0x12010000, 0x11010000, 0x0AC10000, 0x09C10000,
0x08A10000, 0x05210000, 0x04410000, 0x02A10000,
0x02210000, 0x01410000, 0x01110000, 0x00850000,
0x00490000, 0x00250000, 0x00150000, 0x00090000,
0x00050000, 0x00010000, 0x56010000
};
int JArithmeticDecoder::nmpsTab[47] = {
1, 2, 3, 4, 5, 38, 7, 8, 9, 10, 11, 12, 13, 29, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 45, 46
};
int JArithmeticDecoder::nlpsTab[47] = {
1, 6, 9, 12, 29, 33, 6, 14, 14, 14, 17, 18, 20, 21, 14, 14,
15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46
};
int JArithmeticDecoder::switchTab[47] = {
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
JArithmeticDecoder::JArithmeticDecoder() {
str = NULL;
dataLen = 0;
limitStream = gFalse;
nBytesRead = 0;
}
inline Guint JArithmeticDecoder::readByte() {
if (limitStream) {
--dataLen;
if (dataLen < 0) {
return 0xff;
}
}
++nBytesRead;
return (Guint)str->getChar() & 0xff;
}
JArithmeticDecoder::~JArithmeticDecoder() {
cleanup();
}
void JArithmeticDecoder::start() {
buf0 = readByte();
buf1 = readByte();
// INITDEC
c = (buf0 ^ 0xff) << 16;
byteIn();
c <<= 7;
ct -= 7;
a = 0x80000000;
}
void JArithmeticDecoder::restart(int dataLenA) {
Guint cAdd;
GBool prevFF;
int k, nBits;
if (dataLen >= 0) {
dataLen = dataLenA;
} else if (dataLen == -1) {
dataLen = dataLenA;
buf1 = readByte();
} else {
k = (-dataLen - 1) * 8 - ct;
dataLen = dataLenA;
cAdd = 0;
prevFF = gFalse;
while (k > 0) {
buf0 = readByte();
if (prevFF) {
cAdd += 0xfe00 - (buf0 << 9);
nBits = 7;
} else {
cAdd += 0xff00 - (buf0 << 8);
nBits = 8;
}
prevFF = buf0 == 0xff;
if (k > nBits) {
cAdd <<= nBits;
k -= nBits;
} else {
cAdd <<= k;
ct = nBits - k;
k = 0;
}
}
c += cAdd;
buf1 = readByte();
}
}
void JArithmeticDecoder::cleanup() {
if (limitStream) {
while (dataLen > 0) {
buf0 = buf1;
buf1 = readByte();
}
}
}
int JArithmeticDecoder::decodeBit(Guint context,
JArithmeticDecoderStats *stats) {
int bit;
Guint qe;
int iCX, mpsCX;
iCX = stats->cxTab[context] >> 1;
mpsCX = stats->cxTab[context] & 1;
qe = qeTab[iCX];
a -= qe;
if (c < a) {
if (a & 0x80000000) {
bit = mpsCX;
} else {
// MPS_EXCHANGE
if (a < qe) {
bit = 1 - mpsCX;
if (switchTab[iCX]) {
stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX);
} else {
stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX;
}
} else {
bit = mpsCX;
stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX;
}
// RENORMD
do {
if (ct == 0) {
byteIn();
}
a <<= 1;
c <<= 1;
--ct;
} while (!(a & 0x80000000));
}
} else {
c -= a;
// LPS_EXCHANGE
if (a < qe) {
bit = mpsCX;
stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX;
} else {
bit = 1 - mpsCX;
if (switchTab[iCX]) {
stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX);
} else {
stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX;
}
}
a = qe;
// RENORMD
do {
if (ct == 0) {
byteIn();
}
a <<= 1;
c <<= 1;
--ct;
} while (!(a & 0x80000000));
}
return bit;
}
int JArithmeticDecoder::decodeByte(Guint context,
JArithmeticDecoderStats *stats) {
int byte;
int i;
byte = 0;
for (i = 0; i < 8; ++i) {
byte = (byte << 1) | decodeBit(context, stats);
}
return byte;
}
GBool JArithmeticDecoder::decodeInt(int *x, JArithmeticDecoderStats *stats) {
int s;
Guint v;
int i;
prev = 1;
s = decodeIntBit(stats);
if (decodeIntBit(stats)) {
if (decodeIntBit(stats)) {
if (decodeIntBit(stats)) {
if (decodeIntBit(stats)) {
if (decodeIntBit(stats)) {
v = 0;
for (i = 0; i < 32; ++i) {
v = (v << 1) | decodeIntBit(stats);
}
v += 4436;
} else {
v = 0;
for (i = 0; i < 12; ++i) {
v = (v << 1) | decodeIntBit(stats);
}
v += 340;
}
} else {
v = 0;
for (i = 0; i < 8; ++i) {
v = (v << 1) | decodeIntBit(stats);
}
v += 84;
}
} else {
v = 0;
for (i = 0; i < 6; ++i) {
v = (v << 1) | decodeIntBit(stats);
}
v += 20;
}
} else {
v = decodeIntBit(stats);
v = (v << 1) | decodeIntBit(stats);
v = (v << 1) | decodeIntBit(stats);
v = (v << 1) | decodeIntBit(stats);
v += 4;
}
} else {
v = decodeIntBit(stats);
v = (v << 1) | decodeIntBit(stats);
}
if (s) {
if (v == 0) {
return gFalse;
}
*x = -(int)v;
} else {
*x = (int)v;
}
return gTrue;
}
int JArithmeticDecoder::decodeIntBit(JArithmeticDecoderStats *stats) {
int bit;
bit = decodeBit(prev, stats);
if (prev < 0x100) {
prev = (prev << 1) | bit;
} else {
prev = (((prev << 1) | bit) & 0x1ff) | 0x100;
}
return bit;
}
Guint JArithmeticDecoder::decodeIAID(Guint codeLen,
JArithmeticDecoderStats *stats) {
Guint i;
int bit;
prev = 1;
for (i = 0; i < codeLen; ++i) {
bit = decodeBit(prev, stats);
prev = (prev << 1) | bit;
}
return prev - (1 << codeLen);
}
void JArithmeticDecoder::byteIn() {
if (buf0 == 0xff) {
if (buf1 > 0x8f) {
if (limitStream) {
buf0 = buf1;
buf1 = readByte();
c = c + 0xff00 - (buf0 << 8);
}
ct = 8;
} else {
buf0 = buf1;
buf1 = readByte();
c = c + 0xfe00 - (buf0 << 9);
ct = 7;
}
} else {
buf0 = buf1;
buf1 = readByte();
c = c + 0xff00 - (buf0 << 8);
ct = 8;
}
}