You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
300 lines
6.6 KiB
300 lines
6.6 KiB
//======================================================================== |
|
// |
|
// JArithmeticDecoder.cc |
|
// |
|
// Copyright 2002-2004 Glyph & Cog, LLC |
|
// |
|
//======================================================================== |
|
|
|
#include <aconf.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 *)gmalloc(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; |
|
} |
|
|
|
JArithmeticDecoder::~JArithmeticDecoder() { |
|
while (dataLen > 0) { |
|
readByte(); |
|
} |
|
} |
|
|
|
inline Guint JArithmeticDecoder::readByte() { |
|
if (dataLen == 0) { |
|
return 0xff; |
|
} |
|
if (dataLen > 0) { |
|
--dataLen; |
|
} |
|
return (Guint)str->getChar() & 0xff; |
|
} |
|
|
|
void JArithmeticDecoder::start() { |
|
buf0 = readByte(); |
|
buf1 = readByte(); |
|
|
|
// INITDEC |
|
c = (buf0 ^ 0xff) << 16; |
|
byteIn(); |
|
c <<= 7; |
|
ct -= 7; |
|
a = 0x80000000; |
|
} |
|
|
|
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) { |
|
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; |
|
} |
|
}
|
|
|