Back to index

tetex-bin  3.0
Public Member Functions | Protected Attributes | Private Member Functions | Private Attributes
JBIG2Stream Class Reference

#include <JBIG2Stream.h>

Inheritance diagram for JBIG2Stream:
Inheritance graph
[legend]
Collaboration diagram for JBIG2Stream:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 JBIG2Stream (Stream *strA, Object *globalsStream)
virtual ~JBIG2Stream ()
virtual StreamKind getKind ()
virtual void reset ()
virtual int getChar ()
virtual int lookChar ()
virtual GStringgetPSFilter (int psLevel, char *indent)
virtual GBool isBinary (GBool last=gTrue)
virtual void close ()
virtual int getPos ()
virtual void setPos (Guint pos, int dir=0)
virtual BaseStreamgetBaseStream ()
virtual DictgetDict ()
virtual void ignoreLength ()
int incRef ()
int decRef ()
virtual int getRawChar ()
virtual char * getLine (char *buf, int size)
virtual GBool isEncoder ()
StreamaddFilters (Object *dict)

Protected Attributes

Streamstr

Private Member Functions

void readSegments ()
void readSymbolDictSeg (Guint segNum, Guint length, Guint *refSegs, Guint nRefSegs)
void readTextRegionSeg (Guint segNum, GBool imm, GBool lossless, Guint length, Guint *refSegs, Guint nRefSegs)
JBIG2BitmapreadTextRegion (GBool huff, GBool refine, int w, int h, Guint numInstances, Guint logStrips, int numSyms, JBIG2HuffmanTable *symCodeTab, Guint symCodeLen, JBIG2Bitmap **syms, Guint defPixel, Guint combOp, Guint transposed, Guint refCorner, int sOffset, JBIG2HuffmanTable *huffFSTable, JBIG2HuffmanTable *huffDSTable, JBIG2HuffmanTable *huffDTTable, JBIG2HuffmanTable *huffRDWTable, JBIG2HuffmanTable *huffRDHTable, JBIG2HuffmanTable *huffRDXTable, JBIG2HuffmanTable *huffRDYTable, JBIG2HuffmanTable *huffRSizeTable, Guint templ, int *atx, int *aty)
void readPatternDictSeg (Guint segNum, Guint length)
void readHalftoneRegionSeg (Guint segNum, GBool imm, GBool lossless, Guint length, Guint *refSegs, Guint nRefSegs)
void readGenericRegionSeg (Guint segNum, GBool imm, GBool lossless, Guint length)
JBIG2BitmapreadGenericBitmap (GBool mmr, int w, int h, int templ, GBool tpgdOn, GBool useSkip, JBIG2Bitmap *skip, int *atx, int *aty, int mmrDataLength)
void readGenericRefinementRegionSeg (Guint segNum, GBool imm, GBool lossless, Guint length, Guint *refSegs, Guint nRefSegs)
JBIG2BitmapreadGenericRefinementRegion (int w, int h, int templ, GBool tpgrOn, JBIG2Bitmap *refBitmap, int refDX, int refDY, int *atx, int *aty)
void readPageInfoSeg (Guint length)
void readEndOfStripeSeg (Guint length)
void readProfilesSeg (Guint length)
void readCodeTableSeg (Guint segNum, Guint length)
void readExtensionSeg (Guint length)
JBIG2SegmentfindSegment (Guint segNum)
void discardSegment (Guint segNum)
void resetGenericStats (Guint templ, JArithmeticDecoderStats *prevStats)
void resetRefinementStats (Guint templ, JArithmeticDecoderStats *prevStats)
void resetIntStats (int symCodeLen)
GBool readUByte (Guint *x)
GBool readByte (int *x)
GBool readUWord (Guint *x)
GBool readULong (Guint *x)
GBool readLong (int *x)

Private Attributes

Guint pageW
Guint pageH
Guint curPageH
Guint pageDefPixel
JBIG2BitmappageBitmap
Guint defCombOp
GListsegments
GListglobalSegments
StreamcurStr
GuchardataPtr
GuchardataEnd
JArithmeticDecoderarithDecoder
JArithmeticDecoderStatsgenericRegionStats
JArithmeticDecoderStatsrefinementRegionStats
JArithmeticDecoderStatsiadhStats
JArithmeticDecoderStatsiadwStats
JArithmeticDecoderStatsiaexStats
JArithmeticDecoderStatsiaaiStats
JArithmeticDecoderStatsiadtStats
JArithmeticDecoderStatsiaitStats
JArithmeticDecoderStatsiafsStats
JArithmeticDecoderStatsiadsStats
JArithmeticDecoderStatsiardxStats
JArithmeticDecoderStatsiardyStats
JArithmeticDecoderStatsiardwStats
JArithmeticDecoderStatsiardhStats
JArithmeticDecoderStatsiariStats
JArithmeticDecoderStatsiaidStats
JBIG2HuffmanDecoderhuffDecoder
JBIG2MMRDecodermmrDecoder

Detailed Description

Definition at line 33 of file JBIG2Stream.h.


Constructor & Destructor Documentation

JBIG2Stream::JBIG2Stream ( Stream strA,
Object globalsStream 
)

Definition at line 1123 of file JBIG2Stream.cc.

                          {
  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;
  if (pageBitmap) {
    delete pageBitmap;
  }
  if (segments) {
    deleteGList(segments, JBIG2Segment);
  }
  if (globalSegments) {
    deleteGList(globalSegments, JBIG2Segment);
  }
  delete str;
}

Member Function Documentation

Stream * Stream::addFilters ( Object dict) [inherited]

Definition at line 92 of file Stream.cc.

                                       {
  Object obj, obj2;
  Object params, params2;
  Stream *str;
  int i;

  str = this;
  dict->dictLookup("Filter", &obj);
  if (obj.isNull()) {
    obj.free();
    dict->dictLookup("F", &obj);
  }
  dict->dictLookup("DecodeParms", &params);
  if (params.isNull()) {
    params.free();
    dict->dictLookup("DP", &params);
  }
  if (obj.isName()) {
    str = makeFilter(obj.getName(), str, &params);
  } else if (obj.isArray()) {
    for (i = 0; i < obj.arrayGetLength(); ++i) {
      obj.arrayGet(i, &obj2);
      if (params.isArray())
       params.arrayGet(i, &params2);
      else
       params2.initNull();
      if (obj2.isName()) {
       str = makeFilter(obj2.getName(), str, &params2);
      } else {
       error(getPos(), "Bad filter name");
       str = new EOFStream(str);
      }
      obj2.free();
      params2.free();
    }
  } else if (!obj.isNull()) {
    error(getPos(), "Bad 'Filter' attribute in stream");
  }
  obj.free();
  params.free();

  return str;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void FilterStream::close ( ) [virtual, inherited]

Reimplemented from Stream.

Definition at line 306 of file Stream.cc.

                         {
  str->close();
}

Here is the call graph for this function:

int Stream::decRef ( ) [inline, inherited]

Definition at line 58 of file Stream.h.

{ return --ref; }
void JBIG2Stream::discardSegment ( Guint  segNum) [private]

Definition at line 3190 of file JBIG2Stream.cc.

                                             {
  JBIG2Segment *seg;
  int i;

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

Here is the call graph for this function:

Here is the caller graph for this function:

JBIG2Segment * JBIG2Stream::findSegment ( Guint  segNum) [private]

Definition at line 3171 of file JBIG2Stream.cc.

                                                   {
  JBIG2Segment *seg;
  int i;

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

Here is the call graph for this function:

Here is the caller graph for this function:

virtual BaseStream* FilterStream::getBaseStream ( ) [inline, virtual, inherited]

Implements Stream.

Definition at line 174 of file Stream.h.

{ return str->getBaseStream(); }

Here is the call graph for this function:

int JBIG2Stream::getChar ( ) [virtual]

Implements Stream.

Definition at line 1180 of file JBIG2Stream.cc.

                         {
  if (dataPtr && dataPtr < dataEnd) {
    return (*dataPtr++ ^ 0xff) & 0xff;
  }
  return EOF;
}
virtual Dict* FilterStream::getDict ( ) [inline, virtual, inherited]

Implements Stream.

Definition at line 175 of file Stream.h.

{ return str->getDict(); }

Here is the call graph for this function:

virtual StreamKind JBIG2Stream::getKind ( ) [inline, virtual]

Implements Stream.

Definition at line 38 of file JBIG2Stream.h.

{ return strJBIG2; }
char * Stream::getLine ( char *  buf,
int  size 
) [virtual, inherited]

Definition at line 67 of file Stream.cc.

                                         {
  int i;
  int c;

  if (lookChar() == EOF)
    return NULL;
  for (i = 0; i < size - 1; ++i) {
    c = getChar();
    if (c == EOF || c == '\n')
      break;
    if (c == '\r') {
      if ((c = lookChar()) == '\n')
       getChar();
      break;
    }
    buf[i] = c;
  }
  buf[i] = '\0';
  return buf;
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual int FilterStream::getPos ( ) [inline, virtual, inherited]

Implements Stream.

Definition at line 172 of file Stream.h.

{ return str->getPos(); }

Here is the call graph for this function:

GString * JBIG2Stream::getPSFilter ( int  psLevel,
char *  indent 
) [virtual]

Reimplemented from Stream.

Definition at line 1194 of file JBIG2Stream.cc.

                                                           {
  return NULL;
}
int Stream::getRawChar ( ) [virtual, inherited]

Reimplemented in FlateStream, and LZWStream.

Definition at line 62 of file Stream.cc.

                       {
  error(-1, "Internal: called getRawChar() on non-predictor stream");
  return EOF;
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual void FilterStream::ignoreLength ( ) [inline, virtual, inherited]

Reimplemented from Stream.

Definition at line 176 of file Stream.h.

{ str->ignoreLength(); }

Here is the call graph for this function:

int Stream::incRef ( ) [inline, inherited]

Definition at line 57 of file Stream.h.

{ return ++ref; }
GBool JBIG2Stream::isBinary ( GBool  last = gTrue) [virtual]

Implements Stream.

Definition at line 1198 of file JBIG2Stream.cc.

                                      {
  return str->isBinary(gTrue);
}

Here is the call graph for this function:

virtual GBool Stream::isEncoder ( ) [inline, virtual, inherited]

Reimplemented in RunLengthEncoder, ASCII85Encoder, ASCIIHexEncoder, and FixedLengthEncoder.

Definition at line 103 of file Stream.h.

{ return gFalse; }

Here is the caller graph for this function:

int JBIG2Stream::lookChar ( ) [virtual]

Implements Stream.

Definition at line 1187 of file JBIG2Stream.cc.

                          {
  if (dataPtr && dataPtr < dataEnd) {
    return (*dataPtr ^ 0xff) & 0xff;
  }
  return EOF;
}
GBool JBIG2Stream::readByte ( int x) [private]

Definition at line 3286 of file JBIG2Stream.cc.

                                  {
 int c0;

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

Here is the call graph for this function:

Here is the caller graph for this function:

void JBIG2Stream::readCodeTableSeg ( Guint  segNum,
Guint  length 
) [private]

Definition at line 3098 of file JBIG2Stream.cc.

                                                             {
  JBIG2HuffmanTable *huffTab;
  Guint flags, oob, prefixBits, rangeBits;
  int lowVal, highVal, val;
  Guint huffTabSize, i;

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

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

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

  return;

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

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3080 of file JBIG2Stream.cc.

                                                 {
  Guint i;

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

Here is the call graph for this function:

Here is the caller graph for this function:

void JBIG2Stream::readExtensionSeg ( Guint  length) [private]

Definition at line 3162 of file JBIG2Stream.cc.

                                               {
  Guint i;

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

Here is the call graph for this function:

Here is the caller graph for this function:

JBIG2Bitmap * JBIG2Stream::readGenericBitmap ( GBool  mmr,
int  w,
int  h,
int  templ,
GBool  tpgdOn,
GBool  useSkip,
JBIG2Bitmap skip,
int atx,
int aty,
int  mmrDataLength 
) [private]

Definition at line 2432 of file JBIG2Stream.cc.

                                                          {
  JBIG2Bitmap *bitmap;
  GBool ltp;
  Guint ltpCX, cx, cx0, cx1, cx2;
  JBIG2BitmapPtr cxPtr0, cxPtr1;
  JBIG2BitmapPtr atPtr0, atPtr1, atPtr2, atPtr3;
  int *refLine, *codingLine;
  int code1, code2, code3;
  int x, y, a0, pix, i, refI, codingI;

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

  //----- MMR decode

  if (mmr) {

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

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

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

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

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

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

    gfree(refLine);
    gfree(codingLine);

  //----- arithmetic decode

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

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

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

      switch (templ) {
      case 0:

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

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

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

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

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

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

      case 1:

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

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

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

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

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

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

      case 2:

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

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

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

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

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

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

      case 3:

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

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

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

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

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

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

  return bitmap;
}

Here is the call graph for this function:

Here is the caller graph for this function:

JBIG2Bitmap * JBIG2Stream::readGenericRefinementRegion ( int  w,
int  h,
int  templ,
GBool  tpgrOn,
JBIG2Bitmap refBitmap,
int  refDX,
int  refDY,
int atx,
int aty 
) [private]

Definition at line 2878 of file JBIG2Stream.cc.

                                                                    {
  JBIG2Bitmap *bitmap;
  GBool ltp;
  Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
  JBIG2BitmapPtr cxPtr0, cxPtr1, cxPtr2, cxPtr3, cxPtr4, cxPtr5, cxPtr6;
  JBIG2BitmapPtr tpgrCXPtr0, tpgrCXPtr1, tpgrCXPtr2;
  int x, y, pix;

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

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

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

    if (templ) {

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

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

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

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

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

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

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

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

    } else {

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

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

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

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

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

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

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

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

  return bitmap;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void JBIG2Stream::readGenericRefinementRegionSeg ( Guint  segNum,
GBool  imm,
GBool  lossless,
Guint  length,
Guint refSegs,
Guint  nRefSegs 
) [private]

Definition at line 2790 of file JBIG2Stream.cc.

                                                           {
  JBIG2Bitmap *bitmap, *refBitmap;
  Guint w, h, x, y, segInfoFlags, extCombOp;
  Guint flags, templ, tpgrOn;
  int atx[2], aty[2];
  JBIG2Segment *seg;

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

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

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

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

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

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

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

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

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

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

  return;

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

Here is the call graph for this function:

Here is the caller graph for this function:

void JBIG2Stream::readGenericRegionSeg ( Guint  segNum,
GBool  imm,
GBool  lossless,
Guint  length 
) [private]

Definition at line 2358 of file JBIG2Stream.cc.

                                                                 {
  JBIG2Bitmap *bitmap;
  Guint w, h, x, y, segInfoFlags, extCombOp;
  Guint flags, mmr, templ, tpgdOn;
  int atx[4], aty[4];

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

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

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

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

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

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

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

  return;

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

Here is the call graph for this function:

Here is the caller graph for this function:

void JBIG2Stream::readHalftoneRegionSeg ( Guint  segNum,
GBool  imm,
GBool  lossless,
Guint  length,
Guint refSegs,
Guint  nRefSegs 
) [private]

Definition at line 2210 of file JBIG2Stream.cc.

                                                                   {
  JBIG2Bitmap *bitmap;
  JBIG2Segment *seg;
  JBIG2PatternDict *patternDict;
  JBIG2Bitmap *skipBitmap;
  Guint *grayImg;
  JBIG2Bitmap *grayBitmap;
  JBIG2Bitmap *patternBitmap;
  Guint w, h, x, y, segInfoFlags, extCombOp;
  Guint flags, mmr, templ, enableSkip, combOp;
  Guint gridW, gridH, stepX, stepY, patW, patH;
  int atx[4], aty[4];
  int gridX, gridY, xx, yy, bit, j;
  Guint bpp, m, n, i;

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

  // rest of the halftone region header
  if (!readUByte(&flags)) {
    goto eofError;
  }
  mmr = flags & 1;
  templ = (flags >> 1) & 3;
  enableSkip = (flags >> 3) & 1;
  combOp = (flags >> 4) & 7;
  if (!readULong(&gridW) || !readULong(&gridH) ||
      !readLong(&gridX) || !readLong(&gridY) ||
      !readUWord(&stepX) || !readUWord(&stepY)) {
    goto eofError;
  }

  // get pattern dictionary
  if (nRefSegs != 1) {
    error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
    return;
  }
  seg = findSegment(refSegs[0]);
  if (seg->getType() != jbig2SegPatternDict) {
    error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
    return;
  }
  patternDict = (JBIG2PatternDict *)seg;
  bpp = 0;
  i = 1;
  while (i < patternDict->getSize()) {
    ++bpp;
    i <<= 1;
  }
  patW = patternDict->getBitmap(0)->getWidth();
  patH = patternDict->getBitmap(0)->getHeight();

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

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

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

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

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

  gfree(grayImg);

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

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

  return;

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

Here is the call graph for this function:

Here is the caller graph for this function:

GBool JBIG2Stream::readLong ( int x) [private]

Definition at line 3323 of file JBIG2Stream.cc.

                                  {
  int c0, c1, c2, c3;

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

Here is the call graph for this function:

Here is the caller graph for this function:

void JBIG2Stream::readPageInfoSeg ( Guint  length) [private]

Definition at line 3048 of file JBIG2Stream.cc.

                                              {
  Guint xRes, yRes, flags, striping;

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

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

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

  return;

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

Here is the call graph for this function:

Here is the caller graph for this function:

void JBIG2Stream::readPatternDictSeg ( Guint  segNum,
Guint  length 
) [private]

Definition at line 2156 of file JBIG2Stream.cc.

                                                               {
  JBIG2PatternDict *patternDict;
  JBIG2Bitmap *bitmap;
  Guint flags, patternW, patternH, grayMax, templ, mmr;
  int atx[4], aty[4];
  Guint i, x;

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

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

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

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

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

  // free memory
  delete bitmap;

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

  return;

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

Here is the call graph for this function:

Here is the caller graph for this function:

void JBIG2Stream::readProfilesSeg ( Guint  length) [private]

Definition at line 3089 of file JBIG2Stream.cc.

                                              {
  Guint i;

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

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1202 of file JBIG2Stream.cc.

                               {
  Guint segNum, segFlags, segType, page, segLength;
  Guint refFlags, nRefSegs;
  Guint *refSegs;
  int c1, c2, c3;
  Guint i;

  while (readULong(&segNum)) {

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

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

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

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

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

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

    gfree(refSegs);
  }

  return;

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

Here is the call graph for this function:

Here is the caller graph for this function:

void JBIG2Stream::readSymbolDictSeg ( Guint  segNum,
Guint  length,
Guint refSegs,
Guint  nRefSegs 
) [private]

Definition at line 1359 of file JBIG2Stream.cc.

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

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

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

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

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

  // get referenced segments: input symbol dictionaries and code tables
  codeTables = new GList();
  numInputSyms = 0;
  for (i = 0; i < nRefSegs; ++i) {
    seg = findSegment(refSegs[i]);
    if (seg->getType() == jbig2SegSymbolDict) {
      numInputSyms += ((JBIG2SymbolDict *)seg)->getSize();
    } else if (seg->getType() == jbig2SegCodeTable) {
      codeTables->append(seg);
    }
  }

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

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

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

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

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

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

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

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

    // read the height class delta height
    if (huff) {
      huffDecoder->decodeInt(&dh, huffDHTable);
    } else {
      arithDecoder->decodeInt(&dh, iadhStats);
    }
    symHeight += dh;
    symWidth = 0;
    totalWidth = 0;
    j = i;

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

      // read the delta width
      if (huff) {
       if (!huffDecoder->decodeInt(&dw, huffDWTable)) {
         break;
       }
      } else {
       if (!arithDecoder->decodeInt(&dw, iadwStats)) {
         break;
       }
      }
      symWidth += dw;

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

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

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

      ++i;
    }

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

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

  // exported symbol list
  i = j = 0;
  ex = gFalse;
  while (i < numInputSyms + numNewSyms) {
    if (huff) {
      huffDecoder->decodeInt(&run, huffTableA);
    } else {
      arithDecoder->decodeInt(&run, iaexStats);
    }
    if (ex) {
      for (cnt = 0; cnt < run; ++cnt) {
       symbolDict->setBitmap(j++, bitmaps[i++]->copy());
      }
    } else {
      i += run;
    }
    ex = !ex;
  }

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

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

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

  return;

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

Here is the call graph for this function:

Here is the caller graph for this function:

JBIG2Bitmap * JBIG2Stream::readTextRegion ( GBool  huff,
GBool  refine,
int  w,
int  h,
Guint  numInstances,
Guint  logStrips,
int  numSyms,
JBIG2HuffmanTable symCodeTab,
Guint  symCodeLen,
JBIG2Bitmap **  syms,
Guint  defPixel,
Guint  combOp,
Guint  transposed,
Guint  refCorner,
int  sOffset,
JBIG2HuffmanTable huffFSTable,
JBIG2HuffmanTable huffDSTable,
JBIG2HuffmanTable huffDTTable,
JBIG2HuffmanTable huffRDWTable,
JBIG2HuffmanTable huffRDHTable,
JBIG2HuffmanTable huffRDXTable,
JBIG2HuffmanTable huffRDYTable,
JBIG2HuffmanTable huffRSizeTable,
Guint  templ,
int atx,
int aty 
) [private]

Definition at line 1963 of file JBIG2Stream.cc.

                                                        {
  JBIG2Bitmap *bitmap;
  JBIG2Bitmap *symbolBitmap;
  Guint strips;
  int t, dt, tt, s, ds, sFirst, j;
  int rdw, rdh, rdx, rdy, ri, refDX, refDY, bmSize;
  Guint symID, inst, bw, bh;

  strips = 1 << logStrips;

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

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

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

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

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

    // read the instances
    while (1) {

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

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

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

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

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

      // next instance
      ++inst;

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

  return bitmap;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void JBIG2Stream::readTextRegionSeg ( Guint  segNum,
GBool  imm,
GBool  lossless,
Guint  length,
Guint refSegs,
Guint  nRefSegs 
) [private]

Definition at line 1699 of file JBIG2Stream.cc.

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

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

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

  // get symbol dictionaries and tables
  codeTables = new GList();
  numSyms = 0;
  for (i = 0; i < nRefSegs; ++i) {
    seg = findSegment(refSegs[i]);
    if (seg->getType() == jbig2SegSymbolDict) {
      numSyms += ((JBIG2SymbolDict *)seg)->getSize();
    } else if (seg->getType() == jbig2SegCodeTable) {
      codeTables->append(seg);
    }
  }
  symCodeLen = 0;
  i = 1;
  while (i < numSyms) {
    ++symCodeLen;
    i <<= 1;
  }

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

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

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

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

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

  gfree(syms);

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

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

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

  return;

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

Here is the call graph for this function:

Here is the caller graph for this function:

GBool JBIG2Stream::readUByte ( Guint x) [private]

Definition at line 3276 of file JBIG2Stream.cc.

                                     {
  int c0;

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

Here is the call graph for this function:

Here is the caller graph for this function:

GBool JBIG2Stream::readULong ( Guint x) [private]

Definition at line 3310 of file JBIG2Stream.cc.

                                     {
  int c0, c1, c2, c3;

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

Here is the call graph for this function:

Here is the caller graph for this function:

GBool JBIG2Stream::readUWord ( Guint x) [private]

Definition at line 3299 of file JBIG2Stream.cc.

                                     {
  int c0, c1;

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

Here is the call graph for this function:

Here is the caller graph for this function:

void JBIG2Stream::reset ( ) [virtual]

Implements Stream.

Definition at line 1155 of file JBIG2Stream.cc.

Here is the call graph for this function:

void JBIG2Stream::resetGenericStats ( Guint  templ,
JArithmeticDecoderStats prevStats 
) [private]

Definition at line 3210 of file JBIG2Stream.cc.

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

Here is the call graph for this function:

Here is the caller graph for this function:

void JBIG2Stream::resetIntStats ( int  symCodeLen) [private]

Definition at line 3254 of file JBIG2Stream.cc.

Here is the call graph for this function:

Here is the caller graph for this function:

void JBIG2Stream::resetRefinementStats ( Guint  templ,
JArithmeticDecoderStats prevStats 
) [private]

Definition at line 3232 of file JBIG2Stream.cc.

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

Here is the call graph for this function:

Here is the caller graph for this function:

void FilterStream::setPos ( Guint  pos,
int  dir = 0 
) [virtual, inherited]

Implements Stream.

Definition at line 310 of file Stream.cc.

                                            {
  error(-1, "Internal: called setPos() on FilterStream");
}

Here is the call graph for this function:


Member Data Documentation

Definition at line 122 of file JBIG2Stream.h.

Definition at line 112 of file JBIG2Stream.h.

Definition at line 118 of file JBIG2Stream.h.

Definition at line 120 of file JBIG2Stream.h.

Definition at line 119 of file JBIG2Stream.h.

Definition at line 115 of file JBIG2Stream.h.

Definition at line 123 of file JBIG2Stream.h.

Definition at line 117 of file JBIG2Stream.h.

Definition at line 139 of file JBIG2Stream.h.

Definition at line 128 of file JBIG2Stream.h.

Definition at line 125 of file JBIG2Stream.h.

Definition at line 132 of file JBIG2Stream.h.

Definition at line 129 of file JBIG2Stream.h.

Definition at line 126 of file JBIG2Stream.h.

Definition at line 127 of file JBIG2Stream.h.

Definition at line 131 of file JBIG2Stream.h.

Definition at line 138 of file JBIG2Stream.h.

Definition at line 130 of file JBIG2Stream.h.

Definition at line 136 of file JBIG2Stream.h.

Definition at line 135 of file JBIG2Stream.h.

Definition at line 133 of file JBIG2Stream.h.

Definition at line 134 of file JBIG2Stream.h.

Definition at line 137 of file JBIG2Stream.h.

Definition at line 140 of file JBIG2Stream.h.

Definition at line 114 of file JBIG2Stream.h.

Definition at line 113 of file JBIG2Stream.h.

Definition at line 112 of file JBIG2Stream.h.

Definition at line 112 of file JBIG2Stream.h.

Definition at line 124 of file JBIG2Stream.h.

Definition at line 116 of file JBIG2Stream.h.

Stream* FilterStream::str [protected, inherited]

Definition at line 180 of file Stream.h.


The documentation for this class was generated from the following files: