[poppler] Branch 'xpdf303merge' - 2 commits - poppler/JBIG2Stream.cc poppler/JBIG2Stream.h poppler/Stream.cc poppler/Stream.h

Albert Astals Cid aacid at kemper.freedesktop.org
Thu Sep 8 07:15:21 PDT 2011


 poppler/JBIG2Stream.cc |   17 ++++
 poppler/JBIG2Stream.h  |    2 
 poppler/Stream.cc      |  171 +++++++++++++++++++++++++++++++++++++++----------
 poppler/Stream.h       |   57 +++++++++-------
 4 files changed, 189 insertions(+), 58 deletions(-)

New commits:
commit 41a620ef60507ceda42a14d06d6587ed10016468
Author: Albert Astals Cid <aacid at kde.org>
Date:   Thu Sep 8 16:18:01 2011 +0200

    xpdf303: Adapt use of getBlock to our use of getChars

diff --git a/poppler/Stream.cc b/poppler/Stream.cc
index b155f9b..5ebd5af 100644
--- a/poppler/Stream.cc
+++ b/poppler/Stream.cc
@@ -415,21 +415,34 @@ ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) {
   nBits = nBitsA;
 
   nVals = width * nComps;
-  if (nBits == 1) {
-    imgLineSize = (nVals + 7) & ~7;
-  } else {
-    imgLineSize = nVals;
-  }
-  if (width > INT_MAX / nComps) {
+  inputLineSize = (nVals * nBits + 7) >> 3;
+  if (nVals > INT_MAX / nBits - 7) {
     // force a call to gmallocn(-1,...), which will throw an exception
-    imgLineSize = -1;
+    inputLineSize = -1;
+  }
+  inputLine = (Guchar *)gmallocn(inputLineSize, sizeof(char));
+  if (nBits == 8) {
+    imgLine = (Guchar *)inputLine;
+  } else {
+    if (nBits == 1) {
+      imgLineSize = (nVals + 7) & ~7;
+    } else {
+      imgLineSize = nVals;
+    }
+    if (width > INT_MAX / nComps) {
+      // force a call to gmallocn(-1,...), which will throw an exception
+      imgLineSize = -1;
+    }
+    imgLine = (Guchar *)gmallocn(imgLineSize, sizeof(Guchar));
   }
-  imgLine = (Guchar *)gmallocn(imgLineSize, sizeof(Guchar));
   imgIdx = nVals;
 }
 
 ImageStream::~ImageStream() {
-  gfree(imgLine);
+  if (imgLine != (Guchar *)inputLine) {
+    gfree(imgLine);
+  }
+  gfree(inputLine);
 }
 
 void ImageStream::reset() {
@@ -460,10 +473,14 @@ Guchar *ImageStream::getLine() {
   int bits;
   int c;
   int i;
-
+  Guchar *p;
+ 
+  int readChars = str->doGetChars(inputLineSize, inputLine);
+  for ( ; readChars < inputLineSize; readChars++) inputLine[readChars] = EOF;
   if (nBits == 1) {
+    p = inputLine;
     for (i = 0; i < nVals; i += 8) {
-      c = str->getChar();
+      c = *p++;
       imgLine[i+0] = (Guchar)((c >> 7) & 1);
       imgLine[i+1] = (Guchar)((c >> 6) & 1);
       imgLine[i+2] = (Guchar)((c >> 5) & 1);
@@ -474,25 +491,25 @@ Guchar *ImageStream::getLine() {
       imgLine[i+7] = (Guchar)(c & 1);
     }
   } else if (nBits == 8) {
-    Guchar *line = imgLine;
-    int readChars = str->doGetChars(nVals, line);
-    for ( ; readChars < nVals; readChars++) line[readChars] = EOF;
+    // special case: imgLine == inputLine
   } else if (nBits == 16) {
     // this is a hack to support 16 bits images, everywhere
     // we assume a component fits in 8 bits, with this hack
     // we treat 16 bit images as 8 bit ones until it's fixed correctly.
     // The hack has another part on GfxImageColorMap::GfxImageColorMap
+    p = inputLine;
     for (i = 0; i < nVals; ++i) {
-      imgLine[i] = str->getChar();
-      str->getChar();
+      imgLine[i] = *p++;
+      p++;
     }
   } else {
     bitMask = (1 << nBits) - 1;
     buf = 0;
     bits = 0;
+    p = inputLine;
     for (i = 0; i < nVals; ++i) {
       if (bits < nBits) {
-	buf = (buf << 8) | (str->getChar() & 0xff);
+	buf = (buf << 8) | (*p++ & 0xff);
 	bits += 8;
       }
       imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask);
@@ -503,12 +520,7 @@ Guchar *ImageStream::getLine() {
 }
 
 void ImageStream::skipLine() {
-  int n, i;
-
-  n = (nVals * nBits + 7) >> 3;
-  for (i = 0; i < n; ++i) {
-    str->getChar();
-  }
+  str->doGetChars(inputLineSize, inputLine);
 }
 
 //------------------------------------------------------------------------
diff --git a/poppler/Stream.h b/poppler/Stream.h
index 539a579..6accabe 100644
--- a/poppler/Stream.h
+++ b/poppler/Stream.h
@@ -385,6 +385,8 @@ private:
   int nComps;			// components per pixel
   int nBits;			// bits per component
   int nVals;			// components per line
+  int inputLineSize;		// input line buffer size
+  Guchar *inputLine;		// input line buffer
   Guchar *imgLine;		// line buffer
   int imgIdx;			// current index in imgLine
 };
commit 2f7701fe730a648d0a1d181c5b20e4802640dc52
Author: Albert Astals Cid <aacid at kde.org>
Date:   Thu Sep 8 15:59:27 2011 +0200

    xpdf303: Adapt xpdf getBlock to our getChars

diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc
index 0f3c4d8..5a3e329 100644
--- a/poppler/JBIG2Stream.cc
+++ b/poppler/JBIG2Stream.cc
@@ -1272,6 +1272,23 @@ int JBIG2Stream::getPos() {
   return dataPtr - pageBitmap->getDataPtr();
 }
 
+int JBIG2Stream::getChars(int nChars, Guchar *buffer) {
+  int n, i;
+
+  if (nChars <= 0) {
+    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 NULL;
 }
diff --git a/poppler/JBIG2Stream.h b/poppler/JBIG2Stream.h
index 504ecea..c518aa5 100644
--- a/poppler/JBIG2Stream.h
+++ b/poppler/JBIG2Stream.h
@@ -57,6 +57,8 @@ public:
   virtual GBool isBinary(GBool last = gTrue);
 
 private:
+  virtual GBool hasGetChars() { return true; }
+  virtual int getChars(int nChars, Guchar *buffer);
 
   void readSegments();
   GBool readSymbolDictSeg(Guint segNum, Guint length,
diff --git a/poppler/Stream.cc b/poppler/Stream.cc
index 910418e..b155f9b 100644
--- a/poppler/Stream.cc
+++ b/poppler/Stream.cc
@@ -556,17 +556,33 @@ int StreamPredictor::lookChar() {
 }
 
 int StreamPredictor::getChar() {
-  return doGetChar();
+  if (predIdx >= rowBytes) {
+    if (!getNextLine()) {
+      return EOF;
+    }
+  }
+  return predLine[predIdx++];
 }
 
-int StreamPredictor::getChars(int nChars, Guchar *buffer)
-{
-  for (int i = 0; i < nChars; ++i) {
-    const int c = doGetChar();
-    if (likely(c != EOF)) buffer[i] = c;
-    else return i;
+int StreamPredictor::getChars(int nChars, Guchar *buffer) {
+  int n, m;
+
+  n = 0;
+  while (n < nChars) {
+    if (predIdx >= rowBytes) {
+      if (!getNextLine()) {
+	break;
+      }
+    }
+    m = rowBytes - predIdx;
+    if (m > nChars - n) {
+      m = nChars - n;
+    }
+    memcpy(buffer + n, predLine + predIdx, m);
+    predIdx += m;
+    n += m;
   }
-  return nChars;
+  return n;
 }
 
 GBool StreamPredictor::getNextLine() {
@@ -954,6 +970,22 @@ void MemStream::reset() {
 void MemStream::close() {
 }
 
+int MemStream::getChars(int nChars, Guchar *buffer) {
+  int n;
+
+  if (nChars <= 0) {
+    return 0;
+  }
+  if (bufEnd - bufPtr < nChars) {
+    n = (int)(bufEnd - bufPtr);
+  } else {
+    n = nChars;
+  }
+  memcpy(buffer, bufPtr, n);
+  bufPtr += n;
+  return n;
+}
+
 void MemStream::setPos(Guint pos, int dir) {
   Guint i;
 
@@ -1012,6 +1044,16 @@ int EmbedStream::lookChar() {
   return str->lookChar();
 }
 
+int EmbedStream::getChars(int nChars, Guchar *buffer) {
+  if (nChars <= 0) {
+    return 0;
+  }
+  if (limited && length < (Guint)nChars) {
+    nChars = (int)length;
+  }
+  return str->doGetChars(nChars, buffer);
+}
+
 void EmbedStream::setPos(Guint pos, int dir) {
   error(errInternal, -1, "Internal: called setPos() on EmbedStream");
 }
@@ -1266,6 +1308,33 @@ int LZWStream::getRawChar() {
   return doGetRawChar();
 }
 
+int LZWStream::getChars(int nChars, Guchar *buffer) {
+  int n, m;
+
+  if (pred) {
+    return pred->getChars(nChars, buffer);
+  }
+  if (eof) {
+    return 0;
+  }
+  n = 0;
+  while (n < nChars) {
+    if (seqIndex >= seqLength) {
+      if (!processNextCode()) {
+	break;
+      }
+    }
+    m = seqLength - seqIndex;
+    if (m > nChars - n) {
+      m = nChars - n;
+    }
+    memcpy(buffer + n, seqBuf + seqIndex, m);
+    seqIndex += m;
+    n += m;
+  }
+  return n;
+}
+
 void LZWStream::reset() {
   str->reset();
   eof = gFalse;
@@ -1406,6 +1475,27 @@ void RunLengthStream::reset() {
   eof = gFalse;
 }
 
+int RunLengthStream::getChars(int nChars, Guchar *buffer) {
+  int n, m;
+
+  n = 0;
+  while (n < nChars) {
+    if (bufPtr >= bufEnd) {
+      if (!fillBuf()) {
+	break;
+      }
+    }
+    m = (int)(bufEnd - bufPtr);
+    if (m > nChars - n) {
+      m = nChars - n;
+    }
+    memcpy(buffer + n, bufPtr, m);
+    bufPtr += m;
+    n += m;
+  }
+  return n;
+}
+
 GooString *RunLengthStream::getPSFilter(int psLevel, const char *indent) {
   GooString *s;
 
@@ -4318,7 +4408,10 @@ void FlateStream::reset() {
 }
 
 int FlateStream::getChar() {
-  return doGetChar();
+  if (pred) {
+    return pred->getChar();
+  }
+  return doGetRawChar();
 }
 
 int FlateStream::getChars(int nChars, Guchar *buffer) {
@@ -4326,7 +4419,7 @@ int FlateStream::getChars(int nChars, Guchar *buffer) {
     return pred->getChars(nChars, buffer);
   } else {
     for (int i = 0; i < nChars; ++i) {
-      const int c = doGetChar();
+      const int c = doGetRawChar();
       if (likely(c != EOF)) buffer[i] = c;
       else return i;
     }
diff --git a/poppler/Stream.h b/poppler/Stream.h
index 9a5270f..539a579 100644
--- a/poppler/Stream.h
+++ b/poppler/Stream.h
@@ -413,15 +413,6 @@ private:
 
   GBool getNextLine();
 
-  inline int doGetChar() {
-    if (predIdx >= rowBytes) {
-      if (!getNextLine()) {
-        return EOF;
-      }
-    }
-    return predLine[predIdx++];
-  }
-
   Stream *str;			// base stream
   int predictor;		// predictor
   int width;			// pixels per line
@@ -453,7 +444,7 @@ public:
   virtual void reset();
   virtual void close();
   virtual int getChar()
-    { return doGetChar(); }
+    { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
   virtual int lookChar()
     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
   virtual int getPos() { return bufPos + (bufPtr - buf); }
@@ -468,18 +459,27 @@ private:
 
   GBool fillBuf();
   
-  inline int doGetChar()
-    { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
-
   virtual GBool hasGetChars() { return true; }
   virtual int getChars(int nChars, Guchar *buffer)
     {
-      for (int i = 0; i < nChars; ++i) {
-        const int c = doGetChar();
-        if (likely(c != EOF)) buffer[i] = c;
-        else return i;
+      int n, m;
+
+      n = 0;
+      while (n < nChars) {
+        if (bufPtr >= bufEnd) {
+          if (!fillBuf()) {
+            break;
+          }
+        }
+        m = (int)(bufEnd - bufPtr);
+        if (m > nChars - n) {
+          m = nChars - n;
+        }
+        memcpy(buffer + n, bufPtr, m);
+        bufPtr += m;
+        n += m;
       }
-      return nChars;
+      return n;
     }
 
   FILE *f;
@@ -570,6 +570,9 @@ public:
 
 private:
 
+  virtual GBool hasGetChars() { return true; }
+  virtual int getChars(int nChars, Guchar *buffer);
+
   char *buf;
   Guint start;
   char *bufEnd;
@@ -609,6 +612,9 @@ public:
 
 private:
 
+  virtual GBool hasGetChars() { return true; }
+  virtual int getChars(int nChars, Guchar *buffer);
+
   Stream *str;
   GBool limited;
 };
@@ -682,6 +688,9 @@ public:
 
 private:
 
+  virtual GBool hasGetChars() { return true; }
+  virtual int getChars(int nChars, Guchar *buffer);
+
   inline int doGetRawChar() {
     if (eof) {
       return EOF;
@@ -738,6 +747,9 @@ public:
 
 private:
 
+  virtual GBool hasGetChars() { return true; }
+  virtual int getChars(int nChars, Guchar *buffer);
+
   char buf[128];		// buffer
   char *bufPtr;			// next char to read
   char *bufEnd;			// end of buffer
@@ -968,13 +980,6 @@ private:
     return c;
   }
 
-  inline int doGetChar() {
-    if (pred) {
-      return pred->getChar();
-    }
-    return doGetRawChar();
-  }
-
   virtual GBool hasGetChars() { return true; }
   virtual int getChars(int nChars, Guchar *buffer);
 


More information about the poppler mailing list