[poppler] poppler/poppler: JArithmeticDecoder.cc, 1.2, 1.3 JArithmeticDecoder.h, 1.1.1.1, 1.2 JBIG2Stream.cc, 1.2, 1.3 JBIG2Stream.h, 1.1.1.1, 1.2

Brad Hards bradh at freedesktop.org
Wed Aug 31 02:51:43 PDT 2005


Update of /cvs/poppler/poppler/poppler
In directory gabe:/tmp/cvs-serv24216/poppler

Modified Files:
	JArithmeticDecoder.cc JArithmeticDecoder.h JBIG2Stream.cc 
	JBIG2Stream.h 
Log Message:
poppler/JArithmeticDecoder.cc
poppler/JArithmeticDecoder.h
poppler/JBIG2Stream.cc
poppler/JBIG2Stream.h: merge in some of the JBIG2 changes from xpdf 3.0.1.



Index: JArithmeticDecoder.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/JArithmeticDecoder.cc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- JArithmeticDecoder.cc	27 Aug 2005 08:43:43 -0000	1.2
+++ JArithmeticDecoder.cc	31 Aug 2005 09:51:41 -0000	1.3
@@ -89,24 +89,24 @@
 
 JArithmeticDecoder::JArithmeticDecoder() {
   str = NULL;
-}
-
-JArithmeticDecoder::~JArithmeticDecoder() {
-  while (dataLen > 0) {
-    readByte();
-  }
+  dataLen = 0;
+  limitStream = gFalse;
 }
 
 inline Guint JArithmeticDecoder::readByte() {
-  if (dataLen == 0) {
-    return 0xff;
-  }
-  if (dataLen > 0) {
+  if (limitStream) {
     --dataLen;
+    if (dataLen < 0) {
+      return 0xff;
+    }
   }
   return (Guint)str->getChar() & 0xff;
 }
 
+JArithmeticDecoder::~JArithmeticDecoder() {
+  cleanup();
+}
+
 void JArithmeticDecoder::start() {
   buf0 = readByte();
   buf1 = readByte();
@@ -119,6 +119,28 @@
   a = 0x80000000;
 }
 
+void JArithmeticDecoder::restart(int dataLenA) {
+  int oldDataLen;
+
+  oldDataLen = dataLen;
+  dataLen = dataLenA;
+  if (oldDataLen == -1) {
+    buf1 = readByte();
+  } else if (oldDataLen <= -2) {
+    buf0 = readByte();
+    buf1 = readByte();
+  }
+}
+
+void JArithmeticDecoder::cleanup() {
+  if (limitStream) {
+    while (dataLen > 0) {
+      buf0 = buf1;
+      buf1 = readByte();
+    }
+  }
+}
+
 int JArithmeticDecoder::decodeBit(Guint context,
 				  JArithmeticDecoderStats *stats) {
   int bit;

Index: JArithmeticDecoder.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/JArithmeticDecoder.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- JArithmeticDecoder.h	3 Mar 2005 19:46:00 -0000	1.1.1.1
+++ JArithmeticDecoder.h	31 Aug 2005 09:51:41 -0000	1.2
@@ -51,12 +51,29 @@
 
   JArithmeticDecoder();
   ~JArithmeticDecoder();
+
   void setStream(Stream *strA)
-    { str = strA; dataLen = -1; }
+    { str = strA; dataLen = 0; limitStream = gFalse; }
   void setStream(Stream *strA, int dataLenA)
-    { str = strA; dataLen = dataLenA; }
+    { str = strA; dataLen = dataLenA; limitStream = gTrue; }
+
+  // Start decoding on a new stream.  This fills the byte buffers and
+  // runs INITDEC.
   void start();
+
+  // Restart decoding on an interrupted stream.  This refills the
+  // buffers if needed, but does not run INITDEC.  (This is used in
+  // JPEG 2000 streams when codeblock data is split across multiple
+  // packets/layers.)
+  void restart(int dataLenA);
+
+  // Read any leftover data in the stream.
+  void cleanup();
+
+  // Decode one bit.
   int decodeBit(Guint context, JArithmeticDecoderStats *stats);
+
+  // Decode eight bits.
   int decodeByte(Guint context, JArithmeticDecoderStats *stats);
 
   // Returns false for OOB, otherwise sets *<x> and returns true.
@@ -84,6 +101,7 @@
 
   Stream *str;
   int dataLen;
+  GBool limitStream;
 };
 
 #endif

Index: JBIG2Stream.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/JBIG2Stream.cc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- JBIG2Stream.cc	27 Aug 2005 08:43:43 -0000	1.2
+++ JBIG2Stream.cc	31 Aug 2005 09:51:41 -0000	1.3
@@ -681,7 +681,9 @@
   w = wA;
   h = hA;
   line = (wA + 7) >> 3;
-  data = (Guchar *)gmalloc(h * line);
+  // need to allocate one extra guard byte for use in combine()
+  data = (Guchar *)gmalloc(h * line + 1);
+  data[h * line] = 0;
 }
 
 JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):
@@ -690,8 +692,10 @@
   w = bitmap->w;
   h = bitmap->h;
   line = bitmap->line;
-  data = (Guchar *)gmalloc(h * line);
+  // need to allocate one extra guard byte for use in combine()
+  data = (Guchar *)gmalloc(h * line + 1);
   memcpy(data, bitmap->data, h * line);
+  data[h * line] = 0;
 }
 
 JBIG2Bitmap::~JBIG2Bitmap() {
@@ -719,13 +723,15 @@
   if (newH <= h) {
     return;
   }
-  data = (Guchar *)grealloc(data, newH * line);
+  // need to allocate one extra guard byte for use in combine()
+  data = (Guchar *)grealloc(data, newH * line + 1);
   if (pixel) {
     memset(data + h * line, 0xff, (newH - h) * line);
   } else {
     memset(data + h * line, 0x00, (newH - h) * line);
   }
   h = newH;
+  data[h * line] = 0;
 }
 
 void JBIG2Bitmap::clearToZero() {
@@ -933,6 +939,10 @@
       }
 
       // 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++;
@@ -1273,7 +1283,9 @@
     // read the segment data
     switch (segType) {
     case 0:
-      readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs);
+      if (!readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs)) {
+	goto syntaxError;
+      }
       break;
     case 4:
       readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs);
@@ -1350,14 +1362,18 @@
 
   return;
 
+ syntaxError:
+  gfree(refSegs);
+  return;
+
  eofError2:
   gfree(refSegs);
  eofError1:
   error(getPos(), "Unexpected EOF in JBIG2 stream");
 }
 
-void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
-				    Guint *refSegs, Guint nRefSegs) {
+GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
+				     Guint *refSegs, Guint nRefSegs) {
   JBIG2SymbolDict *symbolDict;
   JBIG2HuffmanTable *huffDHTable, *huffDWTable;
   JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable;
@@ -1453,6 +1469,9 @@
   // get the input symbol bitmaps
   bitmaps = (JBIG2Bitmap **)gmallocn(numInputSyms + numNewSyms,
 				     sizeof(JBIG2Bitmap *));
+  for (i = 0; i < numInputSyms + numNewSyms; ++i) {
+    bitmaps[i] = NULL;
+  }
   k = 0;
   inputSymbolDict = NULL;
   for (i = 0; i < nRefSegs; ++i) {
@@ -1540,6 +1559,10 @@
     } else {
       arithDecoder->decodeInt(&dh, iadhStats);
     }
+    if (dh < 0 && (Guint)-dh >= symHeight) {
+      error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
+      goto syntaxError;
+    }
     symHeight += dh;
     symWidth = 0;
     totalWidth = 0;
@@ -1558,6 +1581,10 @@
 	  break;
 	}
       }
+      if (dw < 0 && (Guint)-dw >= symWidth) {
+	error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
+	goto syntaxError;
+      }
       symWidth += dw;
 
       // using a collective bitmap, so don't read a bitmap here
@@ -1690,10 +1717,23 @@
   // store the new symbol dict
   segments->append(symbolDict);
 
-  return;
+  return gTrue;
+
+ syntaxError:
+  for (i = 0; i < numNewSyms; ++i) {
+    if (bitmaps[numInputSyms + i]) {
+      delete bitmaps[numInputSyms + i];
+    }
+  }
+  gfree(bitmaps);
+  if (symWidths) {
+    gfree(symWidths);
+  }
+  return gFalse;
 
  eofError:
   error(getPos(), "Unexpected EOF in JBIG2 stream");
+  return gFalse;
 }
 
 void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
@@ -1773,11 +1813,14 @@
   codeTables = new GooList();
   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);
+    if ((seg = findSegment(refSegs[i]))) {
+      if (seg->getType() == jbig2SegSymbolDict) {
+	numSyms += ((JBIG2SymbolDict *)seg)->getSize();
+      } else if (seg->getType() == jbig2SegCodeTable) {
+	codeTables->append(seg);
+      }
+    } else {
+      error(getPos(), "Invalid segment reference in JBIG2 text region");
     }
   }
   symCodeLen = 0;
@@ -1791,11 +1834,12 @@
   syms = (JBIG2Bitmap **)gmallocn(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);
+    if ((seg = findSegment(refSegs[i]))) {
+      if (seg->getType() == jbig2SegSymbolDict) {
+	symbolDict = (JBIG2SymbolDict *)seg;
+	for (k = 0; k < symbolDict->getSize(); ++k) {
+	  syms[kk++] = symbolDict->getBitmap(k);
+	}
       }
     }
   }
@@ -2052,85 +2096,90 @@
 	symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
       }
 
-      // get the symbol bitmap
-      symbolBitmap = NULL;
-      if (refine) {
-	if (huff) {
-	  ri = (int)huffDecoder->readBit();
-	} else {
-	  arithDecoder->decodeInt(&ri, iariStats);
-	}
+      if (symID >= (Guint)numSyms) {
+	error(getPos(), "Invalid symbol number in JBIG2 text region");
       } 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();
+
+	// get the symbol bitmap
+	symbolBitmap = NULL;
+	if (refine) {
+	  if (huff) {
+	    ri = (int)huffDecoder->readBit();
+	  } else {
+	    arithDecoder->decodeInt(&ri, iariStats);
+	  }
 	} else {
-	  arithDecoder->decodeInt(&rdw, iardwStats);
-	  arithDecoder->decodeInt(&rdh, iardhStats);
-	  arithDecoder->decodeInt(&rdx, iardxStats);
-	  arithDecoder->decodeInt(&rdy, iardyStats);
+	  ri = 0;
 	}
-	refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
-	refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
+	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];
-      }
+	  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;
+	// 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;
 	}
-	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;
+	if (ri) {
+	  delete symbolBitmap;
 	}
-	s += bw;
-      }
-      if (ri) {
-	delete symbolBitmap;
       }
 
       // next instance

Index: JBIG2Stream.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/JBIG2Stream.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- JBIG2Stream.h	3 Mar 2005 19:46:00 -0000	1.1.1.1
+++ JBIG2Stream.h	31 Aug 2005 09:51:41 -0000	1.2
@@ -43,8 +43,8 @@
 private:
 
   void readSegments();
-  void readSymbolDictSeg(Guint segNum, Guint length,
-			 Guint *refSegs, Guint nRefSegs);
+  GBool readSymbolDictSeg(Guint segNum, Guint length,
+			  Guint *refSegs, Guint nRefSegs);
   void readTextRegionSeg(Guint segNum, GBool imm,
 			 GBool lossless, Guint length,
 			 Guint *refSegs, Guint nRefSegs);



More information about the poppler mailing list