X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=pdf2swf%2Fxpdf%2FJArithmeticDecoder.cc;fp=pdf2swf%2Fxpdf%2FJArithmeticDecoder.cc;h=fd297445b278ba8fb276fb7f7b8c71682241304f;hb=c7432833fe3a6469d63fad135151a92e12877b94;hp=0000000000000000000000000000000000000000;hpb=b9ddd4a2ed601bc01ddacc69d2522687a93a94ce;p=swftools.git diff --git a/pdf2swf/xpdf/JArithmeticDecoder.cc b/pdf2swf/xpdf/JArithmeticDecoder.cc new file mode 100644 index 0000000..fd29744 --- /dev/null +++ b/pdf2swf/xpdf/JArithmeticDecoder.cc @@ -0,0 +1,300 @@ +//======================================================================== +// +// JArithmeticDecoder.cc +// +// Copyright 2002-2004 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#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; + } +}