//========================================================================
//
// JBIG2Stream.cc
//
// Copyright 2002-2003 Glyph & Cog, LLC
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2006 Raj Kumar <rkumar@archive.org>
// Copyright (C) 2006 Paul Walmsley <paul@booyaka.com>
// Copyright (C) 2006-2009 Albert Astals Cid <aacid@kde.org>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#include <config.h>

#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif

#include <stdlib.h>
#include <limits.h>
#include "goo/GooList.h"
#include "Error.h"
#include "JArithmeticDecoder.h"
#include "JBIG2Stream.h"

//~ share these tables
#include "Stream-CCITT.h"

//------------------------------------------------------------------------

static const int contextSize[4] = { 16, 13, 10, 10 };
static const int refContextSize[2] = { 13, 10 };

//------------------------------------------------------------------------
// JBIG2HuffmanTable
//------------------------------------------------------------------------

#define jbig2HuffmanLOW 0xfffffffd
#define jbig2HuffmanOOB 0xfffffffe
#define jbig2HuffmanEOT 0xffffffff

struct JBIG2HuffmanTable {
  int val;
  Guint prefixLen;
  Guint rangeLen;		// can also be LOW, OOB, or EOT
  Guint prefix;
};

static JBIG2HuffmanTable huffTableA[] = {
  {     0, 1,  4,              0x000 },
  {    16, 2,  8,              0x002 },
  {   272, 3, 16,              0x006 },
  { 65808, 3, 32,              0x007 },
  {     0, 0, jbig2HuffmanEOT, 0     }
};

static 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     }
};

static 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     }
};

static 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     }
};

static 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     }
};

static 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     }
};

static 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     }
};

static 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     }
};

static 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     }
};

static 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     }
};

static 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     }
};

static 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     }
};

static 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     }
};

static 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     }
};

static 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 this
GBool 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() {
  const 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() {
  const CCITTCode *p;
  Guint code;

  if (bufLen == 0) {
    buf = str->getChar() & 0xff;
    bufLen = 8;
    ++nBytesRead;
  }
  while (1) {
    if (bufLen >= 11 && ((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() {
  const CCITTCode *p;
  Guint code;

  if (bufLen == 0) {
    buf = str->getChar() & 0xff;
    bufLen = 8;
    ++nBytesRead;
  }
  while (1) {
    if (bufLen >= 10 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
      if (bufLen <= 13) {
	code = buf << (13 - bufLen);
      } else {
	code = buf >> (bufLen - 13);
      }
      p = &blackTab1[code & 0x7f];
    } else if (bufLen >= 7 && ((buf >> (bufLen - 4)) & 0x0f) == 0 &&
	       ((buf >> (bufLen - 6)) & 0x03) != 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
//------------------------------------------------------------------------

struct JBIG2BitmapPtr {
  Guchar *p;
  int shift;
  int x;
};

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 getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr);
  int nextPixel(JBIG2BitmapPtr *ptr);
  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;

  if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
    error(-1, "invalid width/height");
    data = NULL;
    return;
  }
  // need to allocate one extra guard byte for use in combine()
  data = (Guchar *)gmalloc(h * line + 1);
  data[h * line] = 0;
}

JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):
  JBIG2Segment(segNumA)
{
  w = bitmap->w;
  h = bitmap->h;
  line = bitmap->line;

  if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
    error(-1, "invalid width/height");
    data = NULL;
    return;
  }
  // need to allocate one extra guard byte for use in combine()
  data = (Guchar *)gmalloc(h * line + 1);
  memcpy(data, bitmap->data, h * line);
  data[h * line] = 0;
}

JBIG2Bitmap::~JBIG2Bitmap() {
  gfree(data);
}

//~ optimize this
JBIG2Bitmap *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 || line <= 0 || newH >= (INT_MAX - 1) / line) {
    error(-1, "invalid width/height");
    gfree(data);
    data = NULL;
    return;
  }
  // need to allocate one extra guard byte for use in combine()
  data = (Guchar *)grealloc(data, newH * line + 1);
  if (pixel) {
    memset(data + h * line, 0xff, (newH - h) * line);
  } else {
    memset(data + h * line, 0x00, (newH - h) * line);
  }
  h = newH;
  data[h * line] = 0;
}

void JBIG2Bitmap::clearToZero() {
  memset(data, 0, h * line);
}

void JBIG2Bitmap::clearToOne() {
  memset(data, 0xff, h * line);
}

inline void JBIG2Bitmap::getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr) {
  if (y < 0 || y >= h || x >= w) {
    ptr->p = NULL;
  } else if (x < 0) {
    ptr->p = &data[y * line];
    ptr->shift = 7;
    ptr->x = x;
  } else {
    ptr->p = &data[y * line + (x >> 3)];
    ptr->shift = 7 - (x & 7);
    ptr->x = x;
  }
}

inline int JBIG2Bitmap::nextPixel(JBIG2BitmapPtr *ptr) {
  int pix;

  if (!ptr->p) {
    pix = 0;
  } else if (ptr->x < 0) {
    ++ptr->x;
    pix = 0;
  } else {
    pix = (*ptr->p >> ptr->shift) & 1;
    if (++ptr->x == w) {
      ptr->p = NULL;
    } else if (ptr->shift == 0) {
      ++ptr->p;
      ptr->shift = 7;
    } else {
      --ptr->shift;
    }
  }
  return pix;
}

void JBIG2Bitmap::duplicateRow(int yDest, int ySrc) {
  memcpy(data + yDest * line, data + ySrc * line, line);
}

void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y,
			  Guint combOp) {
  int x0, x1, y0, y1, xx, yy;
  Guchar *srcPtr, *destPtr;
  Guint src0, src1, src, dest, s1, s2, m1, m2, m3;
  GBool oneByte;

  if (y < 0) {
    y0 = -y;
  } else {
    y0 = 0;
  }
  if (y + bitmap->h > h) {
    y1 = h - y;
  } else {
    y1 = bitmap->h;
  }
  if (y0 >= y1) {
    return;
  }

  if (x >= 0) {
    x0 = x & ~7;
  } else {
    x0 = 0;
  }
  x1 = x + bitmap->w;
  if (x1 > w) {
    x1 = w;
  }
  if (x0 >= x1) {
    return;
  }

  s1 = x & 7;
  s2 = 8 - s1;
  m1 = 0xff >> (x1 & 7);
  m2 = 0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7));
  m3 = (0xff >> s1) & m2;

  oneByte = x0 == ((x1 - 1) & ~7);

  for (yy = y0; yy < y1; ++yy) {

    // one byte per line -- need to mask both left and right side
    if (oneByte) {
      if (x >= 0) {
	destPtr = data + (y + yy) * line + (x >> 3);
	srcPtr = bitmap->data + yy * bitmap->line;
	dest = *destPtr;
	src1 = *srcPtr;
	switch (combOp) {
	case 0: // or
	  dest |= (src1 >> s1) & m2;
	  break;
	case 1: // and
	  dest &= ((0xff00 | src1) >> s1) | m1;
	  break;
	case 2: // xor
	  dest ^= (src1 >> s1) & m2;
	  break;
	case 3: // xnor
	  dest ^= ((src1 ^ 0xff) >> s1) & m2;
	  break;
	case 4: // replace
	  dest = (dest & ~m3) | ((src1 >> s1) & m3);
	  break;
	}
	*destPtr = dest;
      } else {
	destPtr = data + (y + yy) * line;
	srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
	dest = *destPtr;
	src1 = *srcPtr;
	switch (combOp) {
	case 0: // or
	  dest |= src1 & m2;
	  break;
	case 1: // and
	  dest &= src1 | m1;
	  break;
	case 2: // xor
	  dest ^= src1 & m2;
	  break;
	case 3: // xnor
	  dest ^= (src1 ^ 0xff) & m2;
	  break;
	case 4: // replace
	  dest = (src1 & m2) | (dest & m1);
	  break;
	}
	*destPtr = dest;
      }

    // multiple bytes per line -- need to mask left side of left-most
    // byte and right side of right-most byte
    } else {

      // left-most byte
      if (x >= 0) {
	destPtr = data + (y + yy) * line + (x >> 3);
	srcPtr = bitmap->data + yy * bitmap->line;
	src1 = *srcPtr++;
	dest = *destPtr;
	switch (combOp) {
	case 0: // or
	  dest |= src1 >> s1;
	  break;
	case 1: // and
	  dest &= (0xff00 | src1) >> s1;
	  break;
	case 2: // xor
	  dest ^= src1 >> s1;
	  break;
	case 3: // xnor
	  dest ^= (src1 ^ 0xff) >> s1;
	  break;
	case 4: // replace
	  dest = (dest & (0xff << s2)) | (src1 >> s1);
	  break;
	}
	*destPtr++ = dest;
	xx = x0 + 8;
      } else {
	destPtr = data + (y + yy) * line;
	srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
	src1 = *srcPtr++;
	xx = x0;
      }

      // middle bytes
      for (; xx < x1 - 8; xx += 8) {
	dest = *destPtr;
	src0 = src1;
	src1 = *srcPtr++;
	src = (((src0 << 8) | src1) >> s1) & 0xff;
	switch (combOp) {
	case 0: // or
	  dest |= src;
	  break;
	case 1: // and
	  dest &= src;
	  break;
	case 2: // xor
	  dest ^= src;
	  break;
	case 3: // xnor
	  dest ^= src ^ 0xff;
	  break;
	case 4: // replace
	  dest = src;
	  break;
	}
	*destPtr++ = dest;
      }

      // right-most byte
      // note: this last byte (src1) may not actually be used, depending
      // on the values of s1, m1, and m2 - and in fact, it may be off
      // the edge of the source bitmap, which means we need to allocate
      // one extra guard byte at the end of each bitmap
      dest = *destPtr;
      src0 = src1;
      src1 = *srcPtr++;
      src = (((src0 << 8) | src1) >> s1) & 0xff;
      switch (combOp) {
      case 0: // or
	dest |= src & m2;
	break;
      case 1: // and
	dest &= src | m1;
	break;
      case 2: // xor
	dest ^= src & m2;
	break;
      case 3: // xnor
	dest ^= (src ^ 0xff) & m2;
	break;
      case 4: // replace
	dest = (src & m2) | (dest & m1);
	break;
      }
      *destPtr = dest;
    }
  }
}

//------------------------------------------------------------------------
// JBIG2SymbolDict
//------------------------------------------------------------------------

class JBIG2SymbolDict: public JBIG2Segment {
public:

  JBIG2SymbolDict(Guint segNumA, Guint sizeA);
  virtual ~JBIG2SymbolDict();
  virtual JBIG2SegmentType getType() { return jbig2SegSymbolDict; }
  Guint getSize() { return size; }
  void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
  JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
  void setGenericRegionStats(JArithmeticDecoderStats *stats)
    { genericRegionStats = stats; }
  void setRefinementRegionStats(JArithmeticDecoderStats *stats)
    { refinementRegionStats = stats; }
  JArithmeticDecoderStats *getGenericRegionStats()
    { return genericRegionStats; }
  JArithmeticDecoderStats *getRefinementRegionStats()
    { return refinementRegionStats; }

private:

  Guint size;
  JBIG2Bitmap **bitmaps;
  JArithmeticDecoderStats *genericRegionStats;
  JArithmeticDecoderStats *refinementRegionStats;
};

JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
  JBIG2Segment(segNumA)
{
  size = sizeA;
  bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
  genericRegionStats = NULL;
  refinementRegionStats = NULL;
}

JBIG2SymbolDict::~JBIG2SymbolDict() {
  Guint i;

  for (i = 0; i < size; ++i) {
    delete bitmaps[i];
  }
  gfree(bitmaps);
  if (genericRegionStats) {
    delete genericRegionStats;
  }
  if (refinementRegionStats) {
    delete refinementRegionStats;
  }
}

//------------------------------------------------------------------------
// JBIG2PatternDict
//------------------------------------------------------------------------

class JBIG2PatternDict: public JBIG2Segment {
public:

  JBIG2PatternDict(Guint segNumA, Guint sizeA);
  virtual ~JBIG2PatternDict();
  virtual JBIG2SegmentType getType() { return jbig2SegPatternDict; }
  Guint getSize() { return size; }
  void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
  JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }

private:

  Guint size;
  JBIG2Bitmap **bitmaps;
};

JBIG2PatternDict::JBIG2PatternDict(Guint segNumA, Guint sizeA):
  JBIG2Segment(segNumA)
{
  size = sizeA;
  bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
}

JBIG2PatternDict::~JBIG2PatternDict() {
  Guint i;

  for (i = 0; i < size; ++i) {
    delete bitmaps[i];
  }
  gfree(bitmaps);
}

//------------------------------------------------------------------------
// JBIG2CodeTable
//------------------------------------------------------------------------

class JBIG2CodeTable: public JBIG2Segment {
public:

  JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA);
  virtual ~JBIG2CodeTable();
  virtual JBIG2SegmentType getType() { return jbig2SegCodeTable; }
  JBIG2HuffmanTable *getHuffTable() { return table; }

private:

  JBIG2HuffmanTable *table;
};

JBIG2CodeTable::JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA):
  JBIG2Segment(segNumA)
{
  table = tableA;
}

JBIG2CodeTable::~JBIG2CodeTable() {
  gfree(table);
}

//------------------------------------------------------------------------
// JBIG2Stream
//------------------------------------------------------------------------

JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStreamA):
  FilterStream(strA)
{
  pageBitmap = NULL;

  arithDecoder = new JArithmeticDecoder();
  genericRegionStats = new JArithmeticDecoderStats(1 << 1);
  refinementRegionStats = new JArithmeticDecoderStats(1 << 1);
  iadhStats = new JArithmeticDecoderStats(1 << 9);
  iadwStats = new JArithmeticDecoderStats(1 << 9);
  iaexStats = new JArithmeticDecoderStats(1 << 9);
  iaaiStats = new JArithmeticDecoderStats(1 << 9);
  iadtStats = new JArithmeticDecoderStats(1 << 9);
  iaitStats = new JArithmeticDecoderStats(1 << 9);
  iafsStats = new JArithmeticDecoderStats(1 << 9);
  iadsStats = new JArithmeticDecoderStats(1 << 9);
  iardxStats = new JArithmeticDecoderStats(1 << 9);
  iardyStats = new JArithmeticDecoderStats(1 << 9);
  iardwStats = new JArithmeticDecoderStats(1 << 9);
  iardhStats = new JArithmeticDecoderStats(1 << 9);
  iariStats = new JArithmeticDecoderStats(1 << 9);
  iaidStats = new JArithmeticDecoderStats(1 << 1);
  huffDecoder = new JBIG2HuffmanDecoder();
  mmrDecoder = new JBIG2MMRDecoder();

  globalsStreamA->copy(&globalsStream);
  segments = globalSegments = NULL;
  curStr = NULL;
  dataPtr = dataEnd = NULL;
}

JBIG2Stream::~JBIG2Stream() {
  close();
  globalsStream.free();
  delete arithDecoder;
  delete genericRegionStats;
  delete refinementRegionStats;
  delete iadhStats;
  delete iadwStats;
  delete iaexStats;
  delete iaaiStats;
  delete iadtStats;
  delete iaitStats;
  delete iafsStats;
  delete iadsStats;
  delete iardxStats;
  delete iardyStats;
  delete iardwStats;
  delete iardhStats;
  delete iariStats;
  delete iaidStats;
  delete huffDecoder;
  delete mmrDecoder;
  delete str;
}

void JBIG2Stream::reset() {
  // read the globals stream
  globalSegments = new GooList();
  if (globalsStream.isStream()) {
    segments = globalSegments;
    curStr = globalsStream.getStream();
    curStr->reset();
    arithDecoder->setStream(curStr);
    huffDecoder->setStream(curStr);
    mmrDecoder->setStream(curStr);
    readSegments();
    curStr->close();
  }

  // read the main stream
  segments = new GooList();
  curStr = str;
  curStr->reset();
  arithDecoder->setStream(curStr);
  huffDecoder->setStream(curStr);
  mmrDecoder->setStream(curStr);
  readSegments();

  if (pageBitmap) {
    dataPtr = pageBitmap->getDataPtr();
    dataEnd = dataPtr + pageBitmap->getDataSize();
  } else {
    dataPtr = dataEnd = NULL;
  }
}

void JBIG2Stream::close() {
  if (pageBitmap) {
    delete pageBitmap;
    pageBitmap = NULL;
  }
  if (segments) {
    deleteGooList(segments, JBIG2Segment);
    segments = NULL;
  }
  if (globalSegments) {
    deleteGooList(globalSegments, JBIG2Segment);
    globalSegments = NULL;
  }
  dataPtr = dataEnd = NULL;
  FilterStream::close();
}

int JBIG2Stream::getChar() {
  if (dataPtr && dataPtr < dataEnd) {
    return (*dataPtr++ ^ 0xff) & 0xff;
  }
  return EOF;
}

int JBIG2Stream::lookChar() {
  if (dataPtr && dataPtr < dataEnd) {
    return (*dataPtr ^ 0xff) & 0xff;
  }
  return EOF;
}

GooString *JBIG2Stream::getPSFilter(int psLevel, char *indent) {
  return NULL;
}

GBool JBIG2Stream::isBinary(GBool last) {
  return str->isBinary(gTrue);
}

void JBIG2Stream::readSegments() {
  Guint segNum, segFlags, segType, page, segLength;
  Guint refFlags, nRefSegs;
  Guint *refSegs;
  int segDataPos;
  int c1, c2, c3;
  Guint i;

  while (readULong(&segNum)) {

    // segment header flags
    if (!readUByte(&segFlags)) {
      goto eofError1;
    }
    segType = segFlags & 0x3f;

    // referred-to segment count and retention flags
    if (!readUByte(&refFlags)) {
      goto eofError1;
    }
    nRefSegs = refFlags >> 5;
    if (nRefSegs == 7) {
      if ((c1 = curStr->getChar()) == EOF ||
	  (c2 = curStr->getChar()) == EOF ||
	  (c3 = curStr->getChar()) == EOF) {
	goto eofError1;
      }
      refFlags = (refFlags << 24) | (c1 << 16) | (c2 << 8) | c3;
      nRefSegs = refFlags & 0x1fffffff;
      for (i = 0; i < (nRefSegs + 9) >> 3; ++i) {
	c1 = curStr->getChar();
      }
    }

    // referred-to segment numbers
    refSegs = (Guint *)gmallocn(nRefSegs, sizeof(Guint));
    if (segNum <= 256) {
      for (i = 0; i < nRefSegs; ++i) {
	if (!readUByte(&refSegs[i])) {
	  goto eofError2;
	}
      }
    } else if (segNum <= 65536) {
      for (i = 0; i < nRefSegs; ++i) {
	if (!readUWord(&refSegs[i])) {
	  goto eofError2;
	}
      }
    } else {
      for (i = 0; i < nRefSegs; ++i) {
	if (!readULong(&refSegs[i])) {
	  goto eofError2;
	}
      }
    }

    // segment page association
    if (segFlags & 0x40) {
      if (!readULong(&page)) {
	goto eofError2;
      }
    } else {
      if (!readUByte(&page)) {
	goto eofError2;
      }
    }

    // segment data length
    if (!readULong(&segLength)) {
      goto eofError2;
    }

    // keep track of the start of the segment data 
    segDataPos = getPos();

    // read the segment data
    switch (segType) {
    case 0:
      if (!readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs)) {
	goto syntaxError;
      }
      break;
    case 4:
      readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs);
      break;
    case 6:
      readTextRegionSeg(segNum, gTrue, gFalse, segLength, refSegs, nRefSegs);
      break;
    case 7:
      readTextRegionSeg(segNum, gTrue, gTrue, segLength, refSegs, nRefSegs);
      break;
    case 16:
      readPatternDictSeg(segNum, segLength);
      break;
    case 20:
      readHalftoneRegionSeg(segNum, gFalse, gFalse, segLength,
			    refSegs, nRefSegs);
      break;
    case 22:
      readHalftoneRegionSeg(segNum, gTrue, gFalse, segLength,
			    refSegs, nRefSegs);
      break;
    case 23:
      readHalftoneRegionSeg(segNum, gTrue, gTrue, segLength,
			    refSegs, nRefSegs);
      break;
    case 36:
      readGenericRegionSeg(segNum, gFalse, gFalse, segLength);
      break;
    case 38:
      readGenericRegionSeg(segNum, gTrue, gFalse, segLength);
      break;
    case 39:
      readGenericRegionSeg(segNum, gTrue, gTrue, segLength);
      break;
    case 40:
      readGenericRefinementRegionSeg(segNum, gFalse, gFalse, segLength,
				     refSegs, nRefSegs);
      break;
    case 42:
      readGenericRefinementRegionSeg(segNum, gTrue, gFalse, segLength,
				     refSegs, nRefSegs);
      break;
    case 43:
      readGenericRefinementRegionSeg(segNum, gTrue, gTrue, segLength,
				     refSegs, nRefSegs);
      break;
    case 48:
      readPageInfoSeg(segLength);
      break;
    case 50:
      readEndOfStripeSeg(segLength);
      break;
    case 52:
      readProfilesSeg(segLength);
      break;
    case 53:
      readCodeTableSeg(segNum, segLength);
      break;
    case 62:
      readExtensionSeg(segLength);
      break;
    default:
      error(getPos(), "Unknown segment type in JBIG2 stream");
      for (i = 0; i < segLength; ++i) {
	if ((c1 = curStr->getChar()) == EOF) {
	  goto eofError2;
	}
      }
      break;
    }

    // Make sure the segment handler read all of the bytes in the 
    // segment data, unless this segment is marked as having an
    // unknown length (section 7.2.7 of the JBIG2 Final Committee Draft)

    if (segLength != 0xffffffff) {

      int segExtraBytes = segDataPos + segLength - getPos();
      if (segExtraBytes > 0) {

	// If we didn't read all of the bytes in the segment data,
	// indicate an error, and throw away the rest of the data.
	
	// v.3.1.01.13 of the LuraTech PDF Compressor Server will
	// sometimes generate an extraneous NULL byte at the end of
	// arithmetic-coded symbol dictionary segments when numNewSyms
	// == 0.  Segments like this often occur for blank pages.
	
	error(getPos(), "%d extraneous byte%s after segment",
	      segExtraBytes, (segExtraBytes > 1) ? "s" : "");
	
	// Burn through the remaining bytes -- inefficient, but
	// hopefully we're not doing this much
	
	int trash;
	for (int i = segExtraBytes; i > 0; i--) {
	  readByte(&trash);
	}
	
      } else if (segExtraBytes < 0) {
	
	// If we read more bytes than we should have, according to the 
	// segment length field, note an error.
	
	error(getPos(), "Previous segment handler read too many bytes");
	
      }

    }
    
    gfree(refSegs);
  }

  return;

 syntaxError:
  gfree(refSegs);
  return;

 eofError2:
  gfree(refSegs);
 eofError1:
  error(getPos(), "Unexpected EOF in JBIG2 stream");
}

GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
				     Guint *refSegs, Guint nRefSegs) {
  JBIG2SymbolDict *symbolDict;
  JBIG2HuffmanTable *huffDHTable, *huffDWTable;
  JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable;
  JBIG2Segment *seg;
  GooList *codeTables;
  JBIG2SymbolDict *inputSymbolDict;
  Guint flags, sdTemplate, sdrTemplate, huff, refAgg;
  Guint huffDH, huffDW, huffBMSize, huffAggInst;
  Guint contextUsed, contextRetained;
  int sdATX[4], sdATY[4], sdrATX[2], sdrATY[2];
  Guint numExSyms, numNewSyms, numInputSyms, symCodeLen;
  JBIG2Bitmap **bitmaps;
  JBIG2Bitmap *collBitmap, *refBitmap;
  Guint *symWidths;
  Guint symHeight, symWidth, totalWidth, x, symID;
  int dh, dw, refAggNum, refDX, refDY, bmSize;
  GBool ex;
  int run, cnt;
  Guint i, j, k;
  Guchar *p;

  // symbol dictionary flags
  if (!readUWord(&flags)) {
    goto eofError;
  }
  sdTemplate = (flags >> 10) & 3;
  sdrTemplate = (flags >> 12) & 1;
  huff = flags & 1;
  refAgg = (flags >> 1) & 1;
  huffDH = (flags >> 2) & 3;
  huffDW = (flags >> 4) & 3;
  huffBMSize = (flags >> 6) & 1;
  huffAggInst = (flags >> 7) & 1;
  contextUsed = (flags >> 8) & 1;
  contextRetained = (flags >> 9) & 1;

  // symbol dictionary AT flags
  if (!huff) {
    if (sdTemplate == 0) {
      if (!readByte(&sdATX[0]) ||
	  !readByte(&sdATY[0]) ||
	  !readByte(&sdATX[1]) ||
	  !readByte(&sdATY[1]) ||
	  !readByte(&sdATX[2]) ||
	  !readByte(&sdATY[2]) ||
	  !readByte(&sdATX[3]) ||
	  !readByte(&sdATY[3])) {
	goto eofError;
      }
    } else {
      if (!readByte(&sdATX[0]) ||
	  !readByte(&sdATY[0])) {
	goto eofError;
      }
    }
  }

  // symbol dictionary refinement AT flags
  if (refAgg && !sdrTemplate) {
    if (!readByte(&sdrATX[0]) ||
	!readByte(&sdrATY[0]) ||
	!readByte(&sdrATX[1]) ||
	!readByte(&sdrATY[1])) {
      goto eofError;
    }
  }

  // SDNUMEXSYMS and SDNUMNEWSYMS
  if (!readULong(&numExSyms) || !readULong(&numNewSyms)) {
    goto eofError;
  }

  // get referenced segments: input symbol dictionaries and code tables
  codeTables = new GooList();
  numInputSyms = 0;
  for (i = 0; i < nRefSegs; ++i) {
    // This is need by bug 12014, returning gFalse makes it not crash
    // but we end up with a empty page while acroread is able to render
    // part of it
    if ((seg = findSegment(refSegs[i]))) {
      if (seg->getType() == jbig2SegSymbolDict) {
        numInputSyms += ((JBIG2SymbolDict *)seg)->getSize();
      } else if (seg->getType() == jbig2SegCodeTable) {
        codeTables->append(seg);
      }
    } else {
      delete codeTables;
      return gFalse;
    }
  }

  // compute symbol code length
  symCodeLen = 0;
  i = 1;
  while (i < numInputSyms + numNewSyms) {
    ++symCodeLen;
    i <<= 1;
  }

  // get the input symbol bitmaps
  bitmaps = (JBIG2Bitmap **)gmallocn(numInputSyms + numNewSyms,
				     sizeof(JBIG2Bitmap *));
  for (i = 0; i < numInputSyms + numNewSyms; ++i) {
    bitmaps[i] = NULL;
  }
  k = 0;
  inputSymbolDict = NULL;
  for (i = 0; i < nRefSegs; ++i) {
    seg = findSegment(refSegs[i]);
    if (seg != NULL && seg->getType() == jbig2SegSymbolDict) {
      inputSymbolDict = (JBIG2SymbolDict *)seg;
      for (j = 0; j < inputSymbolDict->getSize(); ++j) {
	bitmaps[k++] = inputSymbolDict->getBitmap(j);
      }
    }
  }

  // get the Huffman tables
  huffDHTable = huffDWTable = NULL; // make gcc happy
  huffBMSizeTable = huffAggInstTable = NULL; // make gcc happy
  i = 0;
  if (huff) {
    if (huffDH == 0) {
      huffDHTable = huffTableD;
    } else if (huffDH == 1) {
      huffDHTable = huffTableE;
    } else {
      huffDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
    }
    if (huffDW == 0) {
      huffDWTable = huffTableB;
    } else if (huffDW == 1) {
      huffDWTable = huffTableC;
    } else {
      huffDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
    }
    if (huffBMSize == 0) {
      huffBMSizeTable = huffTableA;
    } else {
      huffBMSizeTable =
	  ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
    }
    if (huffAggInst == 0) {
      huffAggInstTable = huffTableA;
    } else {
      huffAggInstTable =
	  ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
    }
  }
  delete codeTables;

  // set up the Huffman decoder
  if (huff) {
    huffDecoder->reset();

  // set up the arithmetic decoder
  } else {
    if (contextUsed && inputSymbolDict) {
      resetGenericStats(sdTemplate, inputSymbolDict->getGenericRegionStats());
    } else {
      resetGenericStats(sdTemplate, NULL);
    }
    resetIntStats(symCodeLen);
    arithDecoder->start();
  }

  // set up the arithmetic decoder for refinement/aggregation
  if (refAgg) {
    if (contextUsed && inputSymbolDict) {
      resetRefinementStats(sdrTemplate,
			   inputSymbolDict->getRefinementRegionStats());
    } else {
      resetRefinementStats(sdrTemplate, NULL);
    }
  }

  // allocate symbol widths storage
  symWidths = NULL;
  if (huff && !refAgg) {
    symWidths = (Guint *)gmallocn(numNewSyms, sizeof(Guint));
  }

  symHeight = 0;
  i = 0;
  while (i < numNewSyms) {

    // read the height class delta height
    if (huff) {
      huffDecoder->decodeInt(&dh, huffDHTable);
    } else {
      arithDecoder->decodeInt(&dh, iadhStats);
    }
    if (dh < 0 && (Guint)-dh >= symHeight) {
      error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
      goto syntaxError;
    }
    symHeight += dh;
    symWidth = 0;
    totalWidth = 0;
    j = i;

    // read the symbols in this height class
    while (1) {

      // read the delta width
      if (huff) {
	if (!huffDecoder->decodeInt(&dw, huffDWTable)) {
	  break;
	}
      } else {
	if (!arithDecoder->decodeInt(&dw, iadwStats)) {
	  break;
	}
      }
      if (dw < 0 && (Guint)-dw >= symWidth) {
	error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
	goto syntaxError;
      }
      symWidth += dw;

      // using a collective bitmap, so don't read a bitmap here
      if (huff && !refAgg) {
	symWidths[i] = symWidth;
	totalWidth += symWidth;

      // refinement/aggregate coding
      } else if (refAgg) {
	if (huff) {
	  if (!huffDecoder->decodeInt(&refAggNum, huffAggInstTable)) {
	    break;
	  }
	} else {
	  if (!arithDecoder->decodeInt(&refAggNum, iaaiStats)) {
	    break;
	  }
	}
#if 0 //~ This special case was added about a year before the final draft
      //~ of the JBIG2 spec was released.  I have encountered some old
      //~ JBIG2 images that predate it.
	if (0) {
#else
	if (refAggNum == 1) {
#endif
	  if (huff) {
	    symID = huffDecoder->readBits(symCodeLen);
	    huffDecoder->decodeInt(&refDX, huffTableO);
	    huffDecoder->decodeInt(&refDY, huffTableO);
	    huffDecoder->decodeInt(&bmSize, huffTableA);
	    huffDecoder->reset();
	    arithDecoder->start();
	  } else {
	    symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
	    arithDecoder->decodeInt(&refDX, iardxStats);
	    arithDecoder->decodeInt(&refDY, iardyStats);
	  }
	  refBitmap = bitmaps[symID];
	  bitmaps[numInputSyms + i] =
	      readGenericRefinementRegion(symWidth, symHeight,
					  sdrTemplate, gFalse,
					  refBitmap, refDX, refDY,
					  sdrATX, sdrATY);
	  //~ do we need to use the bmSize value here (in Huffman mode)?
	} else {
	  bitmaps[numInputSyms + i] =
	      readTextRegion(huff, gTrue, symWidth, symHeight,
			     refAggNum, 0, numInputSyms + i, NULL,
			     symCodeLen, bitmaps, 0, 0, 0, 1, 0,
			     huffTableF, huffTableH, huffTableK, huffTableO,
			     huffTableO, huffTableO, huffTableO, huffTableA,
			     sdrTemplate, sdrATX, sdrATY);
	}

      // non-ref/agg coding
      } else {
	bitmaps[numInputSyms + i] =
	    readGenericBitmap(gFalse, symWidth, symHeight,
			      sdTemplate, gFalse, gFalse, NULL,
			      sdATX, sdATY, 0);
      }

      ++i;
    }

    // read the collective bitmap
    if (huff && !refAgg) {
      huffDecoder->decodeInt(&bmSize, huffBMSizeTable);
      huffDecoder->reset();
      if (bmSize == 0) {
	collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight);
	bmSize = symHeight * ((totalWidth + 7) >> 3);
	p = collBitmap->getDataPtr();
	for (k = 0; k < (Guint)bmSize; ++k) {
	  *p++ = curStr->getChar();
	}
      } else {
	collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight,
				       0, gFalse, gFalse, NULL, NULL, NULL,
				       bmSize);
      }
      x = 0;
      for (; j < i; ++j) {
	bitmaps[numInputSyms + j] =
	    collBitmap->getSlice(x, 0, symWidths[j], symHeight);
	x += symWidths[j];
      }
      delete collBitmap;
    }
  }

  // create the symbol dict object
  symbolDict = new JBIG2SymbolDict(segNum, numExSyms);

  // exported symbol list
  i = j = 0;
  ex = gFalse;
  while (i < numInputSyms + numNewSyms) {
    if (huff) {
      huffDecoder->decodeInt(&run, huffTableA);
    } else {
      arithDecoder->decodeInt(&run, iaexStats);
    }
    if (ex) {
      for (cnt = 0; cnt < run; ++cnt) {
	symbolDict->setBitmap(j++, bitmaps[i++]->copy());
      }
    } else {
      i += run;
    }
    ex = !ex;
  }
  for ( ; j < numExSyms; ++j) {
    // this should never happen but happens on PDF we don't parse
    // correctly like bug #19702
    symbolDict->setBitmap(j, NULL);
  }

  for (i = 0; i < numNewSyms; ++i) {
    delete bitmaps[numInputSyms + i];
  }
  gfree(bitmaps);
  if (symWidths) {
    gfree(symWidths);
  }

  // save the arithmetic decoder stats
  if (!huff && contextRetained) {
    symbolDict->setGenericRegionStats(genericRegionStats->copy());
    if (refAgg) {
      symbolDict->setRefinementRegionStats(refinementRegionStats->copy());
    }
  }

  // store the new symbol dict
  segments->append(symbolDict);

  return gTrue;

 syntaxError:
  for (i = 0; i < numNewSyms; ++i) {
    if (bitmaps[numInputSyms + i]) {
      delete bitmaps[numInputSyms + i];
    }
  }
  gfree(bitmaps);
  if (symWidths) {
    gfree(symWidths);
  }
  return gFalse;

 eofError:
  error(getPos(), "Unexpected EOF in JBIG2 stream");
  return gFalse;
}

void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
				    GBool lossless, Guint length,
				    Guint *refSegs, Guint nRefSegs) {
  JBIG2Bitmap *bitmap;
  JBIG2HuffmanTable runLengthTab[36];
  JBIG2HuffmanTable *symCodeTab;
  JBIG2HuffmanTable *huffFSTable, *huffDSTable, *huffDTTable;
  JBIG2HuffmanTable *huffRDWTable, *huffRDHTable;
  JBIG2HuffmanTable *huffRDXTable, *huffRDYTable, *huffRSizeTable;
  JBIG2Segment *seg;
  GooList *codeTables;
  JBIG2SymbolDict *symbolDict;
  JBIG2Bitmap **syms;
  Guint w, h, x, y, segInfoFlags, extCombOp;
  Guint flags, huff, refine, logStrips, refCorner, transposed;
  Guint combOp, defPixel, templ;
  int sOffset;
  Guint huffFlags, huffFS, huffDS, huffDT;
  Guint huffRDW, huffRDH, huffRDX, huffRDY, huffRSize;
  Guint numInstances, numSyms, symCodeLen;
  int atx[2], aty[2];
  Guint i, k, kk;
  int j;

  // region segment info field
  if (!readULong(&w) || !readULong(&h) ||
      !readULong(&x) || !readULong(&y) ||
      !readUByte(&segInfoFlags)) {
    goto eofError;
  }
  extCombOp = segInfoFlags & 7;

  // rest of the text region header
  if (!readUWord(&flags)) {
    goto eofError;
  }
  huff = flags & 1;
  refine = (flags >> 1) & 1;
  logStrips = (flags >> 2) & 3;
  refCorner = (flags >> 4) & 3;
  transposed = (flags >> 6) & 1;
  combOp = (flags >> 7) & 3;
  defPixel = (flags >> 9) & 1;
  sOffset = (flags >> 10) & 0x1f;
  if (sOffset & 0x10) {
    sOffset |= -1 - 0x0f;
  }
  templ = (flags >> 15) & 1;
  huffFS = huffDS = huffDT = 0; // make gcc happy
  huffRDW = huffRDH = huffRDX = huffRDY = huffRSize = 0; // make gcc happy
  if (huff) {
    if (!readUWord(&huffFlags)) {
      goto eofError;
    }
    huffFS = huffFlags & 3;
    huffDS = (huffFlags >> 2) & 3;
    huffDT = (huffFlags >> 4) & 3;
    huffRDW = (huffFlags >> 6) & 3;
    huffRDH = (huffFlags >> 8) & 3;
    huffRDX = (huffFlags >> 10) & 3;
    huffRDY = (huffFlags >> 12) & 3;
    huffRSize = (huffFlags >> 14) & 1;
  }
  if (refine && templ == 0) {
    if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
	!readByte(&atx[1]) || !readByte(&aty[1])) {
      goto eofError;
    }
  }
  if (!readULong(&numInstances)) {
    goto eofError;
  }

  // get symbol dictionaries and tables
  codeTables = new GooList();
  numSyms = 0;
  for (i = 0; i < nRefSegs; ++i) {
    if ((seg = findSegment(refSegs[i]))) {
      if (seg->getType() == jbig2SegSymbolDict) {
	numSyms += ((JBIG2SymbolDict *)seg)->getSize();
      } else if (seg->getType() == jbig2SegCodeTable) {
	codeTables->append(seg);
      }
    } else {
      error(getPos(), "Invalid segment reference in JBIG2 text region");
    }
  }
  symCodeLen = 0;
  i = 1;
  while (i < numSyms) {
    ++symCodeLen;
    i <<= 1;
  }

  // get the symbol bitmaps
  syms = (JBIG2Bitmap **)gmallocn(numSyms, sizeof(JBIG2Bitmap *));
  kk = 0;
  for (i = 0; i < nRefSegs; ++i) {
    if ((seg = findSegment(refSegs[i]))) {
      if (seg->getType() == jbig2SegSymbolDict) {
	symbolDict = (JBIG2SymbolDict *)seg;
	for (k = 0; k < symbolDict->getSize(); ++k) {
	  syms[kk++] = symbolDict->getBitmap(k);
	}
      }
    }
  }

  // get the Huffman tables
  huffFSTable = huffDSTable = huffDTTable = NULL; // make gcc happy
  huffRDWTable = huffRDHTable = NULL; // make gcc happy
  huffRDXTable = huffRDYTable = huffRSizeTable = NULL; // make gcc happy
  i = 0;
  if (huff) {
    if (huffFS == 0) {
      huffFSTable = huffTableF;
    } else if (huffFS == 1) {
      huffFSTable = huffTableG;
    } else {
      huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
    }
    if (huffDS == 0) {
      huffDSTable = huffTableH;
    } else if (huffDS == 1) {
      huffDSTable = huffTableI;
    } else if (huffDS == 2) {
      huffDSTable = huffTableJ;
    } else {
      huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
    }
    if (huffDT == 0) {
      huffDTTable = huffTableK;
    } else if (huffDT == 1) {
      huffDTTable = huffTableL;
    } else if (huffDT == 2) {
      huffDTTable = huffTableM;
    } else {
      huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
    }
    if (huffRDW == 0) {
      huffRDWTable = huffTableN;
    } else if (huffRDW == 1) {
      huffRDWTable = huffTableO;
    } else {
      huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
    }
    if (huffRDH == 0) {
      huffRDHTable = huffTableN;
    } else if (huffRDH == 1) {
      huffRDHTable = huffTableO;
    } else {
      huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
    }
    if (huffRDX == 0) {
      huffRDXTable = huffTableN;
    } else if (huffRDX == 1) {
      huffRDXTable = huffTableO;
    } else {
      huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
    }
    if (huffRDY == 0) {
      huffRDYTable = huffTableN;
    } else if (huffRDY == 1) {
      huffRDYTable = huffTableO;
    } else {
      huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
    }
    if (huffRSize == 0) {
      huffRSizeTable = huffTableA;
    } else {
      huffRSizeTable =
	  ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
    }
  }
  delete codeTables;

  // symbol ID Huffman decoding table
  if (huff) {
    huffDecoder->reset();
    for (i = 0; i < 32; ++i) {
      runLengthTab[i].val = i;
      runLengthTab[i].prefixLen = huffDecoder->readBits(4);
      runLengthTab[i].rangeLen = 0;
    }
    runLengthTab[32].val = 0x103;
    runLengthTab[32].prefixLen = huffDecoder->readBits(4);
    runLengthTab[32].rangeLen = 2;
    runLengthTab[33].val = 0x203;
    runLengthTab[33].prefixLen = huffDecoder->readBits(4);
    runLengthTab[33].rangeLen = 3;
    runLengthTab[34].val = 0x20b;
    runLengthTab[34].prefixLen = huffDecoder->readBits(4);
    runLengthTab[34].rangeLen = 7;
    runLengthTab[35].prefixLen = 0;
    runLengthTab[35].rangeLen = jbig2HuffmanEOT;
    huffDecoder->buildTable(runLengthTab, 35);
    symCodeTab = (JBIG2HuffmanTable *)gmallocn(numSyms + 1,
					       sizeof(JBIG2HuffmanTable));
    for (i = 0; i < numSyms; ++i) {
      symCodeTab[i].val = i;
      symCodeTab[i].rangeLen = 0;
    }
    i = 0;
    while (i < numSyms) {
      huffDecoder->decodeInt(&j, runLengthTab);
      if (j > 0x200) {
	for (j -= 0x200; j && i < numSyms; --j) {
	  symCodeTab[i++].prefixLen = 0;
	}
      } else if (j > 0x100) {
	for (j -= 0x100; j && i < numSyms; --j) {
	  symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen;
	  ++i;
	}
      } else {
	symCodeTab[i++].prefixLen = j;
      }
    }
    symCodeTab[numSyms].prefixLen = 0;
    symCodeTab[numSyms].rangeLen = jbig2HuffmanEOT;
    huffDecoder->buildTable(symCodeTab, numSyms);
    huffDecoder->reset();

  // set up the arithmetic decoder
  } else {
    symCodeTab = NULL;
    resetIntStats(symCodeLen);
    arithDecoder->start();
  }
  if (refine) {
    resetRefinementStats(templ, NULL);
  }

  bitmap = readTextRegion(huff, refine, w, h, numInstances,
			  logStrips, numSyms, symCodeTab, symCodeLen, syms,
			  defPixel, combOp, transposed, refCorner, sOffset,
			  huffFSTable, huffDSTable, huffDTTable,
			  huffRDWTable, huffRDHTable,
			  huffRDXTable, huffRDYTable, huffRSizeTable,
			  templ, atx, aty);

  gfree(syms);

  // combine the region bitmap into the page bitmap
  if (imm) {
    if (pageH == 0xffffffff && y + h > curPageH) {
      pageBitmap->expand(y + h, pageDefPixel);
    }
    pageBitmap->combine(bitmap, x, y, extCombOp);
    delete bitmap;

  // store the region bitmap
  } else {
    bitmap->setSegNum(segNum);
    segments->append(bitmap);
  }

  // clean up the Huffman decoder
  if (huff) {
    gfree(symCodeTab);
  }

  return;

 eofError:
  error(getPos(), "Unexpected EOF in JBIG2 stream");
}

JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
					 int w, int h,
					 Guint numInstances,
					 Guint logStrips,
					 int numSyms,
					 JBIG2HuffmanTable *symCodeTab,
					 Guint symCodeLen,
					 JBIG2Bitmap **syms,
					 Guint defPixel, Guint combOp,
					 Guint transposed, Guint refCorner,
					 int sOffset,
					 JBIG2HuffmanTable *huffFSTable,
					 JBIG2HuffmanTable *huffDSTable,
					 JBIG2HuffmanTable *huffDTTable,
					 JBIG2HuffmanTable *huffRDWTable,
					 JBIG2HuffmanTable *huffRDHTable,
					 JBIG2HuffmanTable *huffRDXTable,
					 JBIG2HuffmanTable *huffRDYTable,
					 JBIG2HuffmanTable *huffRSizeTable,
					 Guint templ,
					 int *atx, int *aty) {
  JBIG2Bitmap *bitmap;
  JBIG2Bitmap *symbolBitmap;
  Guint strips;
  int t, dt, tt, s, ds, sFirst, j;
  int rdw, rdh, rdx, rdy, ri, refDX, refDY, bmSize;
  Guint symID, inst, bw, bh;

  strips = 1 << logStrips;

  // allocate the bitmap
  bitmap = new JBIG2Bitmap(0, w, h);
  if (defPixel) {
    bitmap->clearToOne();
  } else {
    bitmap->clearToZero();
  }

  // decode initial T value
  if (huff) {
    huffDecoder->decodeInt(&t, huffDTTable);
  } else {
    arithDecoder->decodeInt(&t, iadtStats);
  }
  t *= -(int)strips;

  inst = 0;
  sFirst = 0;
  while (inst < numInstances) {

    // decode delta-T
    if (huff) {
      huffDecoder->decodeInt(&dt, huffDTTable);
    } else {
      arithDecoder->decodeInt(&dt, iadtStats);
    }
    t += dt * strips;

    // first S value
    if (huff) {
      huffDecoder->decodeInt(&ds, huffFSTable);
    } else {
      arithDecoder->decodeInt(&ds, iafsStats);
    }
    sFirst += ds;
    s = sFirst;

    // read the instances
    while (1) {

      // T value
      if (strips == 1) {
	dt = 0;
      } else if (huff) {
	dt = huffDecoder->readBits(logStrips);
      } else {
	arithDecoder->decodeInt(&dt, iaitStats);
      }
      tt = t + dt;

      // symbol ID
      if (huff) {
	if (symCodeTab) {
	  huffDecoder->decodeInt(&j, symCodeTab);
	  symID = (Guint)j;
	} else {
	  symID = huffDecoder->readBits(symCodeLen);
	}
      } else {
	symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
      }

      if (symID >= (Guint)numSyms) {
	error(getPos(), "Invalid symbol number in JBIG2 text region");
      } else {

	// get the symbol bitmap
	symbolBitmap = NULL;
	if (refine) {
	  if (huff) {
	    ri = (int)huffDecoder->readBit();
	  } else {
	    arithDecoder->decodeInt(&ri, iariStats);
	  }
	} else {
	  ri = 0;
	}
	if (ri) {
	  if (huff) {
	    huffDecoder->decodeInt(&rdw, huffRDWTable);
	    huffDecoder->decodeInt(&rdh, huffRDHTable);
	    huffDecoder->decodeInt(&rdx, huffRDXTable);
	    huffDecoder->decodeInt(&rdy, huffRDYTable);
	    huffDecoder->decodeInt(&bmSize, huffRSizeTable);
	    huffDecoder->reset();
	    arithDecoder->start();
	  } else {
	    arithDecoder->decodeInt(&rdw, iardwStats);
	    arithDecoder->decodeInt(&rdh, iardhStats);
	    arithDecoder->decodeInt(&rdx, iardxStats);
	    arithDecoder->decodeInt(&rdy, iardyStats);
	  }
	  refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
	  refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;

	  symbolBitmap =
	    readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
					rdh + syms[symID]->getHeight(),
					templ, gFalse, syms[symID],
					refDX, refDY, atx, aty);
	  //~ do we need to use the bmSize value here (in Huffman mode)?
	} else {
	  symbolBitmap = syms[symID];
	}

	// combine the symbol bitmap into the region bitmap
	//~ something is wrong here - refCorner shouldn't degenerate into
	//~   two cases
	bw = symbolBitmap->getWidth() - 1;
	bh = symbolBitmap->getHeight() - 1;
	if (transposed) {
	  switch (refCorner) {
	  case 0: // bottom left
	    bitmap->combine(symbolBitmap, tt, s, combOp);
	    break;
	  case 1: // top left
	    bitmap->combine(symbolBitmap, tt, s, combOp);
	    break;
	  case 2: // bottom right
	    bitmap->combine(symbolBitmap, tt - bw, s, combOp);
	    break;
	  case 3: // top right
	    bitmap->combine(symbolBitmap, tt - bw, s, combOp);
	    break;
	  }
	  s += bh;
	} else {
	  switch (refCorner) {
	  case 0: // bottom left
	    bitmap->combine(symbolBitmap, s, tt - bh, combOp);
	    break;
	  case 1: // top left
	    bitmap->combine(symbolBitmap, s, tt, combOp);
	    break;
	  case 2: // bottom right
	    bitmap->combine(symbolBitmap, s, tt - bh, combOp);
	    break;
	  case 3: // top right
	    bitmap->combine(symbolBitmap, s, tt, combOp);
	    break;
	  }
	  s += bw;
	}
	if (ri) {
	  delete symbolBitmap;
	}
      }

      // next instance
      ++inst;

      // next S value
      if (huff) {
	if (!huffDecoder->decodeInt(&ds, huffDSTable)) {
	  break;
	}
      } else {
	if (!arithDecoder->decodeInt(&ds, iadsStats)) {
	  break;
	}
      }
      s += sOffset + ds;
    }
  }

  return bitmap;
}

void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
  JBIG2PatternDict *patternDict;
  JBIG2Bitmap *bitmap;
  Guint flags, patternW, patternH, grayMax, templ, mmr;
  int atx[4], aty[4];
  Guint i, x;

  // halftone dictionary flags, pattern width and height, max gray value
  if (!readUByte(&flags) ||
      !readUByte(&patternW) ||
      !readUByte(&patternH) ||
      !readULong(&grayMax)) {
    goto eofError;
  }
  templ = (flags >> 1) & 3;
  mmr = flags & 1;

  // set up the arithmetic decoder
  if (!mmr) {
    resetGenericStats(templ, NULL);
    arithDecoder->start();
  }

  // read the bitmap
  atx[0] = -(int)patternW; aty[0] =  0;
  atx[1] = -3;             aty[1] = -1;
  atx[2] =  2;             aty[2] = -2;
  atx[3] = -2;             aty[3] = -2;
  bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH,
			     templ, gFalse, gFalse, NULL,
			     atx, aty, length - 7);

  // create the pattern dict object
  patternDict = new JBIG2PatternDict(segNum, grayMax + 1);

  // split up the bitmap
  x = 0;
  for (i = 0; i <= grayMax; ++i) {
    patternDict->setBitmap(i, bitmap->getSlice(x, 0, patternW, patternH));
    x += patternW;
  }

  // free memory
  delete bitmap;

  // store the new pattern dict
  segments->append(patternDict);

  return;

 eofError:
  error(getPos(), "Unexpected EOF in JBIG2 stream");
}

void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
					GBool lossless, Guint length,
					Guint *refSegs, Guint nRefSegs) {
  JBIG2Bitmap *bitmap;
  JBIG2Segment *seg;
  JBIG2PatternDict *patternDict;
  JBIG2Bitmap *skipBitmap;
  Guint *grayImg;
  JBIG2Bitmap *grayBitmap;
  JBIG2Bitmap *patternBitmap;
  Guint w, h, x, y, segInfoFlags, extCombOp;
  Guint flags, mmr, templ, enableSkip, combOp;
  Guint gridW, gridH, stepX, stepY, patW, patH;
  int atx[4], aty[4];
  int gridX, gridY, xx, yy, bit, j;
  Guint bpp, m, n, i;

  // region segment info field
  if (!readULong(&w) || !readULong(&h) ||
      !readULong(&x) || !readULong(&y) ||
      !readUByte(&segInfoFlags)) {
    goto eofError;
  }
  extCombOp = segInfoFlags & 7;

  // rest of the halftone region header
  if (!readUByte(&flags)) {
    goto eofError;
  }
  mmr = flags & 1;
  templ = (flags >> 1) & 3;
  enableSkip = (flags >> 3) & 1;
  combOp = (flags >> 4) & 7;
  if (!readULong(&gridW) || !readULong(&gridH) ||
      !readLong(&gridX) || !readLong(&gridY) ||
      !readUWord(&stepX) || !readUWord(&stepY)) {
    goto eofError;
  }
  if (w == 0 || h == 0 || w >= INT_MAX / h) {
    error(getPos(), "Bad bitmap size in JBIG2 halftone segment");
    return;
  }
  if (gridH == 0 || gridW >= INT_MAX / gridH) {
    error(getPos(), "Bad grid size in JBIG2 halftone segment");
    return;
  }

  // get pattern dictionary
  if (nRefSegs != 1) {
    error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
    return;
  }
  seg = findSegment(refSegs[0]);
  if (seg == NULL || seg->getType() != jbig2SegPatternDict) {
    error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
    return;
  }

  patternDict = (JBIG2PatternDict *)seg;
  bpp = 0;
  i = 1;
  while (i < patternDict->getSize()) {
    ++bpp;
    i <<= 1;
  }
  patW = patternDict->getBitmap(0)->getWidth();
  patH = patternDict->getBitmap(0)->getHeight();

  // set up the arithmetic decoder
  if (!mmr) {
    resetGenericStats(templ, NULL);
    arithDecoder->start();
  }

  // allocate the bitmap
  bitmap = new JBIG2Bitmap(segNum, w, h);
  if (flags & 0x80) { // HDEFPIXEL
    bitmap->clearToOne();
  } else {
    bitmap->clearToZero();
  }

  // compute the skip bitmap
  skipBitmap = NULL;
  if (enableSkip) {
    skipBitmap = new JBIG2Bitmap(0, gridW, gridH);
    skipBitmap->clearToZero();
    for (m = 0; m < gridH; ++m) {
      for (n = 0; n < gridW; ++n) {
	xx = gridX + m * stepY + n * stepX;
	yy = gridY + m * stepX - n * stepY;
	if (((xx + (int)patW) >> 8) <= 0 || (xx >> 8) >= (int)w ||
	    ((yy + (int)patH) >> 8) <= 0 || (yy >> 8) >= (int)h) {
	  skipBitmap->setPixel(n, m);
	}
      }
    }
  }

  // read the gray-scale image
  grayImg = (Guint *)gmallocn(gridW * gridH, sizeof(Guint));
  memset(grayImg, 0, gridW * gridH * sizeof(Guint));
  atx[0] = templ <= 1 ? 3 : 2;  aty[0] = -1;
  atx[1] = -3;                  aty[1] = -1;
  atx[2] =  2;                  aty[2] = -2;
  atx[3] = -2;                  aty[3] = -2;
  for (j = bpp - 1; j >= 0; --j) {
    grayBitmap = readGenericBitmap(mmr, gridW, gridH, templ, gFalse,
				   enableSkip, skipBitmap, atx, aty, -1);
    i = 0;
    for (m = 0; m < gridH; ++m) {
      for (n = 0; n < gridW; ++n) {
	bit = grayBitmap->getPixel(n, m) ^ (grayImg[i] & 1);
	grayImg[i] = (grayImg[i] << 1) | bit;
	++i;
      }
    }
    delete grayBitmap;
  }

  // decode the image
  i = 0;
  for (m = 0; m < gridH; ++m) {
    xx = gridX + m * stepY;
    yy = gridY + m * stepX;
    for (n = 0; n < gridW; ++n) {
      if (!(enableSkip && skipBitmap->getPixel(n, m))) {
	patternBitmap = patternDict->getBitmap(grayImg[i]);
	bitmap->combine(patternBitmap, xx >> 8, yy >> 8, combOp);
      }
      xx += stepX;
      yy -= stepY;
      ++i;
    }
  }

  gfree(grayImg);
  if (skipBitmap) {
    delete skipBitmap;
  }

  // combine the region bitmap into the page bitmap
  if (imm) {
    if (pageH == 0xffffffff && y + h > curPageH) {
      pageBitmap->expand(y + h, pageDefPixel);
    }
    pageBitmap->combine(bitmap, x, y, extCombOp);
    delete bitmap;

  // store the region bitmap
  } else {
    segments->append(bitmap);
  }

  return;

 eofError:
  error(getPos(), "Unexpected EOF in JBIG2 stream");
}

void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
				       GBool lossless, Guint length) {
  JBIG2Bitmap *bitmap;
  Guint w, h, x, y, segInfoFlags, extCombOp;
  Guint flags, mmr, templ, tpgdOn;
  int atx[4], aty[4];

  // region segment info field
  if (!readULong(&w) || !readULong(&h) ||
      !readULong(&x) || !readULong(&y) ||
      !readUByte(&segInfoFlags)) {
    goto eofError;
  }
  extCombOp = segInfoFlags & 7;

  // rest of the generic region segment header
  if (!readUByte(&flags)) {
    goto eofError;
  }
  mmr = flags & 1;
  templ = (flags >> 1) & 3;
  tpgdOn = (flags >> 3) & 1;

  // AT flags
  if (!mmr) {
    if (templ == 0) {
      if (!readByte(&atx[0]) ||
	  !readByte(&aty[0]) ||
	  !readByte(&atx[1]) ||
	  !readByte(&aty[1]) ||
	  !readByte(&atx[2]) ||
	  !readByte(&aty[2]) ||
	  !readByte(&atx[3]) ||
	  !readByte(&aty[3])) {
	goto eofError;
      }
    } else {
      if (!readByte(&atx[0]) ||
	  !readByte(&aty[0])) {
	goto eofError;
      }
    }
  }

  // set up the arithmetic decoder
  if (!mmr) {
    resetGenericStats(templ, NULL);
    arithDecoder->start();
  }

  // read the bitmap
  bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
			     NULL, atx, aty, mmr ? 0 : length - 18);

  // combine the region bitmap into the page bitmap
  if (imm) {
    if (pageH == 0xffffffff && y + h > curPageH) {
      pageBitmap->expand(y + h, pageDefPixel);
    }
    pageBitmap->combine(bitmap, x, y, extCombOp);
    delete bitmap;

  // store the region bitmap
  } else {
    bitmap->setSegNum(segNum);
    segments->append(bitmap);
  }

  return;

 eofError:
  error(getPos(), "Unexpected EOF in JBIG2 stream");
}

JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
					    int templ, GBool tpgdOn,
					    GBool useSkip, JBIG2Bitmap *skip,
					    int *atx, int *aty,
					    int mmrDataLength) {
  JBIG2Bitmap *bitmap;
  GBool ltp;
  Guint ltpCX, cx, cx0, cx1, cx2;
  JBIG2BitmapPtr cxPtr0 = {0}, cxPtr1 = {0};
  JBIG2BitmapPtr atPtr0 = {0}, atPtr1 = {0}, atPtr2 = {0}, atPtr3 = {0};
  int *refLine, *codingLine;
  int code1, code2, code3;
  int x, y, a0, pix, i, refI, codingI;

  bitmap = new JBIG2Bitmap(0, w, h);
  bitmap->clearToZero();

  //----- MMR decode

  if (mmr) {

    mmrDecoder->reset();
    refLine = (int *)gmallocn(w + 2, sizeof(int));
    codingLine = (int *)gmallocn(w + 2, sizeof(int));
    codingLine[0] = codingLine[1] = w;

    for (y = 0; y < h; ++y) {

      // copy coding line to ref line
      for (i = 0; codingLine[i] < w; ++i) {
	refLine[i] = codingLine[i];
      }
      refLine[i] = refLine[i + 1] = w;

      // decode a line
      refI = 0;     // b1 = refLine[refI]
      codingI = 0;  // a1 = codingLine[codingI]
      a0 = 0;
      do {
	code1 = mmrDecoder->get2DCode();
	switch (code1) {
	case twoDimPass:
	  if (refLine[refI] < w) {
	    a0 = refLine[refI + 1];
	    refI += 2;
	  }
	  break;
	case twoDimHoriz:
	  if (codingI & 1) {
	    code1 = 0;
	    do {
	      code1 += code3 = mmrDecoder->getBlackCode();
	    } while (code3 >= 64);
	    code2 = 0;
	    do {
	      code2 += code3 = mmrDecoder->getWhiteCode();
	    } while (code3 >= 64);
	  } else {
	    code1 = 0;
	    do {
	      code1 += code3 = mmrDecoder->getWhiteCode();
	    } while (code3 >= 64);
	    code2 = 0;
	    do {
	      code2 += code3 = mmrDecoder->getBlackCode();
	    } while (code3 >= 64);
	  }
	  if (code1 > 0 || code2 > 0) {
	    a0 = codingLine[codingI++] = a0 + code1;
	    a0 = codingLine[codingI++] = a0 + code2;
	    while (refLine[refI] <= a0 && refLine[refI] < w) {
	      refI += 2;
	    }
	  }
	  break;
	case twoDimVert0:
	  a0 = codingLine[codingI++] = refLine[refI];
	  if (refLine[refI] < w) {
	    ++refI;
	  }
	  break;
	case twoDimVertR1:
	  a0 = codingLine[codingI++] = refLine[refI] + 1;
	  if (refLine[refI] < w) {
	    ++refI;
	    while (refLine[refI] <= a0 && refLine[refI] < w) {
	      refI += 2;
	    }
	  }
	  break;
	case twoDimVertR2:
	  a0 = codingLine[codingI++] = refLine[refI] + 2;
	  if (refLine[refI] < w) {
	    ++refI;
	    while (refLine[refI] <= a0 && refLine[refI] < w) {
	      refI += 2;
	    }
	  }
	  break;
	case twoDimVertR3:
	  a0 = codingLine[codingI++] = refLine[refI] + 3;
	  if (refLine[refI] < w) {
	    ++refI;
	    while (refLine[refI] <= a0 && refLine[refI] < w) {
	      refI += 2;
	    }
	  }
	  break;
	case twoDimVertL1:
	  a0 = codingLine[codingI++] = refLine[refI] - 1;
	  if (refI > 0) {
	    --refI;
	  } else {
	    ++refI;
	  }
	  while (refLine[refI] <= a0 && refLine[refI] < w) {
	    refI += 2;
	  }
	  break;
	case twoDimVertL2:
	  a0 = codingLine[codingI++] = refLine[refI] - 2;
	  if (refI > 0) {
	    --refI;
	  } else {
	    ++refI;
	  }
	  while (refLine[refI] <= a0 && refLine[refI] < w) {
	    refI += 2;
	  }
	  break;
	case twoDimVertL3:
	  a0 = codingLine[codingI++] = refLine[refI] - 3;
	  if (refI > 0) {
	    --refI;
	  } else {
	    ++refI;
	  }
	  while (refLine[refI] <= a0 && refLine[refI] < w) {
	    refI += 2;
	  }
	  break;
	default:
	  error(getPos(), "Illegal code in JBIG2 MMR bitmap data");
	  break;
	}
      } while (a0 < w);
      codingLine[codingI++] = w;

      // convert the run lengths to a bitmap line
      i = 0;
      while (codingLine[i] < w) {
	for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
	  bitmap->setPixel(x, y);
	}
	i += 2;
      }
    }

    if (mmrDataLength >= 0) {
      mmrDecoder->skipTo(mmrDataLength);
    } else {
      if (mmrDecoder->get24Bits() != 0x001001) {
	error(getPos(), "Missing EOFB in JBIG2 MMR bitmap data");
      }
    }

    gfree(refLine);
    gfree(codingLine);

  //----- arithmetic decode

  } else {
    // set up the typical row context
    ltpCX = 0; // make gcc happy
    if (tpgdOn) {
      switch (templ) {
      case 0:
	ltpCX = 0x3953; // 001 11001 0101 0011
	break;
      case 1:
	ltpCX = 0x079a; // 0011 11001 101 0
	break;
      case 2:
	ltpCX = 0x0e3; // 001 1100 01 1
	break;
      case 3:
	ltpCX = 0x18a; // 01100 0101 1
	break;
      }
    }

    ltp = 0;
    cx = cx0 = cx1 = cx2 = 0; // make gcc happy
    for (y = 0; y < h; ++y) {

      // check for a "typical" (duplicate) row
      if (tpgdOn) {
	if (arithDecoder->decodeBit(ltpCX, genericRegionStats)) {
	  ltp = !ltp;
	}
	if (ltp) {
	  bitmap->duplicateRow(y, y-1);
	  continue;
	}
      }

      switch (templ) {
      case 0:

	// set up the context
	bitmap->getPixelPtr(0, y-2, &cxPtr0);
	cx0 = bitmap->nextPixel(&cxPtr0);
	cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
	bitmap->getPixelPtr(0, y-1, &cxPtr1);
	cx1 = bitmap->nextPixel(&cxPtr1);
	cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
	cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
	cx2 = 0;
	bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
	bitmap->getPixelPtr(atx[1], y + aty[1], &atPtr1);
	bitmap->getPixelPtr(atx[2], y + aty[2], &atPtr2);
	bitmap->getPixelPtr(atx[3], y + aty[3], &atPtr3);

	// decode the row
	for (x = 0; x < w; ++x) {

	  // build the context
	  cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
	       (bitmap->nextPixel(&atPtr0) << 3) |
	       (bitmap->nextPixel(&atPtr1) << 2) |
	       (bitmap->nextPixel(&atPtr2) << 1) |
	       bitmap->nextPixel(&atPtr3);

	  // check for a skipped pixel
	  if (useSkip && skip->getPixel(x, y)) {
	    pix = 0;

	  // decode the pixel
	  } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
	    bitmap->setPixel(x, y);
	  }

	  // update the context
	  cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
	  cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
	  cx2 = ((cx2 << 1) | pix) & 0x0f;
	}
	break;

      case 1:

	// set up the context
	bitmap->getPixelPtr(0, y-2, &cxPtr0);
	cx0 = bitmap->nextPixel(&cxPtr0);
	cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
	cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
	bitmap->getPixelPtr(0, y-1, &cxPtr1);
	cx1 = bitmap->nextPixel(&cxPtr1);
	cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
	cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
	cx2 = 0;
	bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);

	// decode the row
	for (x = 0; x < w; ++x) {

	  // build the context
	  cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
	       bitmap->nextPixel(&atPtr0);

	  // check for a skipped pixel
	  if (useSkip && skip->getPixel(x, y)) {
	    pix = 0;

	  // decode the pixel
	  } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
	    bitmap->setPixel(x, y);
	  }

	  // update the context
	  cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x0f;
	  cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
	  cx2 = ((cx2 << 1) | pix) & 0x07;
	}
	break;

      case 2:

	// set up the context
	bitmap->getPixelPtr(0, y-2, &cxPtr0);
	cx0 = bitmap->nextPixel(&cxPtr0);
	cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
	bitmap->getPixelPtr(0, y-1, &cxPtr1);
	cx1 = bitmap->nextPixel(&cxPtr1);
	cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
	cx2 = 0;
	bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);

	// decode the row
	for (x = 0; x < w; ++x) {

	  // build the context
	  cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
	       bitmap->nextPixel(&atPtr0);

	  // check for a skipped pixel
	  if (useSkip && skip->getPixel(x, y)) {
	    pix = 0;

	  // decode the pixel
	  } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
	    bitmap->setPixel(x, y);
	  }

	  // update the context
	  cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
	  cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x0f;
	  cx2 = ((cx2 << 1) | pix) & 0x03;
	}
	break;

      case 3:

	// set up the context
	bitmap->getPixelPtr(0, y-1, &cxPtr1);
	cx1 = bitmap->nextPixel(&cxPtr1);
	cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
	cx2 = 0;
	bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);

	// decode the row
	for (x = 0; x < w; ++x) {

	  // build the context
	  cx = (cx1 << 5) | (cx2 << 1) |
	       bitmap->nextPixel(&atPtr0);

	  // check for a skipped pixel
	  if (useSkip && skip->getPixel(x, y)) {
	    pix = 0;

	  // decode the pixel
	  } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
	    bitmap->setPixel(x, y);
	  }

	  // update the context
	  cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
	  cx2 = ((cx2 << 1) | pix) & 0x0f;
	}
	break;
      }
    }
  }

  return bitmap;
}

void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
						 GBool lossless, Guint length,
						 Guint *refSegs,
						 Guint nRefSegs) {
  JBIG2Bitmap *bitmap, *refBitmap;
  Guint w, h, x, y, segInfoFlags, extCombOp;
  Guint flags, templ, tpgrOn;
  int atx[2], aty[2];
  JBIG2Segment *seg;

  // region segment info field
  if (!readULong(&w) || !readULong(&h) ||
      !readULong(&x) || !readULong(&y) ||
      !readUByte(&segInfoFlags)) {
    goto eofError;
  }
  extCombOp = segInfoFlags & 7;

  // rest of the generic refinement region segment header
  if (!readUByte(&flags)) {
    goto eofError;
  }
  templ = flags & 1;
  tpgrOn = (flags >> 1) & 1;

  // AT flags
  if (!templ) {
    if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
	!readByte(&atx[1]) || !readByte(&aty[1])) {
      goto eofError;
    }
  }

  // resize the page bitmap if needed
  if (nRefSegs == 0 || imm) {
    if (pageH == 0xffffffff && y + h > curPageH) {
      pageBitmap->expand(y + h, pageDefPixel);
    }
  }

  // get referenced bitmap
  if (nRefSegs > 1) {
    error(getPos(), "Bad reference in JBIG2 generic refinement segment");
    return;
  }
  if (nRefSegs == 1) {
    seg = findSegment(refSegs[0]);
    if (seg == NULL || seg->getType() != jbig2SegBitmap) {
      error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
      return;
    }
    refBitmap = (JBIG2Bitmap *)seg;
  } else {
    refBitmap = pageBitmap->getSlice(x, y, w, h);
  }

  // set up the arithmetic decoder
  resetRefinementStats(templ, NULL);
  arithDecoder->start();

  // read
  bitmap = readGenericRefinementRegion(w, h, templ, tpgrOn,
				       refBitmap, 0, 0, atx, aty);

  // combine the region bitmap into the page bitmap
  if (imm) {
    pageBitmap->combine(bitmap, x, y, extCombOp);
    delete bitmap;

  // store the region bitmap
  } else {
    bitmap->setSegNum(segNum);
    segments->append(bitmap);
  }

  // delete the referenced bitmap
  if (nRefSegs == 1) {
    discardSegment(refSegs[0]);
  } else {
    delete refBitmap;
  }

  return;

 eofError:
  error(getPos(), "Unexpected EOF in JBIG2 stream");
}

JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
						      int templ, GBool tpgrOn,
						      JBIG2Bitmap *refBitmap,
						      int refDX, int refDY,
						      int *atx, int *aty) {
  JBIG2Bitmap *bitmap;
  GBool ltp;
  Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
  JBIG2BitmapPtr cxPtr0 = {0};
  JBIG2BitmapPtr cxPtr1 = {0};
  JBIG2BitmapPtr cxPtr2 = {0};
  JBIG2BitmapPtr cxPtr3 = {0};
  JBIG2BitmapPtr cxPtr4 = {0};
  JBIG2BitmapPtr cxPtr5 = {0};
  JBIG2BitmapPtr cxPtr6 = {0};
  JBIG2BitmapPtr tpgrCXPtr0 = {0};
  JBIG2BitmapPtr tpgrCXPtr1 = {0};
  JBIG2BitmapPtr tpgrCXPtr2 = {0};
  int x, y, pix;

  bitmap = new JBIG2Bitmap(0, w, h);
  bitmap->clearToZero();

  // set up the typical row context
  if (templ) {
    ltpCX = 0x008;
  } else {
    ltpCX = 0x0010;
  }

  ltp = 0;
  for (y = 0; y < h; ++y) {

    if (templ) {

      // set up the context
      bitmap->getPixelPtr(0, y-1, &cxPtr0);
      cx0 = bitmap->nextPixel(&cxPtr0);
      bitmap->getPixelPtr(-1, y, &cxPtr1);
      refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
      refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
      cx3 = refBitmap->nextPixel(&cxPtr3);
      cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
      refBitmap->getPixelPtr(-refDX, y+1-refDY, &cxPtr4);
      cx4 = refBitmap->nextPixel(&cxPtr4);

      // set up the typical prediction context
      tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
      if (tpgrOn) {
	refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
	tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
	tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
	tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
	refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
	tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
	tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
	tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
	refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
	tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
	tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
	tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
      }

      for (x = 0; x < w; ++x) {

	// update the context
	cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 7;
	cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
	cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 3;

	if (tpgrOn) {
	  // update the typical predictor context
	  tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
	  tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
	  tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;

	  // check for a "typical" pixel
	  if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
	    ltp = !ltp;
	  }
	  if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
	    bitmap->clearPixel(x, y);
	    continue;
	  } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
	    bitmap->setPixel(x, y);
	    continue;
	  }
	}

	// build the context
	cx = (cx0 << 7) | (bitmap->nextPixel(&cxPtr1) << 6) |
	     (refBitmap->nextPixel(&cxPtr2) << 5) |
	     (cx3 << 2) | cx4;

	// decode the pixel
	if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
	  bitmap->setPixel(x, y);
	}
      }

    } else {

      // set up the context
      bitmap->getPixelPtr(0, y-1, &cxPtr0);
      cx0 = bitmap->nextPixel(&cxPtr0);
      bitmap->getPixelPtr(-1, y, &cxPtr1);
      refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
      cx2 = refBitmap->nextPixel(&cxPtr2);
      refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
      cx3 = refBitmap->nextPixel(&cxPtr3);
      cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
      refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &cxPtr4);
      cx4 = refBitmap->nextPixel(&cxPtr4);
      cx4 = (cx4 << 1) | refBitmap->nextPixel(&cxPtr4);
      bitmap->getPixelPtr(atx[0], y+aty[0], &cxPtr5);
      refBitmap->getPixelPtr(atx[1]-refDX, y+aty[1]-refDY, &cxPtr6);

      // set up the typical prediction context
      tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
      if (tpgrOn) {
	refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
	tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
	tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
	tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
	refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
	tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
	tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
	tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
	refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
	tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
	tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
	tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
      }

      for (x = 0; x < w; ++x) {

	// update the context
	cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 3;
	cx2 = ((cx2 << 1) | refBitmap->nextPixel(&cxPtr2)) & 3;
	cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
	cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 7;

	if (tpgrOn) {
	  // update the typical predictor context
	  tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
	  tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
	  tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;

	  // check for a "typical" pixel
	  if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
	    ltp = !ltp;
	  }
	  if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
	    bitmap->clearPixel(x, y);
	    continue;
	  } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
	    bitmap->setPixel(x, y);
	    continue;
	  }
	}

	// build the context
	cx = (cx0 << 11) | (bitmap->nextPixel(&cxPtr1) << 10) |
	     (cx2 << 8) | (cx3 << 5) | (cx4 << 2) |
	     (bitmap->nextPixel(&cxPtr5) << 1) |
	     refBitmap->nextPixel(&cxPtr6);

	// decode the pixel
	if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
	  bitmap->setPixel(x, y);
	}
      }
    }
  }

  return bitmap;
}

void JBIG2Stream::readPageInfoSeg(Guint length) {
  Guint xRes, yRes, flags, striping;

  if (!readULong(&pageW) || !readULong(&pageH) ||
      !readULong(&xRes) || !readULong(&yRes) ||
      !readUByte(&flags) || !readUWord(&striping)) {
    goto eofError;
  }
  pageDefPixel = (flags >> 2) & 1;
  defCombOp = (flags >> 3) & 3;

  // allocate the page bitmap
  if (pageH == 0xffffffff) {
    curPageH = striping & 0x7fff;
  } else {
    curPageH = pageH;
  }
  pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);

  // default pixel value
  if (pageDefPixel) {
    pageBitmap->clearToOne();
  } else {
    pageBitmap->clearToZero();
  }

  return;

 eofError:
  error(getPos(), "Unexpected EOF in JBIG2 stream");
}

void JBIG2Stream::readEndOfStripeSeg(Guint length) {
  Guint i;

  // skip the segment
  for (i = 0; i < length; ++i) {
    curStr->getChar();
  }
}

void JBIG2Stream::readProfilesSeg(Guint length) {
  Guint i;

  // skip the segment
  for (i = 0; i < length; ++i) {
    curStr->getChar();
  }
}

void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) {
  JBIG2HuffmanTable *huffTab;
  Guint flags, oob, prefixBits, rangeBits;
  int lowVal, highVal, val;
  Guint huffTabSize, i;

  if (!readUByte(&flags) || !readLong(&lowVal) || !readLong(&highVal)) {
    goto eofError;
  }
  oob = flags & 1;
  prefixBits = ((flags >> 1) & 7) + 1;
  rangeBits = ((flags >> 4) & 7) + 1;

  huffDecoder->reset();
  huffTabSize = 8;
  huffTab = (JBIG2HuffmanTable *)
                gmallocn(huffTabSize, sizeof(JBIG2HuffmanTable));
  i = 0;
  val = lowVal;
  while (val < highVal) {
    if (i == huffTabSize) {
      huffTabSize *= 2;
      huffTab = (JBIG2HuffmanTable *)
	            greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable));
    }
    huffTab[i].val = val;
    huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
    huffTab[i].rangeLen = huffDecoder->readBits(rangeBits);
    val += 1 << huffTab[i].rangeLen;
    ++i;
  }
  if (i + oob + 3 > huffTabSize) {
    huffTabSize = i + oob + 3;
    huffTab = (JBIG2HuffmanTable *)
                  greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable));
  }
  huffTab[i].val = lowVal - 1;
  huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
  huffTab[i].rangeLen = jbig2HuffmanLOW;
  ++i;
  huffTab[i].val = highVal;
  huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
  huffTab[i].rangeLen = 32;
  ++i;
  if (oob) {
    huffTab[i].val = 0;
    huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
    huffTab[i].rangeLen = jbig2HuffmanOOB;
    ++i;
  }
  huffTab[i].val = 0;
  huffTab[i].prefixLen = 0;
  huffTab[i].rangeLen = jbig2HuffmanEOT;
  huffDecoder->buildTable(huffTab, i);

  // create and store the new table segment
  segments->append(new JBIG2CodeTable(segNum, huffTab));

  return;

 eofError:
  error(getPos(), "Unexpected EOF in JBIG2 stream");
}

void JBIG2Stream::readExtensionSeg(Guint length) {
  Guint i;

  // skip the segment
  for (i = 0; i < length; ++i) {
    curStr->getChar();
  }
}

JBIG2Segment *JBIG2Stream::findSegment(Guint segNum) {
  JBIG2Segment *seg;
  int i;

  for (i = 0; i < globalSegments->getLength(); ++i) {
    seg = (JBIG2Segment *)globalSegments->get(i);
    if (seg->getSegNum() == segNum) {
      return seg;
    }
  }
  for (i = 0; i < segments->getLength(); ++i) {
    seg = (JBIG2Segment *)segments->get(i);
    if (seg->getSegNum() == segNum) {
      return seg;
    }
  }
  return NULL;
}

void JBIG2Stream::discardSegment(Guint segNum) {
  JBIG2Segment *seg;
  int i;

  for (i = 0; i < globalSegments->getLength(); ++i) {
    seg = (JBIG2Segment *)globalSegments->get(i);
    if (seg->getSegNum() == segNum) {
      globalSegments->del(i);
      return;
    }
  }
  for (i = 0; i < segments->getLength(); ++i) {
    seg = (JBIG2Segment *)segments->get(i);
    if (seg->getSegNum() == segNum) {
      segments->del(i);
      return;
    }
  }
}

void JBIG2Stream::resetGenericStats(Guint templ,
				    JArithmeticDecoderStats *prevStats) {
  int size;

  size = contextSize[templ];
  if (prevStats && prevStats->getContextSize() == size) {
    if (genericRegionStats->getContextSize() == size) {
      genericRegionStats->copyFrom(prevStats);
    } else {
      delete genericRegionStats;
      genericRegionStats = prevStats->copy();
    }
  } else {
    if (genericRegionStats->getContextSize() == size) {
      genericRegionStats->reset();
    } else {
      delete genericRegionStats;
      genericRegionStats = new JArithmeticDecoderStats(1 << size);
    }
  }
}

void JBIG2Stream::resetRefinementStats(Guint templ,
				       JArithmeticDecoderStats *prevStats) {
  int size;

  size = refContextSize[templ];
  if (prevStats && prevStats->getContextSize() == size) {
    if (refinementRegionStats->getContextSize() == size) {
      refinementRegionStats->copyFrom(prevStats);
    } else {
      delete refinementRegionStats;
      refinementRegionStats = prevStats->copy();
    }
  } else {
    if (refinementRegionStats->getContextSize() == size) {
      refinementRegionStats->reset();
    } else {
      delete refinementRegionStats;
      refinementRegionStats = new JArithmeticDecoderStats(1 << size);
    }
  }
}

void JBIG2Stream::resetIntStats(int symCodeLen) {
  iadhStats->reset();
  iadwStats->reset();
  iaexStats->reset();
  iaaiStats->reset();
  iadtStats->reset();
  iaitStats->reset();
  iafsStats->reset();
  iadsStats->reset();
  iardxStats->reset();
  iardyStats->reset();
  iardwStats->reset();
  iardhStats->reset();
  iariStats->reset();
  if (iaidStats->getContextSize() == 1 << (symCodeLen + 1)) {
    iaidStats->reset();
  } else {
    delete iaidStats;
    iaidStats = new JArithmeticDecoderStats(1 << (symCodeLen + 1));
  }
}

GBool JBIG2Stream::readUByte(Guint *x) {
  int c0;

  if ((c0 = curStr->getChar()) == EOF) {
    return gFalse;
  }
  *x = (Guint)c0;
  return gTrue;
}

GBool JBIG2Stream::readByte(int *x) {
 int c0;

  if ((c0 = curStr->getChar()) == EOF) {
    return gFalse;
  }
  *x = c0;
  if (c0 & 0x80) {
    *x |= -1 - 0xff;
  }
  return gTrue;
}

GBool JBIG2Stream::readUWord(Guint *x) {
  int c0, c1;

  if ((c0 = curStr->getChar()) == EOF ||
      (c1 = curStr->getChar()) == EOF) {
    return gFalse;
  }
  *x = (Guint)((c0 << 8) | c1);
  return gTrue;
}

GBool JBIG2Stream::readULong(Guint *x) {
  int c0, c1, c2, c3;

  if ((c0 = curStr->getChar()) == EOF ||
      (c1 = curStr->getChar()) == EOF ||
      (c2 = curStr->getChar()) == EOF ||
      (c3 = curStr->getChar()) == EOF) {
    return gFalse;
  }
  *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
  return gTrue;
}

GBool JBIG2Stream::readLong(int *x) {
  int c0, c1, c2, c3;

  if ((c0 = curStr->getChar()) == EOF ||
      (c1 = curStr->getChar()) == EOF ||
      (c2 = curStr->getChar()) == EOF ||
      (c3 = curStr->getChar()) == EOF) {
    return gFalse;
  }
  *x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
  if (c0 & 0x80) {
    *x |= -1 - (int)0xffffffff;
  }
  return gTrue;
}
