//========================================================================
//
// 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-2010, 2012, 2014-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2009 David Benjamin <davidben@mit.edu>
// Copyright (C) 2011 Edward Jiang <ejiang@google.com>
// Copyright (C) 2012 William Bader <williambader@hotmail.com>
// Copyright (C) 2012 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2013, 2014 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2015 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
// Copyright (C) 2019 LE GARREC Vincent <legarrec.vincent@gmail.com>
//
// 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>

#include <stdlib.h>
#include <limits.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;
  unsigned int prefixLen;
  unsigned int rangeLen;		// can also be LOW, OOB, or EOT
  unsigned int 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.
  bool decodeInt(int *x, JBIG2HuffmanTable *table);

  unsigned int readBits(unsigned int n);
  unsigned int readBit();

  // Sort the table by prefix length and assign prefix values.
  static bool buildTable(JBIG2HuffmanTable *table, unsigned int len);

private:

  Stream *str;
  unsigned int buf;
  unsigned int bufLen;
};

JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() {
  str = nullptr;
  reset();
}

JBIG2HuffmanDecoder::~JBIG2HuffmanDecoder() {
}

void JBIG2HuffmanDecoder::reset() {
  buf = 0;
  bufLen = 0;
}

//~ optimize this
bool JBIG2HuffmanDecoder::decodeInt(int *x, JBIG2HuffmanTable *table) {
  unsigned int 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 false;
      }
      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 true;
    }
    ++i;
  }
  return false;
}

unsigned int JBIG2HuffmanDecoder::readBits(unsigned int n) {
  unsigned int 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;
}

unsigned int JBIG2HuffmanDecoder::readBit() {
  if (bufLen == 0) {
    buf = str->getChar();
    bufLen = 8;
  }
  --bufLen;
  return (buf >> bufLen) & 1;
}

bool JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, unsigned int len) {
  unsigned int 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
  if (table[0].rangeLen != jbig2HuffmanEOT) {
    i = 0;
    prefix = 0;
    table[i++].prefix = prefix++;
    for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) {
      if (table[i].prefixLen - table[i-1].prefixLen > 32) {
	error(errSyntaxError, -1, "Failed to build table for JBIG2 stream");
	return false;
      } else {
	prefix <<= table[i].prefixLen - table[i-1].prefixLen;
      }
      table[i].prefix = prefix++;
    }
  }

  return true;
}

//------------------------------------------------------------------------
// JBIG2MMRDecoder
//------------------------------------------------------------------------

class JBIG2MMRDecoder {
public:

  JBIG2MMRDecoder();
  ~JBIG2MMRDecoder();
  void setStream(Stream *strA) { str = strA; }
  void reset();
  int get2DCode();
  int getBlackCode();
  int getWhiteCode();
  unsigned int get24Bits();
  void skipTo(unsigned int length);

private:

  Stream *str;
  unsigned int buf;
  unsigned int bufLen;
  unsigned int nBytesRead;
};

JBIG2MMRDecoder::JBIG2MMRDecoder() {
  str = nullptr;
  reset();
}

JBIG2MMRDecoder::~JBIG2MMRDecoder() {
}

void JBIG2MMRDecoder::reset() {
  buf = 0;
  bufLen = 0;
  nBytesRead = 0;
}

int JBIG2MMRDecoder::get2DCode() {
  const CCITTCode *p = nullptr;

  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 if (bufLen < 8) {
    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 == nullptr || p->bits < 0) {
    error(errSyntaxError, str->getPos(), "Bad two dim code in JBIG2 MMR stream");
    return EOF;
  }
  bufLen -= p->bits;
  return p->n;
}

int JBIG2MMRDecoder::getWhiteCode() {
  const CCITTCode *p;
  unsigned int 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(errSyntaxError, 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;
  unsigned int 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);
      }
      if (unlikely((code & 0xff) < 64)) {
        break;
      }
      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(errSyntaxError, 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;
}

unsigned int JBIG2MMRDecoder::get24Bits() {
  while (bufLen < 24) {
    buf = (buf << 8) | (str->getChar() & 0xff);
    bufLen += 8;
    ++nBytesRead;
  }
  return (buf >> (bufLen - 24)) & 0xffffff;
}

void JBIG2MMRDecoder::skipTo(unsigned int length) {
  while (nBytesRead < length) {
    str->getChar();
    ++nBytesRead;
  }
}

//------------------------------------------------------------------------
// JBIG2Segment
//------------------------------------------------------------------------

enum JBIG2SegmentType {
  jbig2SegBitmap,
  jbig2SegSymbolDict,
  jbig2SegPatternDict,
  jbig2SegCodeTable
};

class JBIG2Segment {
public:

  JBIG2Segment(unsigned int segNumA) { segNum = segNumA; }
  virtual ~JBIG2Segment() {}
  JBIG2Segment(const JBIG2Segment &) = delete;
  JBIG2Segment& operator=(const JBIG2Segment &) = delete;
  void setSegNum(unsigned int segNumA) { segNum = segNumA; }
  unsigned int getSegNum() { return segNum; }
  virtual JBIG2SegmentType getType() = 0;

private:

  unsigned int segNum;
};

//------------------------------------------------------------------------
// JBIG2Bitmap
//------------------------------------------------------------------------

struct JBIG2BitmapPtr {
  unsigned char *p;
  int shift;
  int x;
};

class JBIG2Bitmap: public JBIG2Segment {
public:

  JBIG2Bitmap(unsigned int segNumA, int wA, int hA);
  ~JBIG2Bitmap();
  JBIG2SegmentType getType() override { return jbig2SegBitmap; }
  JBIG2Bitmap *copy() { return new JBIG2Bitmap(0, this); }
  JBIG2Bitmap *getSlice(unsigned int x, unsigned int y, unsigned int wA, unsigned int hA);
  void expand(int newH, unsigned int pixel);
  void clearToZero();
  void clearToOne();
  int getWidth() { return w; }
  int getHeight() { return h; }
  int getLineSize() { return line; }
  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, unsigned int combOp);
  unsigned char *getDataPtr() { return data; }
  int getDataSize() { return h * line; }
  bool isOk() { return data != nullptr; }

private:

  JBIG2Bitmap(unsigned int segNumA, JBIG2Bitmap *bitmap);

  int w, h, line;
  unsigned char *data;
};

JBIG2Bitmap::JBIG2Bitmap(unsigned int 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(errSyntaxError, -1, "invalid width/height");
    data = nullptr;
    return;
  }
  // need to allocate one extra guard byte for use in combine()
  data = (unsigned char *)gmalloc_checkoverflow(h * line + 1);
  if (data != nullptr) {
    data[h * line] = 0;
  }
}

JBIG2Bitmap::JBIG2Bitmap(unsigned int segNumA, JBIG2Bitmap *bitmap):
  JBIG2Segment(segNumA)
{
  if (unlikely(bitmap == nullptr)) {
    error(errSyntaxError, -1, "NULL bitmap in JBIG2Bitmap");
    w = h = line = 0;
    data = nullptr;
    return;
  }

  w = bitmap->w;
  h = bitmap->h;
  line = bitmap->line;

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

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

//~ optimize this
JBIG2Bitmap *JBIG2Bitmap::getSlice(unsigned int x, unsigned int y, unsigned int wA, unsigned int hA) {
  JBIG2Bitmap *slice;
  unsigned int xx, yy;

  if (!data) {
      return nullptr;
  }

  slice = new JBIG2Bitmap(0, wA, hA);
  if (slice->isOk()) {
    slice->clearToZero();
    for (yy = 0; yy < hA; ++yy) {
      for (xx = 0; xx < wA; ++xx) {
        if (getPixel(x + xx, y + yy)) {
	  slice->setPixel(xx, yy);
        }
      }
    }
  } else {
    delete slice;
    slice = nullptr;
  }
  return slice;
}

void JBIG2Bitmap::expand(int newH, unsigned int pixel) {
  if (newH <= h || line <= 0 || newH >= (INT_MAX - 1) / line) {
    error(errSyntaxError, -1, "invalid width/height");
    gfree(data);
    data = nullptr;
    return;
  }
  // need to allocate one extra guard byte for use in combine()
  data = (unsigned char *)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 = nullptr;
    ptr->shift = 0; // make gcc happy
    ptr->x = 0; // make gcc happy
  } 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 = nullptr;
    } 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,
			  unsigned int combOp) {
  int x0, x1, y0, y1, xx, yy;
  unsigned char *srcPtr, *destPtr;
  unsigned int src0, src1, src, dest, s1, s2, m1, m2, m3;
  bool oneByte;

  // check for the pathological case where y = -2^31
  if (y < -0x7fffffff) {
    return;
  }
  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) {
    if (unlikely((y + yy >= h) || (y + yy < 0)))
      continue;

    // 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(unsigned int segNumA, unsigned int sizeA);
  ~JBIG2SymbolDict();
  JBIG2SegmentType getType() override { return jbig2SegSymbolDict; }
  unsigned int getSize() { return size; }
  void setBitmap(unsigned int idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
  JBIG2Bitmap *getBitmap(unsigned int idx) { return bitmaps[idx]; }
  bool isOk() { return bitmaps != nullptr; }
  void setGenericRegionStats(JArithmeticDecoderStats *stats)
    { genericRegionStats = stats; }
  void setRefinementRegionStats(JArithmeticDecoderStats *stats)
    { refinementRegionStats = stats; }
  JArithmeticDecoderStats *getGenericRegionStats()
    { return genericRegionStats; }
  JArithmeticDecoderStats *getRefinementRegionStats()
    { return refinementRegionStats; }

private:

  unsigned int size;
  JBIG2Bitmap **bitmaps;
  JArithmeticDecoderStats *genericRegionStats;
  JArithmeticDecoderStats *refinementRegionStats;
};

JBIG2SymbolDict::JBIG2SymbolDict(unsigned int segNumA, unsigned int sizeA):
  JBIG2Segment(segNumA)
{
  unsigned int i;

  size = sizeA;
  bitmaps = (JBIG2Bitmap **)gmallocn_checkoverflow(size, sizeof(JBIG2Bitmap *));
  if (!bitmaps) size = 0;
  for (i = 0; i < size; ++i) {
    bitmaps[i] = nullptr;
  }
  genericRegionStats = nullptr;
  refinementRegionStats = nullptr;
}

JBIG2SymbolDict::~JBIG2SymbolDict() {
  unsigned int 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(unsigned int segNumA, unsigned int sizeA);
  ~JBIG2PatternDict();
  JBIG2SegmentType getType() override { return jbig2SegPatternDict; }
  unsigned int getSize() { return size; }
  void setBitmap(unsigned int idx, JBIG2Bitmap *bitmap) { if (likely(idx < size)) bitmaps[idx] = bitmap; }
  JBIG2Bitmap *getBitmap(unsigned int idx) { return (idx < size) ? bitmaps[idx] : nullptr; }

private:

  unsigned int size;
  JBIG2Bitmap **bitmaps;
};

JBIG2PatternDict::JBIG2PatternDict(unsigned int segNumA, unsigned int sizeA):
  JBIG2Segment(segNumA)
{
  bitmaps = (JBIG2Bitmap **)gmallocn_checkoverflow(sizeA, sizeof(JBIG2Bitmap *));
  if (bitmaps) {
    size = sizeA;
  } else {
    size = 0;
    error(errSyntaxError, -1, "JBIG2PatternDict: can't allocate bitmaps");
  }
}

JBIG2PatternDict::~JBIG2PatternDict() {
  unsigned int i;

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

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

class JBIG2CodeTable: public JBIG2Segment {
public:

  JBIG2CodeTable(unsigned int segNumA, JBIG2HuffmanTable *tableA);
  ~JBIG2CodeTable();
  JBIG2SegmentType getType() override { return jbig2SegCodeTable; }
  JBIG2HuffmanTable *getHuffTable() { return table; }

private:

  JBIG2HuffmanTable *table;
};

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

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

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

JBIG2Stream::JBIG2Stream(Stream *strA, Object &&globalsStreamA, Object *globalsStreamRefA):
  FilterStream(strA)
{
  pageBitmap = nullptr;

  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();

  if (globalsStreamA.isStream()) {
    globalsStream = std::move(globalsStreamA);
    if (globalsStreamRefA->isRef())
      globalsStreamRef = globalsStreamRefA->getRef();
  }

  segments = globalSegments = nullptr;
  curStr = nullptr;
  dataPtr = dataEnd = nullptr;
}

JBIG2Stream::~JBIG2Stream() {
  close();
  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 std::vector<JBIG2Segment*>();
  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 std::vector<JBIG2Segment*>();
  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 = nullptr;
  }
}

void JBIG2Stream::close() {
  if (pageBitmap) {
    delete pageBitmap;
    pageBitmap = nullptr;
  }
  if (segments) {
    for (auto entry : *segments) {
      delete entry;
    }
    delete segments;
    segments = nullptr;
  }
  if (globalSegments) {
    for (auto entry : *globalSegments) {
      delete entry;
    }
    delete globalSegments;
    globalSegments = nullptr;
  }
  dataPtr = dataEnd = nullptr;
  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;
}

Goffset JBIG2Stream::getPos() {
  if (pageBitmap == nullptr) {
    return 0;
  }
  return dataPtr - pageBitmap->getDataPtr();
}

int JBIG2Stream::getChars(int nChars, unsigned char *buffer) {
  int n, i;

  if (nChars <= 0 || !dataPtr) {
    return 0;
  }
  if (dataEnd - dataPtr < nChars) {
    n = (int)(dataEnd - dataPtr);
  } else {
    n = nChars;
  }
  for (i = 0; i < n; ++i) {
    buffer[i] = *dataPtr++ ^ 0xff;
  }
  return n;
}

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

bool JBIG2Stream::isBinary(bool last) {
  return str->isBinary(true);
}

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

  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 (unsigned int i = 0; i < (nRefSegs + 9) >> 3; ++i) {
	if ((c1 = curStr->getChar()) == EOF) {
	  goto eofError1;
	}
      }
    }

    // referred-to segment numbers
    refSegs = (unsigned int *)gmallocn(nRefSegs, sizeof(unsigned int));
    if (segNum <= 256) {
      for (unsigned int i = 0; i < nRefSegs; ++i) {
	if (!readUByte(&refSegs[i])) {
	  goto eofError2;
	}
      }
    } else if (segNum <= 65536) {
      for (unsigned int i = 0; i < nRefSegs; ++i) {
	if (!readUWord(&refSegs[i])) {
	  goto eofError2;
	}
      }
    } else {
      for (unsigned int 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 = curStr->getPos();

    // check for missing page information segment
    if (!pageBitmap && ((segType >= 4 && segType <= 7) ||
			(segType >= 20 && segType <= 43))) {
      error(errSyntaxError, curStr->getPos(), "First JBIG2 segment associated with a page must be a page information segment");
      goto syntaxError;
    }

    // read the segment data
    switch (segType) {
    case 0:
      if (!readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs)) {
	goto syntaxError;
      }
      break;
    case 4:
      readTextRegionSeg(segNum, false, false, segLength, refSegs, nRefSegs);
      break;
    case 6:
      readTextRegionSeg(segNum, true, false, segLength, refSegs, nRefSegs);
      break;
    case 7:
      readTextRegionSeg(segNum, true, true, segLength, refSegs, nRefSegs);
      break;
    case 16:
      readPatternDictSeg(segNum, segLength);
      break;
    case 20:
      readHalftoneRegionSeg(segNum, false, false, segLength,
			    refSegs, nRefSegs);
      break;
    case 22:
      readHalftoneRegionSeg(segNum, true, false, segLength,
			    refSegs, nRefSegs);
      break;
    case 23:
      readHalftoneRegionSeg(segNum, true, true, segLength,
			    refSegs, nRefSegs);
      break;
    case 36:
      readGenericRegionSeg(segNum, false, false, segLength);
      break;
    case 38:
      readGenericRegionSeg(segNum, true, false, segLength);
      break;
    case 39:
      readGenericRegionSeg(segNum, true, true, segLength);
      break;
    case 40:
      readGenericRefinementRegionSeg(segNum, false, false, segLength,
				     refSegs, nRefSegs);
      break;
    case 42:
      readGenericRefinementRegionSeg(segNum, true, false, segLength,
				     refSegs, nRefSegs);
      break;
    case 43:
      readGenericRefinementRegionSeg(segNum, true, true, 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(errSyntaxError, curStr->getPos(), "Unknown segment type in JBIG2 stream");
      for (unsigned int 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) {

      Goffset segExtraBytes = segDataPos + segLength - curStr->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(errSyntaxError, curStr->getPos(), "{0:lld} extraneous byte{1:s} after segment",
	      segExtraBytes, (segExtraBytes > 1) ? "s" : "");
	
	// Burn through the remaining bytes -- inefficient, but
	// hopefully we're not doing this much
	
	int trash;
	for (Goffset 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(errSyntaxError, curStr->getPos(), "Previous segment handler read too many bytes");
	
      }

    }
    
    gfree(refSegs);
  }

  return;

 syntaxError:
  gfree(refSegs);
  return;

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

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

  symWidths = nullptr;

  // 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 std::vector<JBIG2Segment*>();
  numInputSyms = 0;
  for (i = 0; i < nRefSegs; ++i) {
    // This is need by bug 12014, returning false 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) {
	j = ((JBIG2SymbolDict *)seg)->getSize();
	if (numInputSyms > UINT_MAX - j) {
	  error(errSyntaxError, curStr->getPos(), "Too many input symbols in JBIG2 symbol dictionary");
	  delete codeTables;
	  goto eofError;
	}
	numInputSyms += j;
      } else if (seg->getType() == jbig2SegCodeTable) {
	codeTables->push_back(seg);
      }
    } else {
      delete codeTables;
      return false;
    }
  }
  if (numInputSyms > UINT_MAX - numNewSyms) {
    error(errSyntaxError, curStr->getPos(), "Too many input symbols in JBIG2 symbol dictionary");
    delete codeTables;
    goto eofError;
  }

  // compute symbol code length, per 6.5.8.2.3
  //  symCodeLen = ceil( log2( numInputSyms + numNewSyms ) )
  i = numInputSyms + numNewSyms;
  if (i <= 1) {
    symCodeLen = huff ? 1 : 0;
  } else {
    --i;
    symCodeLen = 0;
    // i = floor((numSyms-1) / 2^symCodeLen)
    while (i > 0) {
      ++symCodeLen;
      i >>= 1;
    }
  }

  // get the input symbol bitmaps
  bitmaps = (JBIG2Bitmap **)gmallocn_checkoverflow(numInputSyms + numNewSyms,
				     sizeof(JBIG2Bitmap *));
  if (!bitmaps && (numInputSyms + numNewSyms > 0)) {
    error(errSyntaxError, curStr->getPos(), "Too many input symbols in JBIG2 symbol dictionary");
    delete codeTables;
    goto eofError;
  }
  for (i = 0; i < numInputSyms + numNewSyms; ++i) {
    bitmaps[i] = nullptr;
  }
  k = 0;
  inputSymbolDict = nullptr;
  for (i = 0; i < nRefSegs; ++i) {
    seg = findSegment(refSegs[i]);
    if (seg != nullptr && seg->getType() == jbig2SegSymbolDict) {
      inputSymbolDict = (JBIG2SymbolDict *)seg;
      for (j = 0; j < inputSymbolDict->getSize(); ++j) {
	bitmaps[k++] = inputSymbolDict->getBitmap(j);
      }
    }
  }

  // get the Huffman tables
  huffDHTable = huffDWTable = nullptr; // make gcc happy
  huffBMSizeTable = huffAggInstTable = nullptr; // make gcc happy
  i = 0;
  if (huff) {
    if (huffDH == 0) {
      huffDHTable = huffTableD;
    } else if (huffDH == 1) {
      huffDHTable = huffTableE;
    } else {
      if (i >= codeTables->size()) {
	goto codeTableError;
      }
      huffDHTable = ((JBIG2CodeTable *)(*codeTables)[i++])->getHuffTable();
    }
    if (huffDW == 0) {
      huffDWTable = huffTableB;
    } else if (huffDW == 1) {
      huffDWTable = huffTableC;
    } else {
      if (i >= codeTables->size()) {
	goto codeTableError;
      }
      huffDWTable = ((JBIG2CodeTable *)(*codeTables)[i++])->getHuffTable();
    }
    if (huffBMSize == 0) {
      huffBMSizeTable = huffTableA;
    } else {
      if (i >= codeTables->size()) {
	goto codeTableError;
      }
      huffBMSizeTable =
	  ((JBIG2CodeTable *)(*codeTables)[i++])->getHuffTable();
    }
    if (huffAggInst == 0) {
      huffAggInstTable = huffTableA;
    } else {
      if (i >= codeTables->size()) {
	goto codeTableError;
      }
      huffAggInstTable =
	  ((JBIG2CodeTable *)(*codeTables)[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, nullptr);
    }
    resetIntStats(symCodeLen);
    arithDecoder->start();
  }

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

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

  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 && (unsigned int)-dh >= symHeight) {
      error(errSyntaxError, curStr->getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
      goto syntaxError;
    }
    symHeight += dh;
    if (unlikely(symHeight > 0x40000000)) {
      error(errSyntaxError, curStr->getPos(), "Bad height value in JBIG2 symbol dictionary");
      goto syntaxError;
    }
    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 && (unsigned int)-dw >= symWidth) {
	error(errSyntaxError, curStr->getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
	goto syntaxError;
      }
      symWidth += dw;
      if (i >= numNewSyms) {
	error(errSyntaxError, curStr->getPos(), "Too many symbols in JBIG2 symbol dictionary");
	goto syntaxError;
      }

      // 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);
	  }
	  if (symID >= numInputSyms + i) {
	    error(errSyntaxError, curStr->getPos(), "Invalid symbol ID in JBIG2 symbol dictionary");
	    goto syntaxError;
	  }
	  refBitmap = bitmaps[symID];
	  if (unlikely(refBitmap == nullptr)) {
	    error(errSyntaxError, curStr->getPos(), "Invalid ref bitmap for symbol ID {0:ud} in JBIG2 symbol dictionary", symID);
	    goto syntaxError;
	  }
	  bitmaps[numInputSyms + i] =
	      readGenericRefinementRegion(symWidth, symHeight,
					  sdrTemplate, false,
					  refBitmap, refDX, refDY,
					  sdrATX, sdrATY);
	  //~ do we need to use the bmSize value here (in Huffman mode)?
	} else {
	  bitmaps[numInputSyms + i] =
	      readTextRegion(huff, true, symWidth, symHeight,
			     refAggNum, 0, numInputSyms + i, nullptr,
			     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(false, symWidth, symHeight,
			      sdTemplate, false, false, nullptr,
			      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();
	if (unlikely(p == nullptr)) {
	  delete collBitmap;
	  goto syntaxError;
	}
	for (k = 0; k < (unsigned int)bmSize; ++k) {
	  if ((c = curStr->getChar()) == EOF) {
	    memset(p, 0, bmSize - k);
	    break;
	  }
	  *p++ = (unsigned char)c;
	}
      } else {
	collBitmap = readGenericBitmap(true, totalWidth, symHeight,
				       0, false, false, nullptr, nullptr, nullptr,
				       bmSize);
      }
      if (likely(collBitmap != nullptr)) {
	x = 0;
	for (; j < i; ++j) {
	  bitmaps[numInputSyms + j] =
	      collBitmap->getSlice(x, 0, symWidths[j], symHeight);
	  x += symWidths[j];
	}
	delete collBitmap;
      } else {
	error(errSyntaxError, curStr->getPos(), "collBitmap was null");
	goto syntaxError;
      }
    }
  }

  // create the symbol dict object
  symbolDict = new JBIG2SymbolDict(segNum, numExSyms);
  if (!symbolDict->isOk()) {
    delete symbolDict;
    goto syntaxError;
  }

  // exported symbol list
  i = j = 0;
  ex = false;
  run = 0; // initialize it once in case the first decodeInt fails
           // we do not want to use uninitialized memory
  while (i < numInputSyms + numNewSyms) {
    if (huff) {
      huffDecoder->decodeInt(&run, huffTableA);
    } else {
      arithDecoder->decodeInt(&run, iaexStats);
    }
    if (i + run > numInputSyms + numNewSyms ||
	(ex && j + run > numExSyms)) {
      error(errSyntaxError, curStr->getPos(), "Too many exported symbols in JBIG2 symbol dictionary");
      for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, nullptr);
      delete symbolDict;
      goto syntaxError;
    }
    if (ex) {
      for (cnt = 0; cnt < run; ++cnt) {
	symbolDict->setBitmap(j++, bitmaps[i++]->copy());
      }
    } else {
      i += run;
    }
    ex = !ex;
  }
  if (j != numExSyms) {
    error(errSyntaxError, curStr->getPos(), "Too few symbols in JBIG2 symbol dictionary");
    for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, nullptr);
    delete symbolDict;
    goto syntaxError;
  }

  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->push_back(symbolDict);

  return true;

 codeTableError:
  error(errSyntaxError, curStr->getPos(), "Missing code table in JBIG2 symbol dictionary");
  delete codeTables;

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

 eofError:
  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
  return false;
}

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

  // 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 std::vector<JBIG2Segment*>();
  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->push_back(seg);
      }
    } else {
      error(errSyntaxError, curStr->getPos(), "Invalid segment reference in JBIG2 text region");
      delete codeTables;
      return;
    }
  }
  i = numSyms;
  if (i <= 1) {
    symCodeLen = huff ? 1 : 0;
  } else {
    --i;
    symCodeLen = 0;
    // i = floor((numSyms-1) / 2^symCodeLen)
    while (i > 0) {
      ++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 = nullptr; // make gcc happy
  huffRDWTable = huffRDHTable = nullptr; // make gcc happy
  huffRDXTable = huffRDYTable = huffRSizeTable = nullptr; // make gcc happy
  i = 0;
  if (huff) {
    if (huffFS == 0) {
      huffFSTable = huffTableF;
    } else if (huffFS == 1) {
      huffFSTable = huffTableG;
    } else {
      if (i >= codeTables->size()) {
	goto codeTableError;
      }
      huffFSTable = ((JBIG2CodeTable *)(*codeTables)[i++])->getHuffTable();
    }
    if (huffDS == 0) {
      huffDSTable = huffTableH;
    } else if (huffDS == 1) {
      huffDSTable = huffTableI;
    } else if (huffDS == 2) {
      huffDSTable = huffTableJ;
    } else {
      if (i >= codeTables->size()) {
	goto codeTableError;
      }
      huffDSTable = ((JBIG2CodeTable *)(*codeTables)[i++])->getHuffTable();
    }
    if (huffDT == 0) {
      huffDTTable = huffTableK;
    } else if (huffDT == 1) {
      huffDTTable = huffTableL;
    } else if (huffDT == 2) {
      huffDTTable = huffTableM;
    } else {
      if (i >= codeTables->size()) {
	goto codeTableError;
      }
      huffDTTable = ((JBIG2CodeTable *)(*codeTables)[i++])->getHuffTable();
    }
    if (huffRDW == 0) {
      huffRDWTable = huffTableN;
    } else if (huffRDW == 1) {
      huffRDWTable = huffTableO;
    } else {
      if (i >= codeTables->size()) {
	goto codeTableError;
      }
      huffRDWTable = ((JBIG2CodeTable *)(*codeTables)[i++])->getHuffTable();
    }
    if (huffRDH == 0) {
      huffRDHTable = huffTableN;
    } else if (huffRDH == 1) {
      huffRDHTable = huffTableO;
    } else {
      if (i >= codeTables->size()) {
	goto codeTableError;
      }
      huffRDHTable = ((JBIG2CodeTable *)(*codeTables)[i++])->getHuffTable();
    }
    if (huffRDX == 0) {
      huffRDXTable = huffTableN;
    } else if (huffRDX == 1) {
      huffRDXTable = huffTableO;
    } else {
      if (i >= codeTables->size()) {
	goto codeTableError;
      }
      huffRDXTable = ((JBIG2CodeTable *)(*codeTables)[i++])->getHuffTable();
    }
    if (huffRDY == 0) {
      huffRDYTable = huffTableN;
    } else if (huffRDY == 1) {
      huffRDYTable = huffTableO;
    } else {
      if (i >= codeTables->size()) {
	goto codeTableError;
      }
      huffRDYTable = ((JBIG2CodeTable *)(*codeTables)[i++])->getHuffTable();
    }
    if (huffRSize == 0) {
      huffRSizeTable = huffTableA;
    } else {
      if (i >= codeTables->size()) {
	goto codeTableError;
      }
      huffRSizeTable =
	  ((JBIG2CodeTable *)(*codeTables)[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;
    if (!JBIG2HuffmanDecoder::buildTable(runLengthTab, 35)) {
      huff = false;
    }
  }

  if (huff) {
    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) {
	if (unlikely(i == 0)) ++i;
	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;
    if (!JBIG2HuffmanDecoder::buildTable(symCodeTab, numSyms)) {
      huff = false;
      gfree(symCodeTab);
      symCodeTab = nullptr;
    }
    huffDecoder->reset();

  // set up the arithmetic decoder
  }

  if (!huff) {
    resetIntStats(symCodeLen);
    arithDecoder->start();
  }
  if (refine) {
    resetRefinementStats(templ, nullptr);
  }

  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);

  if (bitmap) {
    // 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->push_back(bitmap);
    }
  }

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

  return;

 codeTableError:
  error(errSyntaxError, curStr->getPos(), "Missing code table in JBIG2 text region");
  delete codeTables;
  gfree(syms);
  return;

 eofError:
  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
  return;
}

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

  strips = 1 << logStrips;

  // allocate the bitmap
  bitmap = new JBIG2Bitmap(0, w, h);
  if (!bitmap->isOk()) {
    delete bitmap;
    return nullptr;
  }
  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
    // (this loop test is here to avoid an infinite loop with damaged
    // JBIG2 streams where the normal loop exit doesn't get triggered)
    while (inst < numInstances) {

      // 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 = (unsigned int)j;
	} else {
	  symID = huffDecoder->readBits(symCodeLen);
	}
      } else {
	symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
      }

      if (symID >= (unsigned int)numSyms) {
	error(errSyntaxError, curStr->getPos(), "Invalid symbol number in JBIG2 text region");
	if (unlikely(numInstances - inst > 0x800)) {
	  // don't loop too often with damaged JBIg2 streams
	  delete bitmap;
	  return nullptr;
	}
      } else {

	// get the symbol bitmap
	symbolBitmap = nullptr;
	if (refine) {
	  if (huff) {
	    ri = (int)huffDecoder->readBit();
	  } else {
	    arithDecoder->decodeInt(&ri, iariStats);
	  }
	} else {
	  ri = 0;
	}
	if (ri) {
	  bool decodeSuccess;
	  if (huff) {
	    decodeSuccess = huffDecoder->decodeInt(&rdw, huffRDWTable);
	    decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdh, huffRDHTable);
	    decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdx, huffRDXTable);
	    decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdy, huffRDYTable);
	    decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&bmSize, huffRSizeTable);
	    huffDecoder->reset();
	    arithDecoder->start();
	  } else {
	    decodeSuccess = arithDecoder->decodeInt(&rdw, iardwStats);
	    decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdh, iardhStats);
	    decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdx, iardxStats);
	    decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdy, iardyStats);
	  }
	  
	  if (decodeSuccess && syms[symID])
	  {
	    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, false, syms[symID],
					  refDX, refDY, atx, aty);
	  }
	  //~ do we need to use the bmSize value here (in Huffman mode)?
	} else {
	  symbolBitmap = syms[symID];
	}

	if (symbolBitmap) {
	  // combine the symbol bitmap into the region bitmap
	  //~ something is wrong here - refCorner shouldn't degenerate into
	  //~   two cases
	  bw = symbolBitmap->getWidth() - 1;
	  if (unlikely(symbolBitmap->getHeight() == 0)) {
	    error(errSyntaxError, curStr->getPos(), "Invalid symbol bitmap height");
	    if (ri) {
	      delete symbolBitmap;
	    }
	    delete bitmap;
	    return nullptr;
	  }
	  bh = symbolBitmap->getHeight() - 1;
	  if (transposed) {
	    if (unlikely(s > 2 * bitmap->getHeight())) {
	      error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine");
	      if (ri) {
	        delete symbolBitmap;
	      }
	      delete bitmap;
	      return nullptr;
	    }
	    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
	      if (unlikely(tt - (int) bh > 2 * bitmap->getHeight())) {
		error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine");
		if (ri) {
		  delete symbolBitmap;
		}
		delete bitmap;
		return nullptr;
	      }
	      bitmap->combine(symbolBitmap, s, tt - bh, combOp);
	      break;
	    case 1: // top left
	      if (unlikely(tt > 2 * bitmap->getHeight())) {
		error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine");
		if (ri) {
		  delete symbolBitmap;
		}
		delete bitmap;
		return nullptr;
	      }
	      bitmap->combine(symbolBitmap, s, tt, combOp);
	      break;
	    case 2: // bottom right
	      if (unlikely(tt - (int) bh > 2 * bitmap->getHeight())) {
		error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine");
		if (ri) {
		  delete symbolBitmap;
		}
		delete bitmap;
		return nullptr;
	      }
	      bitmap->combine(symbolBitmap, s, tt - bh, combOp);
	      break;
	    case 3: // top right
	      if (unlikely(tt > 2 * bitmap->getHeight())) {
		error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine");
		if (ri) {
		  delete symbolBitmap;
		}
		delete bitmap;
		return nullptr;
	      }
	      bitmap->combine(symbolBitmap, s, tt, combOp);
	      break;
	    }
	    s += bw;
	  }
	  if (ri) {
	    delete symbolBitmap;
	  }
	} else {
	  // NULL symbolBitmap only happens on error
	  delete bitmap;
	  return nullptr;
	}
      }

      // 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(unsigned int segNum, unsigned int length) {
  JBIG2PatternDict *patternDict;
  JBIG2Bitmap *bitmap;
  unsigned int flags, patternW, patternH, grayMax, templ, mmr;
  int atx[4], aty[4];
  unsigned int 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, nullptr);
    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, false, false, nullptr,
			     atx, aty, length - 7);

  if (!bitmap)
    return;

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

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

  // free memory
  delete bitmap;

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

  return;

 eofError:
  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
}

void JBIG2Stream::readHalftoneRegionSeg(unsigned int segNum, bool imm,
					bool lossless, unsigned int length,
					unsigned int *refSegs, unsigned int nRefSegs) {
  JBIG2Bitmap *bitmap;
  JBIG2Segment *seg;
  JBIG2PatternDict *patternDict;
  JBIG2Bitmap *skipBitmap;
  unsigned int *grayImg;
  JBIG2Bitmap *grayBitmap;
  JBIG2Bitmap *patternBitmap;
  unsigned int w, h, x, y, segInfoFlags, extCombOp;
  unsigned int flags, mmr, templ, enableSkip, combOp;
  unsigned int gridW, gridH, stepX, stepY, patW, patH;
  int atx[4], aty[4];
  int gridX, gridY, xx, yy, bit, j;
  unsigned int 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(errSyntaxError, curStr->getPos(), "Bad bitmap size in JBIG2 halftone segment");
    return;
  }
  if (gridH == 0 || gridW >= INT_MAX / gridH) {
    error(errSyntaxError, curStr->getPos(), "Bad grid size in JBIG2 halftone segment");
    return;
  }

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

  patternDict = (JBIG2PatternDict *)seg;
  i = patternDict->getSize();
  if (i <= 1) {
    bpp = 0;
  } else {
    --i;
    bpp = 0;
    // i = floor((size-1) / 2^bpp)
    while (i > 0) {
      ++bpp;
      i >>= 1;
    }
  }
  patternBitmap = patternDict->getBitmap(0);
  if (unlikely(patternBitmap == nullptr)) {
    error(errSyntaxError, curStr->getPos(), "Bad pattern bitmap");
    return;
  }
  patW = patternBitmap->getWidth();
  patH = patternBitmap->getHeight();

  // set up the arithmetic decoder
  if (!mmr) {
    resetGenericStats(templ, nullptr);
    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 = nullptr;
  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 = (unsigned int *)gmallocn(gridW * gridH, sizeof(unsigned int));
  memset(grayImg, 0, gridW * gridH * sizeof(unsigned int));
  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, false,
				   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]);
	if (unlikely(patternBitmap == nullptr)) {
	  delete skipBitmap;
	  delete bitmap;
	  gfree(grayImg);
	  error(errSyntaxError, curStr->getPos(), "Bad pattern bitmap");
	  return;
	}
	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->push_back(bitmap);
  }

  return;

 eofError:
  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
}

void JBIG2Stream::readGenericRegionSeg(unsigned int segNum, bool imm,
				       bool lossless, unsigned int length) {
  JBIG2Bitmap *bitmap;
  unsigned int w, h, x, y, segInfoFlags, extCombOp, rowCount;
  unsigned int 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, nullptr);
    arithDecoder->start();
  }

  // read the bitmap
  bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, false,
			     nullptr, atx, aty, mmr ? length - 18 : 0);
  if (!bitmap)
    return;

  // 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->push_back(bitmap);
  }

  // immediate generic segments can have an unspecified length, in
  // which case, a row count is stored at the end of the segment
  if (imm && length == 0xffffffff) {
    readULong(&rowCount);
  }

  return;

 eofError:
  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
}

inline void JBIG2Stream::mmrAddPixels(int a1, int blackPixels,
				      int *codingLine, int *a0i, int w) {
  if (a1 > codingLine[*a0i]) {
    if (a1 > w) {
      error(errSyntaxError, curStr->getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
      a1 = w;
    }
    if ((*a0i & 1) ^ blackPixels) {
      ++*a0i;
    }
    codingLine[*a0i] = a1;
  }
}

inline void JBIG2Stream::mmrAddPixelsNeg(int a1, int blackPixels,
					 int *codingLine, int *a0i, int w) {
  if (a1 > codingLine[*a0i]) {
    if (a1 > w) {
      error(errSyntaxError, curStr->getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
      a1 = w;
    }
    if ((*a0i & 1) ^ blackPixels) {
      ++*a0i;
    }
    codingLine[*a0i] = a1;
  } else if (a1 < codingLine[*a0i]) {
    if (a1 < 0) {
      error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 MMR code");
      a1 = 0;
    }
    while (*a0i > 0 && a1 <= codingLine[*a0i - 1]) {
      --*a0i;
    }
    codingLine[*a0i] = a1;
  }
}

JBIG2Bitmap *JBIG2Stream::readGenericBitmap(bool mmr, int w, int h,
					    int templ, bool tpgdOn,
					    bool useSkip, JBIG2Bitmap *skip,
					    int *atx, int *aty,
					    int mmrDataLength) {
  JBIG2Bitmap *bitmap;
  bool ltp;
  unsigned int ltpCX, cx, cx0, cx1, cx2;
  int *refLine, *codingLine;
  int code1, code2, code3;
  unsigned char *p0, *p1, *p2, *pp;
  unsigned char *atP0, *atP1, *atP2, *atP3;
  unsigned int buf0, buf1, buf2;
  unsigned int atBuf0, atBuf1, atBuf2, atBuf3;
  int atShift0, atShift1, atShift2, atShift3;
  unsigned char mask;
  int x, y, x0, x1, a0i, b1i, blackPixels, pix, i;

  bitmap = new JBIG2Bitmap(0, w, h);
  if (!bitmap->isOk()) {
    delete bitmap;
    return nullptr;
  }
  bitmap->clearToZero();

  //----- MMR decode

  if (mmr) {

    mmrDecoder->reset();
    // 0 <= codingLine[0] < codingLine[1] < ... < codingLine[n] = w
    // ---> max codingLine size = w + 1
    // refLine has one extra guard entry at the end
    // ---> max refLine size = w + 2
    codingLine = (int *)gmallocn_checkoverflow(w + 1, sizeof(int));
    refLine = (int *)gmallocn_checkoverflow(w + 2, sizeof(int));

    if (unlikely(!codingLine || !refLine)) {
      error(errSyntaxError, curStr->getPos(), "Bad width in JBIG2 generic bitmap");
      delete bitmap;
      return nullptr;
    }

    memset(refLine, 0, (w + 2) * sizeof(int));
    for (i = 0; i < w + 1; ++i) codingLine[i] = 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++] = w;
      refLine[i] = w;

      // decode a line
      codingLine[0] = 0;
      a0i = 0;
      b1i = 0;
      blackPixels = 0;
      // invariant:
      // refLine[b1i-1] <= codingLine[a0i] < refLine[b1i] < refLine[b1i+1] <= w
      // exception at left edge:
      //   codingLine[a0i = 0] = refLine[b1i = 0] = 0 is possible
      // exception at right edge:
      //   refLine[b1i] = refLine[b1i+1] = w is possible
      while (codingLine[a0i] < w) {
	code1 = mmrDecoder->get2DCode();
	switch (code1) {
	case twoDimPass:
          if (unlikely(b1i + 1 >= w + 2)) {
            break;
          }
          mmrAddPixels(refLine[b1i + 1], blackPixels, codingLine, &a0i, w);
          if (refLine[b1i + 1] < w) {
            b1i += 2;
          }
          break;
	case twoDimHoriz:
          code1 = code2 = 0;
          if (blackPixels) {
            do {
              code1 += code3 = mmrDecoder->getBlackCode();
            } while (code3 >= 64);
            do {
              code2 += code3 = mmrDecoder->getWhiteCode();
            } while (code3 >= 64);
          } else {
            do {
              code1 += code3 = mmrDecoder->getWhiteCode();
            } while (code3 >= 64);
            do {
              code2 += code3 = mmrDecoder->getBlackCode();
            } while (code3 >= 64);
          }
          mmrAddPixels(codingLine[a0i] + code1, blackPixels,
		       codingLine, &a0i, w);
          if (codingLine[a0i] < w) {
            mmrAddPixels(codingLine[a0i] + code2, blackPixels ^ 1,
			 codingLine, &a0i, w);
          }
          while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
            b1i += 2;
          }
          break;
	case twoDimVertR3:
          if (unlikely(b1i >= w + 2)) {
            break;
          }
          mmrAddPixels(refLine[b1i] + 3, blackPixels, codingLine, &a0i, w);
          blackPixels ^= 1;
          if (codingLine[a0i] < w) {
            ++b1i;
            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
              b1i += 2;
            }
          }
          break;
	case twoDimVertR2:
          if (unlikely(b1i >= w + 2)) {
            break;
          }
          mmrAddPixels(refLine[b1i] + 2, blackPixels, codingLine, &a0i, w);
          blackPixels ^= 1;
          if (codingLine[a0i] < w) {
            ++b1i;
            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
              b1i += 2;
            }
          }
          break;
	case twoDimVertR1:
          if (unlikely(b1i >= w + 2)) {
            break;
          }
          mmrAddPixels(refLine[b1i] + 1, blackPixels, codingLine, &a0i, w);
          blackPixels ^= 1;
          if (codingLine[a0i] < w) {
            ++b1i;
            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
              b1i += 2;
            }
          }
          break;
	case twoDimVert0:
          if (unlikely(b1i >= w + 2)) {
            break;
          }
          mmrAddPixels(refLine[b1i], blackPixels, codingLine, &a0i, w);
          blackPixels ^= 1;
          if (codingLine[a0i] < w) {
            ++b1i;
            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
              b1i += 2;
            }
          }
          break;
	case twoDimVertL3:
          if (unlikely(b1i >= w + 2)) {
            break;
          }
          mmrAddPixelsNeg(refLine[b1i] - 3, blackPixels, codingLine, &a0i, w);
          blackPixels ^= 1;
          if (codingLine[a0i] < w) {
            if (b1i > 0) {
              --b1i;
            } else {
              ++b1i;
            }
            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
              b1i += 2;
            }
          }
          break;
	case twoDimVertL2:
          if (unlikely(b1i >= w + 2)) {
            break;
          }
          mmrAddPixelsNeg(refLine[b1i] - 2, blackPixels, codingLine, &a0i, w);
          blackPixels ^= 1;
          if (codingLine[a0i] < w) {
            if (b1i > 0) {
              --b1i;
            } else {
              ++b1i;
            }
            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
              b1i += 2;
            }
          }
          break;
	case twoDimVertL1:
          if (unlikely(b1i >= w + 2)) {
            break;
          }
          mmrAddPixelsNeg(refLine[b1i] - 1, blackPixels, codingLine, &a0i, w);
          blackPixels ^= 1;
          if (codingLine[a0i] < w) {
            if (b1i > 0) {
              --b1i;
            } else {
              ++b1i;
            }
            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
              b1i += 2;
            }
          }
          break;
	case EOF:
          mmrAddPixels(w, 0, codingLine, &a0i, w);
          break;
	default:
	  error(errSyntaxError, curStr->getPos(), "Illegal code in JBIG2 MMR bitmap data");
          mmrAddPixels(w, 0, codingLine, &a0i, w);
	  break;
	}
      }

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

    if (mmrDataLength >= 0) {
      mmrDecoder->skipTo(mmrDataLength);
    } else {
      if (mmrDecoder->get24Bits() != 0x001001) {
	error(errSyntaxError, curStr->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) {
	  if (y > 0) {
	    bitmap->duplicateRow(y, y-1);
	  }
	  continue;
	}
      }

      switch (templ) {
      case 0:

	// set up the context
	p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
	buf2 = *p2++ << 8;
	if (y >= 1) {
	  p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
	  buf1 = *p1++ << 8;
	  if (y >= 2) {
	    p0 = bitmap->getDataPtr() + (y - 2) * bitmap->getLineSize();
	    buf0 = *p0++ << 8;
	  } else {
	    p0 = nullptr;
	    buf0 = 0;
	  }
	} else {
	  p1 = p0 = nullptr;
	  buf1 = buf0 = 0;
	}

	if (atx[0] >= -8 && atx[0] <= 8 &&
	    atx[1] >= -8 && atx[1] <= 8 &&
	    atx[2] >= -8 && atx[2] <= 8 &&
	    atx[3] >= -8 && atx[3] <= 8) {
	  // set up the adaptive context
	  if (y + aty[0] >= 0 && y + aty[0] < bitmap->getHeight()) {
	    atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
	    atBuf0 = *atP0++ << 8;
	  } else {
	    atP0 = nullptr;
	    atBuf0 = 0;
	  }
	  atShift0 = 15 - atx[0];
	  if (y + aty[1] >= 0 && y + aty[1] < bitmap->getHeight()) {
	    atP1 = bitmap->getDataPtr() + (y + aty[1]) * bitmap->getLineSize();
	    atBuf1 = *atP1++ << 8;
	  } else {
	    atP1 = nullptr;
	    atBuf1 = 0;
	  }
	  atShift1 = 15 - atx[1];
	  if (y + aty[2] >= 0 && y + aty[2] < bitmap->getHeight()) {
	    atP2 = bitmap->getDataPtr() + (y + aty[2]) * bitmap->getLineSize();
	    atBuf2 = *atP2++ << 8;
	  } else {
	    atP2 = nullptr;
	    atBuf2 = 0;
	  }
	  atShift2 = 15 - atx[2];
	  if (y + aty[3] >= 0 && y + aty[3] < bitmap->getHeight()) {
	    atP3 = bitmap->getDataPtr() + (y + aty[3]) * bitmap->getLineSize();
	    atBuf3 = *atP3++ << 8;
	  } else {
	    atP3 = nullptr;
	    atBuf3 = 0;
	  }
	  atShift3 = 15 - atx[3];

	  // decode the row
	  for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
	    if (x0 + 8 < w) {
	      if (p0) {
		buf0 |= *p0++;
	      }
	      if (p1) {
		buf1 |= *p1++;
	      }
	      buf2 |= *p2++;
	      if (atP0) {
		atBuf0 |= *atP0++;
	      }
	      if (atP1) {
		atBuf1 |= *atP1++;
	      }
	      if (atP2) {
		atBuf2 |= *atP2++;
	      }
	      if (atP3) {
		atBuf3 |= *atP3++;
	      }
	    }
	    for (x1 = 0, mask = 0x80; x1 < 8 && x < w; ++x1, ++x, mask >>= 1) {

	      // build the context
	      cx0 = (buf0 >> 14) & 0x07;
	      cx1 = (buf1 >> 13) & 0x1f;
	      cx2 = (buf2 >> 16) & 0x0f;
	      cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
		   (((atBuf0 >> atShift0) & 1) << 3) |
		   (((atBuf1 >> atShift1) & 1) << 2) |
		   (((atBuf2 >> atShift2) & 1) << 1) |
		   ((atBuf3 >> atShift3) & 1);

	      // check for a skipped pixel
	      if (!(useSkip && skip->getPixel(x, y))) {

		// decode the pixel
		if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
		  *pp |= mask;
		  buf2 |= 0x8000;
		  if (aty[0] == 0) {
		    atBuf0 |= 0x8000;
		  }
		  if (aty[1] == 0) {
		    atBuf1 |= 0x8000;
		  }
		  if (aty[2] == 0) {
		    atBuf2 |= 0x8000;
		  }
		  if (aty[3] == 0) {
		    atBuf3 |= 0x8000;
		  }
		}
	      }

	      // update the context
	      buf0 <<= 1;
	      buf1 <<= 1;
	      buf2 <<= 1;
	      atBuf0 <<= 1;
	      atBuf1 <<= 1;
	      atBuf2 <<= 1;
	      atBuf3 <<= 1;
	    }
	  }

	} else {
	  // decode the row
	  for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
	    if (x0 + 8 < w) {
	      if (p0) {
		buf0 |= *p0++;
	      }
	      if (p1) {
		buf1 |= *p1++;
	      }
	      buf2 |= *p2++;
	    }
	    for (x1 = 0, mask = 0x80; x1 < 8 && x < w; ++x1, ++x, mask >>= 1) {

	      // build the context
	      cx0 = (buf0 >> 14) & 0x07;
	      cx1 = (buf1 >> 13) & 0x1f;
	      cx2 = (buf2 >> 16) & 0x0f;
	      cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
		   (bitmap->getPixel(x + atx[0], y + aty[0]) << 3) |
		   (bitmap->getPixel(x + atx[1], y + aty[1]) << 2) |
		   (bitmap->getPixel(x + atx[2], y + aty[2]) << 1) |
		   bitmap->getPixel(x + atx[3], y + aty[3]);

	      // check for a skipped pixel
	      if (!(useSkip && skip->getPixel(x, y))) {

		// decode the pixel
		if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
		  *pp |= mask;
		  buf2 |= 0x8000;
		}
	      }

	      // update the context
	      buf0 <<= 1;
	      buf1 <<= 1;
	      buf2 <<= 1;
	    }
	  }
	}
	break;

      case 1:

	// set up the context
	p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
	buf2 = *p2++ << 8;
	if (y >= 1) {
	  p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
	  buf1 = *p1++ << 8;
	  if (y >= 2) {
	    p0 = bitmap->getDataPtr() + (y - 2) * bitmap->getLineSize();
	    buf0 = *p0++ << 8;
	  } else {
	    p0 = nullptr;
	    buf0 = 0;
	  }
	} else {
	  p1 = p0 = nullptr;
	  buf1 = buf0 = 0;
	}

	if (atx[0] >= -8 && atx[0] <= 8) {
	  // set up the adaptive context
	  const int atY = y + aty[0];
	  if ((atY >= 0) && (atY < bitmap->getHeight())) {
	    atP0 = bitmap->getDataPtr() + atY * bitmap->getLineSize();
	    atBuf0 = *atP0++ << 8;
	  } else {
	    atP0 = nullptr;
	    atBuf0 = 0;
	  }
	  atShift0 = 15 - atx[0];

	  // decode the row
	  for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
	    if (x0 + 8 < w) {
	      if (p0) {
		buf0 |= *p0++;
	      }
	      if (p1) {
		buf1 |= *p1++;
	      }
	      buf2 |= *p2++;
	      if (atP0) {
		atBuf0 |= *atP0++;
	      }
	    }
	    for (x1 = 0, mask = 0x80; x1 < 8 && x < w; ++x1, ++x, mask >>= 1) {

	      // build the context
	      cx0 = (buf0 >> 13) & 0x0f;
	      cx1 = (buf1 >> 13) & 0x1f;
	      cx2 = (buf2 >> 16) & 0x07;
	      cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
		   ((atBuf0 >> atShift0) & 1);

	      // check for a skipped pixel
	      if (!(useSkip && skip->getPixel(x, y))) {

		// decode the pixel
		if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
		  *pp |= mask;
		  buf2 |= 0x8000;
		  if (aty[0] == 0) {
		    atBuf0 |= 0x8000;
		  }
		}
	      }

	      // update the context
	      buf0 <<= 1;
	      buf1 <<= 1;
	      buf2 <<= 1;
	      atBuf0 <<= 1;
	    }
	  }

	} else {
	  // decode the row
	  for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
	    if (x0 + 8 < w) {
	      if (p0) {
		buf0 |= *p0++;
	      }
	      if (p1) {
		buf1 |= *p1++;
	      }
	      buf2 |= *p2++;
	    }
	    for (x1 = 0, mask = 0x80; x1 < 8 && x < w; ++x1, ++x, mask >>= 1) {

	      // build the context
	      cx0 = (buf0 >> 13) & 0x0f;
	      cx1 = (buf1 >> 13) & 0x1f;
	      cx2 = (buf2 >> 16) & 0x07;
	      cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
		   bitmap->getPixel(x + atx[0], y + aty[0]);

	      // check for a skipped pixel
	      if (!(useSkip && skip->getPixel(x, y))) {

		// decode the pixel
		if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
		  *pp |= mask;
		  buf2 |= 0x8000;
		}
	      }

	      // update the context
	      buf0 <<= 1;
	      buf1 <<= 1;
	      buf2 <<= 1;
	    }
	  }
	}
	break;

      case 2:

	// set up the context
	p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
	buf2 = *p2++ << 8;
	if (y >= 1) {
	  p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
	  buf1 = *p1++ << 8;
	  if (y >= 2) {
	    p0 = bitmap->getDataPtr() + (y - 2) * bitmap->getLineSize();
	    buf0 = *p0++ << 8;
	  } else {
	    p0 = nullptr;
	    buf0 = 0;
	  }
	} else {
	  p1 = p0 = nullptr;
	  buf1 = buf0 = 0;
	}

	if (atx[0] >= -8 && atx[0] <= 8) {
	  // set up the adaptive context
	  const int atY = y + aty[0];
	  if ((atY >= 0) && (atY < bitmap->getHeight())) {
	    atP0 = bitmap->getDataPtr() + atY * bitmap->getLineSize();
	    atBuf0 = *atP0++ << 8;
	  } else {
	    atP0 = nullptr;
	    atBuf0 = 0;
	  }
	  atShift0 = 15 - atx[0];

	  // decode the row
	  for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
	    if (x0 + 8 < w) {
	      if (p0) {
		buf0 |= *p0++;
	      }
	      if (p1) {
		buf1 |= *p1++;
	      }
	      buf2 |= *p2++;
	      if (atP0) {
		atBuf0 |= *atP0++;
	      }
	    }
	    for (x1 = 0, mask = 0x80; x1 < 8 && x < w; ++x1, ++x, mask >>= 1) {

	      // build the context
	      cx0 = (buf0 >> 14) & 0x07;
	      cx1 = (buf1 >> 14) & 0x0f;
	      cx2 = (buf2 >> 16) & 0x03;
	      cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
		   ((atBuf0 >> atShift0) & 1);

	      // check for a skipped pixel
	      if (!(useSkip && skip->getPixel(x, y))) {

		// decode the pixel
		if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
		  *pp |= mask;
		  buf2 |= 0x8000;
		  if (aty[0] == 0) {
		    atBuf0 |= 0x8000;
		  }
		}
	      }

	      // update the context
	      buf0 <<= 1;
	      buf1 <<= 1;
	      buf2 <<= 1;
	      atBuf0 <<= 1;
	    }
	  }

	} else {
	  // decode the row
	  for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
	    if (x0 + 8 < w) {
	      if (p0) {
		buf0 |= *p0++;
	      }
	      if (p1) {
		buf1 |= *p1++;
	      }
	      buf2 |= *p2++;
	    }
	    for (x1 = 0, mask = 0x80; x1 < 8 && x < w; ++x1, ++x, mask >>= 1) {

	      // build the context
	      cx0 = (buf0 >> 14) & 0x07;
	      cx1 = (buf1 >> 14) & 0x0f;
	      cx2 = (buf2 >> 16) & 0x03;
	      cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
		   bitmap->getPixel(x + atx[0], y + aty[0]);

	      // check for a skipped pixel
	      if (!(useSkip && skip->getPixel(x, y))) {

		// decode the pixel
		if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
		  *pp |= mask;
		  buf2 |= 0x8000;
		}
	      }

	      // update the context
	      buf0 <<= 1;
	      buf1 <<= 1;
	      buf2 <<= 1;
	    }
	  }
	}
	break;

      case 3:

	// set up the context
	p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
	buf2 = *p2++ << 8;
	if (y >= 1) {
	  p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
	  buf1 = *p1++ << 8;
	} else {
	  p1 = nullptr;
	  buf1 = 0;
	}

	if (atx[0] >= -8 && atx[0] <= 8) {
	  // set up the adaptive context
	  const int atY = y + aty[0];
	  if ((atY >= 0) && (atY < bitmap->getHeight())) {
	    atP0 = bitmap->getDataPtr() + atY * bitmap->getLineSize();
	    atBuf0 = *atP0++ << 8;
	  } else {
	    atP0 = nullptr;
	    atBuf0 = 0;
	  }
	  atShift0 = 15 - atx[0];

	  // decode the row
	  for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
	    if (x0 + 8 < w) {
	      if (p1) {
		buf1 |= *p1++;
	      }
	      buf2 |= *p2++;
	      if (atP0) {
		atBuf0 |= *atP0++;
	      }
	    }
	    for (x1 = 0, mask = 0x80; x1 < 8 && x < w; ++x1, ++x, mask >>= 1) {

	      // build the context
	      cx1 = (buf1 >> 14) & 0x1f;
	      cx2 = (buf2 >> 16) & 0x0f;
	      cx = (cx1 << 5) | (cx2 << 1) |
		   ((atBuf0 >> atShift0) & 1);

	      // check for a skipped pixel
	      if (!(useSkip && skip->getPixel(x, y))) {

		// decode the pixel
		if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
		  *pp |= mask;
		  buf2 |= 0x8000;
		  if (aty[0] == 0) {
		    atBuf0 |= 0x8000;
		  }
		}
	      }

	      // update the context
	      buf1 <<= 1;
	      buf2 <<= 1;
	      atBuf0 <<= 1;
	    }
	  }

	} else {
	  // decode the row
	  for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
	    if (x0 + 8 < w) {
	      if (p1) {
		buf1 |= *p1++;
	      }
	      buf2 |= *p2++;
	    }
	    for (x1 = 0, mask = 0x80; x1 < 8 && x < w; ++x1, ++x, mask >>= 1) {

	      // build the context
	      cx1 = (buf1 >> 14) & 0x1f;
	      cx2 = (buf2 >> 16) & 0x0f;
	      cx = (cx1 << 5) | (cx2 << 1) |
		   bitmap->getPixel(x + atx[0], y + aty[0]);

	      // check for a skipped pixel
	      if (!(useSkip && skip->getPixel(x, y))) {

		// decode the pixel
		if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
		  *pp |= mask;
		  buf2 |= 0x8000;
		}
	      }

	      // update the context
	      buf1 <<= 1;
	      buf2 <<= 1;
	    }
	  }
	}
	break;
      }
    }
  }

  return bitmap;
}

void JBIG2Stream::readGenericRefinementRegionSeg(unsigned int segNum, bool imm,
						 bool lossless, unsigned int length,
						 unsigned int *refSegs,
						 unsigned int nRefSegs) {
  JBIG2Bitmap *bitmap, *refBitmap;
  unsigned int w, h, x, y, segInfoFlags, extCombOp;
  unsigned int 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(errSyntaxError, curStr->getPos(), "Bad reference in JBIG2 generic refinement segment");
    return;
  }
  if (nRefSegs == 1) {
    seg = findSegment(refSegs[0]);
    if (seg == nullptr || seg->getType() != jbig2SegBitmap) {
      error(errSyntaxError, curStr->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, nullptr);
  arithDecoder->start();

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

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

  // store the region bitmap
  } else {
    if (bitmap) {
      bitmap->setSegNum(segNum);
      segments->push_back(bitmap);
    } else {
      error(errSyntaxError, curStr->getPos(), "readGenericRefinementRegionSeg with null bitmap");
    }
  }

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

  return;

 eofError:
  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
}

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

  if (!refBitmap) {
      return nullptr;
  }

  bitmap = new JBIG2Bitmap(0, w, h);
  if (!bitmap->isOk())
  {
    delete bitmap;
    return nullptr;
  }
  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);
      } else {
	tpgrCXPtr0.p = tpgrCXPtr1.p = tpgrCXPtr2.p = nullptr; // make gcc happy
	tpgrCXPtr0.shift = tpgrCXPtr1.shift = tpgrCXPtr2.shift = 0;
	tpgrCXPtr0.x = tpgrCXPtr1.x = tpgrCXPtr2.x = 0;
      }

      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);
      } else {
	tpgrCXPtr0.p = tpgrCXPtr1.p = tpgrCXPtr2.p = nullptr; // make gcc happy
	tpgrCXPtr0.shift = tpgrCXPtr1.shift = tpgrCXPtr2.shift = 0;
	tpgrCXPtr0.x = tpgrCXPtr1.x = tpgrCXPtr2.x = 0;
      }

      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(unsigned int length) {
  unsigned int 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;
  }
  delete pageBitmap;
  pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);

  if (!pageBitmap->isOk()) {
    delete pageBitmap;
    pageBitmap = nullptr;
    return;
  }
  
  // default pixel value
  if (pageDefPixel) {
    pageBitmap->clearToOne();
  } else {
    pageBitmap->clearToZero();
  }

  return;

 eofError:
  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
}

void JBIG2Stream::readEndOfStripeSeg(unsigned int length) {
  unsigned int i;

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

void JBIG2Stream::readProfilesSeg(unsigned int length) {
  unsigned int i;

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

void JBIG2Stream::readCodeTableSeg(unsigned int segNum, unsigned int length) {
  JBIG2HuffmanTable *huffTab;
  unsigned int flags, oob, prefixBits, rangeBits;
  int lowVal, highVal, val;
  unsigned int 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_checkoverflow(huffTabSize, sizeof(JBIG2HuffmanTable));
  if (unlikely(!huffTab)) {
    goto oomError;
  }

  i = 0;
  val = lowVal;
  while (val < highVal) {
    if (i == huffTabSize) {
      huffTabSize *= 2;
      huffTab = (JBIG2HuffmanTable *)greallocn_checkoverflow(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable));
      if (unlikely(!huffTab)) {
	goto oomError;
      }
    }
    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_checkoverflow(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable));
    if (unlikely(!huffTab)) {
      goto oomError;
    }
  }
  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;
  if (JBIG2HuffmanDecoder::buildTable(huffTab, i)) {
    // create and store the new table segment
    segments->push_back(new JBIG2CodeTable(segNum, huffTab));
  } else {
    free(huffTab);
  }

  return;

 eofError:
  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
 oomError:
  error(errInternal, curStr->getPos(), "Failed allocation when processing JBIG2 stream");
}

void JBIG2Stream::readExtensionSeg(unsigned int length) {
  unsigned int i;

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

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

  for (std::size_t i = 0; i < globalSegments->size(); ++i) {
    seg = (*globalSegments)[i];
    if (seg->getSegNum() == segNum) {
      return seg;
    }
  }
  for (std::size_t i = 0; i < segments->size(); ++i) {
    seg = (*segments)[i];
    if (seg->getSegNum() == segNum) {
      return seg;
    }
  }
  return nullptr;
}

void JBIG2Stream::discardSegment(unsigned int segNum) {
  for (auto it = globalSegments->begin(); it != globalSegments->end(); ++it) {
    auto seg = static_cast<JBIG2Segment *>(*it);
    if (seg->getSegNum() == segNum) {
      globalSegments->erase(it);
      return;
    }
  }
  for (auto it = segments->begin(); it != segments->end(); ++it) {
    auto seg = static_cast<JBIG2Segment *>(*it);
    if (seg->getSegNum() == segNum) {
      segments->erase(it);
      return;
    }
  }
}

void JBIG2Stream::resetGenericStats(unsigned int 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(unsigned int 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));
  }
}

bool JBIG2Stream::readUByte(unsigned int *x) {
  int c0;

  if ((c0 = curStr->getChar()) == EOF) {
    return false;
  }
  *x = (unsigned int)c0;
  return true;
}

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

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

bool JBIG2Stream::readUWord(unsigned int *x) {
  int c0, c1;

  if ((c0 = curStr->getChar()) == EOF ||
      (c1 = curStr->getChar()) == EOF) {
    return false;
  }
  *x = (unsigned int)((c0 << 8) | c1);
  return true;
}

bool JBIG2Stream::readULong(unsigned 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 false;
  }
  *x = (unsigned int)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
  return true;
}

bool 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 false;
  }
  *x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
  if (c0 & 0x80) {
    *x |= -1 - (int)0xffffffff;
  }
  return true;
}
