📄 jbig2stream.cc
字号:
//========================================================================//// JBIG2Stream.cc//// Copyright 2002-2003 Glyph & Cog, LLC////========================================================================#include <aconf.h>#ifdef USE_GCC_PRAGMAS#pragma implementation#endif#include <stdlib.h>#include <limits.h>#include "GList.h"#include "Error.h"#include "JArithmeticDecoder.h"#include "JBIG2Stream.h"//~ share these tables#include "Stream-CCITT.h"//------------------------------------------------------------------------static int contextSize[4] = { 16, 13, 10, 10 };static int refContextSize[2] = { 13, 10 };//------------------------------------------------------------------------// JBIG2HuffmanTable//------------------------------------------------------------------------#define jbig2HuffmanLOW 0xfffffffd#define jbig2HuffmanOOB 0xfffffffe#define jbig2HuffmanEOT 0xffffffffstruct JBIG2HuffmanTable { int val; Guint prefixLen; Guint rangeLen; // can also be LOW, OOB, or EOT Guint prefix;};JBIG2HuffmanTable huffTableA[] = { { 0, 1, 4, 0x000 }, { 16, 2, 8, 0x002 }, { 272, 3, 16, 0x006 }, { 65808, 3, 32, 0x007 }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableB[] = { { 0, 1, 0, 0x000 }, { 1, 2, 0, 0x002 }, { 2, 3, 0, 0x006 }, { 3, 4, 3, 0x00e }, { 11, 5, 6, 0x01e }, { 75, 6, 32, 0x03e }, { 0, 6, jbig2HuffmanOOB, 0x03f }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableC[] = { { 0, 1, 0, 0x000 }, { 1, 2, 0, 0x002 }, { 2, 3, 0, 0x006 }, { 3, 4, 3, 0x00e }, { 11, 5, 6, 0x01e }, { 0, 6, jbig2HuffmanOOB, 0x03e }, { 75, 7, 32, 0x0fe }, { -256, 8, 8, 0x0fe }, { -257, 8, jbig2HuffmanLOW, 0x0ff }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableD[] = { { 1, 1, 0, 0x000 }, { 2, 2, 0, 0x002 }, { 3, 3, 0, 0x006 }, { 4, 4, 3, 0x00e }, { 12, 5, 6, 0x01e }, { 76, 5, 32, 0x01f }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableE[] = { { 1, 1, 0, 0x000 }, { 2, 2, 0, 0x002 }, { 3, 3, 0, 0x006 }, { 4, 4, 3, 0x00e }, { 12, 5, 6, 0x01e }, { 76, 6, 32, 0x03e }, { -255, 7, 8, 0x07e }, { -256, 7, jbig2HuffmanLOW, 0x07f }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableF[] = { { 0, 2, 7, 0x000 }, { 128, 3, 7, 0x002 }, { 256, 3, 8, 0x003 }, { -1024, 4, 9, 0x008 }, { -512, 4, 8, 0x009 }, { -256, 4, 7, 0x00a }, { -32, 4, 5, 0x00b }, { 512, 4, 9, 0x00c }, { 1024, 4, 10, 0x00d }, { -2048, 5, 10, 0x01c }, { -128, 5, 6, 0x01d }, { -64, 5, 5, 0x01e }, { -2049, 6, jbig2HuffmanLOW, 0x03e }, { 2048, 6, 32, 0x03f }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableG[] = { { -512, 3, 8, 0x000 }, { 256, 3, 8, 0x001 }, { 512, 3, 9, 0x002 }, { 1024, 3, 10, 0x003 }, { -1024, 4, 9, 0x008 }, { -256, 4, 7, 0x009 }, { -32, 4, 5, 0x00a }, { 0, 4, 5, 0x00b }, { 128, 4, 7, 0x00c }, { -128, 5, 6, 0x01a }, { -64, 5, 5, 0x01b }, { 32, 5, 5, 0x01c }, { 64, 5, 6, 0x01d }, { -1025, 5, jbig2HuffmanLOW, 0x01e }, { 2048, 5, 32, 0x01f }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableH[] = { { 0, 2, 1, 0x000 }, { 0, 2, jbig2HuffmanOOB, 0x001 }, { 4, 3, 4, 0x004 }, { -1, 4, 0, 0x00a }, { 22, 4, 4, 0x00b }, { 38, 4, 5, 0x00c }, { 2, 5, 0, 0x01a }, { 70, 5, 6, 0x01b }, { 134, 5, 7, 0x01c }, { 3, 6, 0, 0x03a }, { 20, 6, 1, 0x03b }, { 262, 6, 7, 0x03c }, { 646, 6, 10, 0x03d }, { -2, 7, 0, 0x07c }, { 390, 7, 8, 0x07d }, { -15, 8, 3, 0x0fc }, { -5, 8, 1, 0x0fd }, { -7, 9, 1, 0x1fc }, { -3, 9, 0, 0x1fd }, { -16, 9, jbig2HuffmanLOW, 0x1fe }, { 1670, 9, 32, 0x1ff }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableI[] = { { 0, 2, jbig2HuffmanOOB, 0x000 }, { -1, 3, 1, 0x002 }, { 1, 3, 1, 0x003 }, { 7, 3, 5, 0x004 }, { -3, 4, 1, 0x00a }, { 43, 4, 5, 0x00b }, { 75, 4, 6, 0x00c }, { 3, 5, 1, 0x01a }, { 139, 5, 7, 0x01b }, { 267, 5, 8, 0x01c }, { 5, 6, 1, 0x03a }, { 39, 6, 2, 0x03b }, { 523, 6, 8, 0x03c }, { 1291, 6, 11, 0x03d }, { -5, 7, 1, 0x07c }, { 779, 7, 9, 0x07d }, { -31, 8, 4, 0x0fc }, { -11, 8, 2, 0x0fd }, { -15, 9, 2, 0x1fc }, { -7, 9, 1, 0x1fd }, { -32, 9, jbig2HuffmanLOW, 0x1fe }, { 3339, 9, 32, 0x1ff }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableJ[] = { { -2, 2, 2, 0x000 }, { 6, 2, 6, 0x001 }, { 0, 2, jbig2HuffmanOOB, 0x002 }, { -3, 5, 0, 0x018 }, { 2, 5, 0, 0x019 }, { 70, 5, 5, 0x01a }, { 3, 6, 0, 0x036 }, { 102, 6, 5, 0x037 }, { 134, 6, 6, 0x038 }, { 198, 6, 7, 0x039 }, { 326, 6, 8, 0x03a }, { 582, 6, 9, 0x03b }, { 1094, 6, 10, 0x03c }, { -21, 7, 4, 0x07a }, { -4, 7, 0, 0x07b }, { 4, 7, 0, 0x07c }, { 2118, 7, 11, 0x07d }, { -5, 8, 0, 0x0fc }, { 5, 8, 0, 0x0fd }, { -22, 8, jbig2HuffmanLOW, 0x0fe }, { 4166, 8, 32, 0x0ff }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableK[] = { { 1, 1, 0, 0x000 }, { 2, 2, 1, 0x002 }, { 4, 4, 0, 0x00c }, { 5, 4, 1, 0x00d }, { 7, 5, 1, 0x01c }, { 9, 5, 2, 0x01d }, { 13, 6, 2, 0x03c }, { 17, 7, 2, 0x07a }, { 21, 7, 3, 0x07b }, { 29, 7, 4, 0x07c }, { 45, 7, 5, 0x07d }, { 77, 7, 6, 0x07e }, { 141, 7, 32, 0x07f }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableL[] = { { 1, 1, 0, 0x000 }, { 2, 2, 0, 0x002 }, { 3, 3, 1, 0x006 }, { 5, 5, 0, 0x01c }, { 6, 5, 1, 0x01d }, { 8, 6, 1, 0x03c }, { 10, 7, 0, 0x07a }, { 11, 7, 1, 0x07b }, { 13, 7, 2, 0x07c }, { 17, 7, 3, 0x07d }, { 25, 7, 4, 0x07e }, { 41, 8, 5, 0x0fe }, { 73, 8, 32, 0x0ff }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableM[] = { { 1, 1, 0, 0x000 }, { 2, 3, 0, 0x004 }, { 7, 3, 3, 0x005 }, { 3, 4, 0, 0x00c }, { 5, 4, 1, 0x00d }, { 4, 5, 0, 0x01c }, { 15, 6, 1, 0x03a }, { 17, 6, 2, 0x03b }, { 21, 6, 3, 0x03c }, { 29, 6, 4, 0x03d }, { 45, 6, 5, 0x03e }, { 77, 7, 6, 0x07e }, { 141, 7, 32, 0x07f }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableN[] = { { 0, 1, 0, 0x000 }, { -2, 3, 0, 0x004 }, { -1, 3, 0, 0x005 }, { 1, 3, 0, 0x006 }, { 2, 3, 0, 0x007 }, { 0, 0, jbig2HuffmanEOT, 0 }};JBIG2HuffmanTable huffTableO[] = { { 0, 1, 0, 0x000 }, { -1, 3, 0, 0x004 }, { 1, 3, 0, 0x005 }, { -2, 4, 0, 0x00c }, { 2, 4, 0, 0x00d }, { -4, 5, 1, 0x01c }, { 3, 5, 1, 0x01d }, { -8, 6, 2, 0x03c }, { 5, 6, 2, 0x03d }, { -24, 7, 4, 0x07c }, { 9, 7, 4, 0x07d }, { -25, 7, jbig2HuffmanLOW, 0x07e }, { 25, 7, 32, 0x07f }, { 0, 0, jbig2HuffmanEOT, 0 }};//------------------------------------------------------------------------// JBIG2HuffmanDecoder//------------------------------------------------------------------------class JBIG2HuffmanDecoder {public: JBIG2HuffmanDecoder(); ~JBIG2HuffmanDecoder(); void setStream(Stream *strA) { str = strA; } void reset(); // Returns false for OOB, otherwise sets *<x> and returns true. GBool decodeInt(int *x, JBIG2HuffmanTable *table); Guint readBits(Guint n); Guint readBit(); // Sort the table by prefix length and assign prefix values. void buildTable(JBIG2HuffmanTable *table, Guint len);private: Stream *str; Guint buf; Guint bufLen;};JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() { str = NULL; reset();}JBIG2HuffmanDecoder::~JBIG2HuffmanDecoder() {}void JBIG2HuffmanDecoder::reset() { buf = 0; bufLen = 0;}//~ optimize thisGBool JBIG2HuffmanDecoder::decodeInt(int *x, JBIG2HuffmanTable *table) { Guint i, len, prefix; i = 0; len = 0; prefix = 0; while (table[i].rangeLen != jbig2HuffmanEOT) { while (len < table[i].prefixLen) { prefix = (prefix << 1) | readBit(); ++len; } if (prefix == table[i].prefix) { if (table[i].rangeLen == jbig2HuffmanOOB) { return gFalse; } if (table[i].rangeLen == jbig2HuffmanLOW) { *x = table[i].val - readBits(32); } else if (table[i].rangeLen > 0) { *x = table[i].val + readBits(table[i].rangeLen); } else { *x = table[i].val; } return gTrue; } ++i; } return gFalse;}Guint JBIG2HuffmanDecoder::readBits(Guint n) { Guint x, mask, nLeft; mask = (n == 32) ? 0xffffffff : ((1 << n) - 1); if (bufLen >= n) { x = (buf >> (bufLen - n)) & mask; bufLen -= n; } else { x = buf & ((1 << bufLen) - 1); nLeft = n - bufLen; bufLen = 0; while (nLeft >= 8) { x = (x << 8) | (str->getChar() & 0xff); nLeft -= 8; } if (nLeft > 0) { buf = str->getChar(); bufLen = 8 - nLeft; x = (x << nLeft) | ((buf >> bufLen) & ((1 << nLeft) - 1)); } } return x;}Guint JBIG2HuffmanDecoder::readBit() { if (bufLen == 0) { buf = str->getChar(); bufLen = 8; } --bufLen; return (buf >> bufLen) & 1;}void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) { Guint i, j, k, prefix; JBIG2HuffmanTable tab; // stable selection sort: // - entries with prefixLen > 0, in ascending prefixLen order // - entry with prefixLen = 0, rangeLen = EOT // - all other entries with prefixLen = 0 // (on entry, table[len] has prefixLen = 0, rangeLen = EOT) for (i = 0; i < len; ++i) { for (j = i; j < len && table[j].prefixLen == 0; ++j) ; if (j == len) { break; } for (k = j + 1; k < len; ++k) { if (table[k].prefixLen > 0 && table[k].prefixLen < table[j].prefixLen) { j = k; } } if (j != i) { tab = table[j]; for (k = j; k > i; --k) { table[k] = table[k - 1]; } table[i] = tab; } } table[i] = table[len]; // assign prefixes i = 0; prefix = 0; table[i++].prefix = prefix++; for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) { prefix <<= table[i].prefixLen - table[i-1].prefixLen; table[i].prefix = prefix++; }}//------------------------------------------------------------------------// JBIG2MMRDecoder//------------------------------------------------------------------------class JBIG2MMRDecoder {public: JBIG2MMRDecoder(); ~JBIG2MMRDecoder(); void setStream(Stream *strA) { str = strA; } void reset(); int get2DCode(); int getBlackCode(); int getWhiteCode(); Guint get24Bits(); void skipTo(Guint length);private: Stream *str; Guint buf; Guint bufLen; Guint nBytesRead;};JBIG2MMRDecoder::JBIG2MMRDecoder() { str = NULL; reset();}JBIG2MMRDecoder::~JBIG2MMRDecoder() {}void JBIG2MMRDecoder::reset() { buf = 0; bufLen = 0; nBytesRead = 0;}int JBIG2MMRDecoder::get2DCode() { CCITTCode *p; if (bufLen == 0) { buf = str->getChar() & 0xff; bufLen = 8; ++nBytesRead; p = &twoDimTab1[(buf >> 1) & 0x7f]; } else if (bufLen == 8) { p = &twoDimTab1[(buf >> 1) & 0x7f]; } else { p = &twoDimTab1[(buf << (7 - bufLen)) & 0x7f]; if (p->bits < 0 || p->bits > (int)bufLen) { buf = (buf << 8) | (str->getChar() & 0xff); bufLen += 8; ++nBytesRead; p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f]; } } if (p->bits < 0) { error(str->getPos(), "Bad two dim code in JBIG2 MMR stream"); return 0; } bufLen -= p->bits; return p->n;}int JBIG2MMRDecoder::getWhiteCode() { CCITTCode *p; Guint code; if (bufLen == 0) { buf = str->getChar() & 0xff; bufLen = 8; ++nBytesRead; } while (1) { if (bufLen >= 7 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -