jbig2stream.cc

来自「source code: Covert TXT to PDF」· CC 代码 · 共 2,563 行 · 第 1/5 页

CC
2,563
字号
  {   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) {    //~ if buildTable removes the entries with prefixLen=0, this is unneeded    if (table[i].prefixLen > 0) {      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;}static int cmpHuffmanTabEntries(const void *p1, const void *p2) {  return ((JBIG2HuffmanTable *)p1)->prefixLen         - ((JBIG2HuffmanTable *)p2)->prefixLen;}//~ should remove entries with prefixLen = 0void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) {  Guint i, prefix;  qsort(table, len, sizeof(JBIG2HuffmanTable), &cmpHuffmanTabEntries);  for (i = 0; i < len && table[i].prefixLen == 0; ++i) {    table[i].prefix = 0;  }  prefix = 0;  table[i++].prefix = prefix++;  for (; i < len; ++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) {      if (bufLen <= 12) {	code = buf << (12 - bufLen);      } else {	code = buf >> (bufLen - 12);      }      p = &whiteTab1[code & 0x1f];    } else {      if (bufLen <= 9) {	code = buf << (9 - bufLen);      } else {	code = buf >> (bufLen - 9);      }      p = &whiteTab2[code & 0x1ff];    }    if (p->bits > 0 && p->bits < (int)bufLen) {      bufLen -= p->bits;      return p->n;    }    if (bufLen >= 12) {      break;    }    buf = (buf << 8) | (str->getChar() & 0xff);    bufLen += 8;    ++nBytesRead;  }  error(str->getPos(), "Bad white code in JBIG2 MMR stream");  // eat a bit and return a positive number so that the caller doesn't  // go into an infinite loop  --bufLen;  return 1;}int JBIG2MMRDecoder::getBlackCode() {  CCITTCode *p;  Guint code;  if (bufLen == 0) {    buf = str->getChar() & 0xff;    bufLen = 8;    ++nBytesRead;  }  while (1) {    if (bufLen > 6 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {      if (bufLen <= 13) {	code = buf << (13 - bufLen);      } else {	code = buf >> (bufLen - 13);      }      p = &blackTab1[code & 0x7f];    } else if (bufLen > 4 && ((buf >> (bufLen - 4)) & 0x0f) == 0) {      if (bufLen <= 12) {	code = buf << (12 - bufLen);      } else {	code = buf >> (bufLen - 12);      }      p = &blackTab2[(code & 0xff) - 64];    } else {      if (bufLen <= 6) {	code = buf << (6 - bufLen);      } else {	code = buf >> (bufLen - 6);      }      p = &blackTab3[code & 0x3f];    }    if (p->bits > 0 && p->bits < (int)bufLen) {      bufLen -= p->bits;      return p->n;    }    if (bufLen >= 13) {      break;    }    buf = (buf << 8) | (str->getChar() & 0xff);    bufLen += 8;    ++nBytesRead;  }  error(str->getPos(), "Bad black code in JBIG2 MMR stream");  // eat a bit and return a positive number so that the caller doesn't  // go into an infinite loop  --bufLen;  return 1;}Guint JBIG2MMRDecoder::get24Bits() {  while (bufLen < 24) {    buf = (buf << 8) | (str->getChar() & 0xff);    bufLen += 8;    ++nBytesRead;  }  return (buf >> (bufLen - 24)) & 0xffffff;}void JBIG2MMRDecoder::skipTo(Guint length) {  while (nBytesRead < length) {    str->getChar();    ++nBytesRead;  }}//------------------------------------------------------------------------// JBIG2Segment//------------------------------------------------------------------------enum JBIG2SegmentType {  jbig2SegBitmap,  jbig2SegSymbolDict,  jbig2SegPatternDict,  jbig2SegCodeTable};class JBIG2Segment {public:  JBIG2Segment(Guint segNumA) { segNum = segNumA; }  virtual ~JBIG2Segment() {}  void setSegNum(Guint segNumA) { segNum = segNumA; }  Guint getSegNum() { return segNum; }  virtual JBIG2SegmentType getType() = 0;private:  Guint segNum;};//------------------------------------------------------------------------// JBIG2Bitmap//------------------------------------------------------------------------class JBIG2Bitmap: public JBIG2Segment {public:  JBIG2Bitmap(Guint segNumA, int wA, int hA);  virtual ~JBIG2Bitmap();  virtual JBIG2SegmentType getType() { return jbig2SegBitmap; }  JBIG2Bitmap *copy() { return new JBIG2Bitmap(0, this); }  JBIG2Bitmap *getSlice(Guint x, Guint y, Guint wA, Guint hA);  void expand(int newH, Guint pixel);  void clearToZero();  void clearToOne();  int getWidth() { return w; }  int getHeight() { return h; }  int getPixel(int x, int y)    { return (x < 0 || x >= w || y < 0 || y >= h) ? 0 :             (data[y * line + (x >> 3)] >> (7 - (x & 7))) & 1; }  void setPixel(int x, int y)    { data[y * line + (x >> 3)] |= 1 << (7 - (x & 7)); }  void clearPixel(int x, int y)    { data[y * line + (x >> 3)] &= 0x7f7f >> (x & 7); }  void duplicateRow(int yDest, int ySrc);  void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp);  Guchar *getDataPtr() { return data; }  int getDataSize() { return h * line; }private:  JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap);  int w, h, line;  Guchar *data;};JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, int wA, int hA):  JBIG2Segment(segNumA){  w = wA;  h = hA;  line = (wA + 7) >> 3;  data = (Guchar *)gmalloc(h * line);}JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):  JBIG2Segment(segNumA){  w = bitmap->w;  h = bitmap->h;  line = bitmap->line;  data = (Guchar *)gmalloc(h * line);  memcpy(data, bitmap->data, h * line);}JBIG2Bitmap::~JBIG2Bitmap() {  gfree(data);}//~ optimize thisJBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) {  JBIG2Bitmap *slice;  Guint xx, yy;  slice = new JBIG2Bitmap(0, wA, hA);  slice->clearToZero();  for (yy = 0; yy < hA; ++yy) {    for (xx = 0; xx < wA; ++xx) {      if (getPixel(x + xx, y + yy)) {	slice->setPixel(xx, yy);      }    }  }  return slice;}void JBIG2Bitmap::expand(int newH, Guint pixel) {  if (newH <= h) {    return;  }  data = (Guchar *)grealloc(data, newH * line);  if (pixel) {    memset(data + h * line, 0xff, (newH - h) * line);  } else {    memset(data + h * line, 0x00, (newH - h) * line);  }  h = newH;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?