[poppler] 2 commits - poppler/Catalog.cc poppler/DCTStream.cc poppler/DCTStream.h poppler/GfxFont.cc poppler/GfxState.cc poppler/JPEG2000Stream.cc poppler/JPEG2000Stream.h poppler/Link.cc poppler/Object.h poppler/Stream.cc poppler/Stream.h
Albert Astals Cid
aacid at kemper.freedesktop.org
Mon Jun 21 11:25:06 PDT 2010
poppler/Catalog.cc | 12 ----
poppler/DCTStream.cc | 51 ++++++++++++++-----
poppler/DCTStream.h | 3 +
poppler/GfxFont.cc | 22 +-------
poppler/GfxState.cc | 36 ++++----------
poppler/JPEG2000Stream.cc | 67 +++++++-------------------
poppler/JPEG2000Stream.h | 38 ++++++++++++++
poppler/Link.cc | 14 +----
poppler/Object.h | 4 +
poppler/Stream.cc | 90 +++++++++++++++++++----------------
poppler/Stream.h | 118 +++++++++++++++++++++++++++++++++++++++++++++-
11 files changed, 282 insertions(+), 173 deletions(-)
New commits:
commit 58a53ca0a4e8434e8478f8fe121067dcf05c017d
Author: Albert Astals Cid <aacid at kde.org>
Date: Mon Jun 21 19:24:20 2010 +0100
sqrt is much faster than pow 0.5
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index b7dd8c7..7140efc 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -965,9 +965,9 @@ void GfxCalRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
r = xyzrgb[0][0] * X + xyzrgb[0][1] * Y + xyzrgb[0][2] * Z;
g = xyzrgb[1][0] * X + xyzrgb[1][1] * Y + xyzrgb[1][2] * Z;
b = xyzrgb[2][0] * X + xyzrgb[2][1] * Y + xyzrgb[2][2] * Z;
- rgb->r = dblToCol(pow(clip01(r), 0.5));
- rgb->g = dblToCol(pow(clip01(g), 0.5));
- rgb->b = dblToCol(pow(clip01(b), 0.5));
+ rgb->r = dblToCol(sqrt(clip01(r)));
+ rgb->g = dblToCol(sqrt(clip01(g)));
+ rgb->b = dblToCol(sqrt(clip01(b)));
}
void GfxCalRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
commit bf86a9fc464aca57ebec207a213dcc2cc6031940
Author: Albert Astals Cid <aacid at kde.org>
Date: Mon Jun 21 19:20:47 2010 +0100
introduce getChars to save some method calls
Can give us a decent speedup when we go a lot though this methods
diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc
index 900cdd7..dbf9af2 100644
--- a/poppler/Catalog.cc
+++ b/poppler/Catalog.cc
@@ -192,7 +192,6 @@ GooString *Catalog::readMetadata() {
GooString *s;
Dict *dict;
Object obj;
- int c;
if (metadata.isNone()) {
Object catDict;
@@ -217,10 +216,7 @@ GooString *Catalog::readMetadata() {
}
obj.free();
s = new GooString();
- metadata.streamReset();
- while ((c = metadata.streamGetChar()) != EOF) {
- s->append(c);
- }
+ metadata.getStream()->fillGooString(s);
metadata.streamClose();
return s;
}
@@ -409,11 +405,7 @@ GooString *Catalog::getJS(int i)
else if (obj2.isStream()) {
Stream *stream = obj2.getStream();
js = new GooString();
- stream->reset();
- int j;
- while ((j = stream->getChar()) != EOF) {
- js->append((char)j);
- }
+ stream->fillGooString(js);
}
obj2.free();
obj.free();
diff --git a/poppler/DCTStream.cc b/poppler/DCTStream.cc
index 5cbaced..1b15619 100644
--- a/poppler/DCTStream.cc
+++ b/poppler/DCTStream.cc
@@ -145,27 +145,48 @@ void DCTStream::reset() {
}
}
+// we can not go with inline since gcc
+// refuses to inline because of setjmp
+#define DO_GET_CHAR \
+ if (current == limit) { \
+ if (cinfo.output_scanline < cinfo.output_height) \
+ { \
+ if (!setjmp(src.setjmp_buffer)) \
+ { \
+ if (!jpeg_read_scanlines(&cinfo, row_buffer, 1)) c = EOF; \
+ else { \
+ current = &row_buffer[0][0]; \
+ limit = &row_buffer[0][(cinfo.output_width - 1) * cinfo.output_components] + cinfo.output_components; \
+ c = *current; \
+ ++current; \
+ } \
+ } \
+ else c = EOF; \
+ } \
+ else c = EOF; \
+ } else { \
+ c = *current; \
+ ++current; \
+ } \
+
int DCTStream::getChar() {
int c;
- if (current == limit) {
- if (cinfo.output_scanline < cinfo.output_height)
- {
- if (!setjmp(src.setjmp_buffer))
- {
- if (!jpeg_read_scanlines(&cinfo, row_buffer, 1)) return EOF;
- current = &row_buffer[0][0];
- limit = &row_buffer[0][(cinfo.output_width - 1) * cinfo.output_components] + cinfo.output_components;
- }
- else return EOF;
- }
- else return EOF;
- }
- c = *current;
- ++current;
+ DO_GET_CHAR
+
return c;
}
+int DCTStream::getChars(int nChars, Guchar *buffer) {
+ int c;
+ for (int i = 0; i < nChars; ++i) {
+ DO_GET_CHAR
+ if (likely(c != EOF)) buffer[i] = c;
+ else return i;
+ }
+ return nChars;
+}
+
int DCTStream::lookChar() {
return *current;
}
diff --git a/poppler/DCTStream.h b/poppler/DCTStream.h
index 6768ff2..65196ec 100644
--- a/poppler/DCTStream.h
+++ b/poppler/DCTStream.h
@@ -69,6 +69,9 @@ public:
private:
void init();
+ virtual GBool hasGetChars() { return true; }
+ virtual int getChars(int nChars, Guchar *buffer);
+
JSAMPLE *current;
JSAMPLE *limit;
struct jpeg_decompress_struct cinfo;
diff --git a/poppler/GfxFont.cc b/poppler/GfxFont.cc
index f823faf..aeab6f3 100644
--- a/poppler/GfxFont.cc
+++ b/poppler/GfxFont.cc
@@ -10,7 +10,7 @@
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
-// Copyright (C) 2005, 2006, 2008, 2009 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2005, 2006, 2008-2010 Albert Astals Cid <aacid at kde.org>
// Copyright (C) 2005, 2006 Kristian Høgsberg <krh at redhat.com>
// Copyright (C) 2006 Takashi Iwai <tiwai at suse.de>
// Copyright (C) 2007 Julien Rebetez <julienr at svn.gnome.org>
@@ -421,17 +421,13 @@ CharCodeToUnicode *GfxFont::readToUnicodeCMap(Dict *fontDict, int nBits,
CharCodeToUnicode *ctu) {
GooString *buf;
Object obj1;
- int c;
if (!fontDict->lookup("ToUnicode", &obj1)->isStream()) {
obj1.free();
return NULL;
}
buf = new GooString();
- obj1.streamReset();
- while ((c = obj1.streamGetChar()) != EOF) {
- buf->append(c);
- }
+ obj1.getStream()->fillGooString(buf);
obj1.streamClose();
obj1.free();
if (ctu) {
@@ -488,8 +484,6 @@ char *GfxFont::readEmbFontFile(XRef *xref, int *len) {
char *buf;
Object obj1, obj2;
Stream *str;
- int c;
- int size, i;
obj1.initRef(embFontID.num, embFontID.gen);
obj1.fetch(xref, &obj2);
@@ -503,17 +497,7 @@ char *GfxFont::readEmbFontFile(XRef *xref, int *len) {
}
str = obj2.getStream();
- buf = NULL;
- i = size = 0;
- str->reset();
- while ((c = str->getChar()) != EOF) {
- if (i == size) {
- size += 4096;
- buf = (char *)grealloc(buf, size);
- }
- buf[i++] = c;
- }
- *len = i;
+ buf = (char*)str->toUnsignedChars(len);
str->close();
obj2.free();
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 61dac24..b7dd8c7 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -1484,22 +1484,11 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, Gfx *gfx) {
arr->get(1, &obj1);
dict = obj1.streamGetDict();
Guchar *profBuf;
- unsigned int bufSize;
Stream *iccStream = obj1.getStream();
- int c;
- unsigned int size = 0;
-
- bufSize = 65536;
- profBuf = (Guchar *)gmallocn(bufSize,1);
- iccStream->reset();
- while ((c = iccStream->getChar()) != EOF) {
- if (bufSize <= size) {
- bufSize += 65536;
- profBuf = (Guchar *)greallocn(profBuf,bufSize,1);
- }
- profBuf[size++] = c;
- }
- cmsHPROFILE hp = cmsOpenProfileFromMem(profBuf,size);
+ int length = 0;
+
+ profBuf = iccStream->toUnsignedChars(&length, 65536, 65536);
+ cmsHPROFILE hp = cmsOpenProfileFromMem(profBuf,length);
gfree(profBuf);
if (hp == 0) {
error(-1, "read ICCBased color space profile error");
@@ -1718,7 +1707,6 @@ GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr, Gfx *gfx) {
GfxColorSpace *baseA;
int indexHighA;
Object obj1;
- int x;
char *s;
int n, i, j;
@@ -1755,12 +1743,10 @@ GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr, Gfx *gfx) {
if (obj1.isStream()) {
obj1.streamReset();
for (i = 0; i <= indexHighA; ++i) {
- for (j = 0; j < n; ++j) {
- if ((x = obj1.streamGetChar()) == EOF) {
- error(-1, "Bad Indexed color space (lookup table stream too short) padding with zeroes");
- x = 0;
- }
- cs->lookup[i*n + j] = (Guchar)x;
+ const int readChars = obj1.streamGetChars(n, &cs->lookup[i*n]);
+ for (j = readChars; j < n; ++j) {
+ error(-1, "Bad Indexed color space (lookup table stream too short) padding with zeroes");
+ cs->lookup[i*n + j] = 0;
}
}
obj1.streamClose();
diff --git a/poppler/JPEG2000Stream.cc b/poppler/JPEG2000Stream.cc
index 3b301f7..d52f088 100644
--- a/poppler/JPEG2000Stream.cc
+++ b/poppler/JPEG2000Stream.cc
@@ -4,7 +4,7 @@
//
// A JPX stream decoder using OpenJPEG
//
-// Copyright 2008, 2009 Albert Astals Cid <aacid at kde.org>
+// Copyright 2008-2010 Albert Astals Cid <aacid at kde.org>
//
// Licensed under GPLv2 or later
//
@@ -43,42 +43,34 @@ int JPXStream::getPos() {
return counter;
}
+int JPXStream::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;
+ }
+ return nChars;
+}
+
int JPXStream::getChar() {
- int result = lookChar();
- ++counter;
- return result;
+ return doGetChar();
}
-#define BUFFER_INCREASE 4096
+#define BUFFER_INITIAL_SIZE 4096
void JPXStream::init()
{
Object oLen;
if (getDict()) getDict()->lookup("Length", &oLen);
- int bufSize = BUFFER_INCREASE;
+ int bufSize = BUFFER_INITIAL_SIZE;
if (oLen.isInt()) bufSize = oLen.getInt();
oLen.free();
- unsigned char *buf = (unsigned char*)gmallocn(bufSize, sizeof(unsigned char));
- int index = 0;
-
- str->reset();
- int c = str->getChar();
- while(c != EOF)
- {
- if (index >= bufSize)
- {
- bufSize += BUFFER_INCREASE;
- buf = (unsigned char*)greallocn(buf, bufSize, sizeof(unsigned char));
- }
- buf[index] = c;
- ++index;
- c = str->getChar();
- }
-
- init2(buf, index, CODEC_JP2);
-
+
+ int length = 0;
+ unsigned char *buf = str->toUnsignedChars(&length, bufSize);
+ init2(buf, length, CODEC_JP2);
free(buf);
counter = 0;
@@ -143,30 +135,7 @@ error:
}
int JPXStream::lookChar() {
- if (inited == gFalse) init();
-
- if (!image) return EOF;
-
- int w = image->comps[0].w;
- int h = image->comps[0].h;
-
- int y = (counter / image->numcomps) / w;
- int x = (counter / image->numcomps) % w;
- if (y >= h) return EOF;
-
- int component = counter % image->numcomps;
-
- int adjust = 0;
- if (image->comps[component].prec > 8) {
- adjust = image->comps[component].prec - 8;
- }
-
- int r = image->comps[component].data[y * w + x];
- r += (image->comps[component].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
-
- unsigned char rc = (unsigned char) ((r >> adjust)+((r >> (adjust-1))%2));
-
- return rc;
+ return doLookChar();
}
GooString *JPXStream::getPSFilter(int psLevel, char *indent) {
diff --git a/poppler/JPEG2000Stream.h b/poppler/JPEG2000Stream.h
index ea32093..adec1c3 100644
--- a/poppler/JPEG2000Stream.h
+++ b/poppler/JPEG2000Stream.h
@@ -4,7 +4,7 @@
//
// A JPX stream decoder using OpenJPEG
//
-// Copyright 2008 Albert Astals Cid <aacid at kde.org>
+// Copyright 2008, 2010 Albert Astals Cid <aacid at kde.org>
//
// Licensed under GPLv2 or later
//
@@ -39,6 +39,42 @@ private:
void init();
void init2(unsigned char *buf, int bufLen, OPJ_CODEC_FORMAT format);
+ virtual GBool hasGetChars() { return true; }
+ virtual int getChars(int nChars, Guchar *buffer);
+
+ inline int doGetChar() {
+ int result = doLookChar();
+ ++counter;
+ return result;
+ }
+
+ inline int doLookChar() {
+ if (inited == gFalse) init();
+
+ if (!image) return EOF;
+
+ int w = image->comps[0].w;
+ int h = image->comps[0].h;
+
+ int y = (counter / image->numcomps) / w;
+ int x = (counter / image->numcomps) % w;
+ if (y >= h) return EOF;
+
+ int component = counter % image->numcomps;
+
+ int adjust = 0;
+ if (image->comps[component].prec > 8) {
+ adjust = image->comps[component].prec - 8;
+ }
+
+ int r = image->comps[component].data[y * w + x];
+ r += (image->comps[component].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
+
+ unsigned char rc = (unsigned char) ((r >> adjust)+((r >> (adjust-1))%2));
+
+ return rc;
+ }
+
opj_image_t *image;
opj_dinfo_t *dinfo;
int counter;
diff --git a/poppler/Link.cc b/poppler/Link.cc
index 5d7b779..b6d7f2d 100644
--- a/poppler/Link.cc
+++ b/poppler/Link.cc
@@ -16,7 +16,7 @@
// Copyright (C) 2006, 2008 Pino Toscano <pino at kde.org>
// Copyright (C) 2007,2010 Carlos Garcia Campos <carlosgc at gnome.org>
// Copyright (C) 2008 Hugo Mercier <hmercier31 at gmail.com>
-// Copyright (C) 2008, 2009 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2008-2010 Albert Astals Cid <aacid at kde.org>
// Copyright (C) 2009 Kovid Goyal <kovid at kovidgoyal.net>
// Copyright (C) 2009 Ilya Gorenbein <igorenbein at finjan.com>
//
@@ -704,11 +704,7 @@ LinkRendition::LinkRendition(Object *obj) {
} else if (tmp.isStream()) {
Stream *stream = tmp.getStream();
js = new GooString();
- stream->reset();
- int i;
- while ((i = stream->getChar()) != EOF) {
- js->append((char)i);
- }
+ stream->fillGooString(js);
} else {
error(-1, "Invalid Rendition Action: JS not string or stream");
}
@@ -766,11 +762,7 @@ LinkJavaScript::LinkJavaScript(Object *jsObj) {
else if (jsObj->isStream()) {
Stream *stream = jsObj->getStream();
js = new GooString();
- stream->reset();
- int i;
- while ((i = stream->getChar()) != EOF) {
- js->append((char)i);
- }
+ stream->fillGooString(js);
}
}
diff --git a/poppler/Object.h b/poppler/Object.h
index 3038d0c..6d60d0f 100644
--- a/poppler/Object.h
+++ b/poppler/Object.h
@@ -223,6 +223,7 @@ public:
void streamReset();
void streamClose();
int streamGetChar();
+ int streamGetChars(int nChars, Guchar *buffer);
int streamLookChar();
char *streamGetLine(char *buf, int size);
Guint streamGetPos();
@@ -334,6 +335,9 @@ inline void Object::streamClose()
inline int Object::streamGetChar()
{ OBJECT_TYPE_CHECK(objStream); return stream->getChar(); }
+inline int Object::streamGetChars(int nChars, Guchar *buffer)
+ { OBJECT_TYPE_CHECK(objStream); return stream->doGetChars(nChars, buffer); }
+
inline int Object::streamLookChar()
{ OBJECT_TYPE_CHECK(objStream); return stream->lookChar(); }
diff --git a/poppler/Stream.cc b/poppler/Stream.cc
index 0771e25..988f99a 100644
--- a/poppler/Stream.cc
+++ b/poppler/Stream.cc
@@ -14,7 +14,7 @@
// under GPL version 2 or later
//
// Copyright (C) 2005 Jeff Muizelaar <jeff at infidigm.net>
-// Copyright (C) 2006-2009 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2006-2010 Albert Astals Cid <aacid at kde.org>
// Copyright (C) 2007 Krzysztof Kowalczyk <kkowalczyk at gmail.com>
// Copyright (C) 2008 Julien Rebetez <julien at fhtagn.net>
// Copyright (C) 2009 Carlos Garcia Campos <carlosgc at gnome.org>
@@ -99,6 +99,15 @@ int Stream::getRawChar() {
return EOF;
}
+int Stream::getChars(int nChars, Guchar *buffer) {
+ error(-1, "Internal: called getChars() on non-predictor stream");
+ return 0;
+}
+
+void Stream::getRawChars(int nChars, int *buffer) {
+ error(-1, "Internal: called getRawChars() on non-predictor stream");
+}
+
char *Stream::getLine(char *buf, int size) {
int i;
int c;
@@ -461,9 +470,8 @@ Guchar *ImageStream::getLine() {
}
} else if (nBits == 8) {
Guchar *line = imgLine;
- for (i = 0; i < nVals; ++i) {
- *line++ = str->getChar();
- }
+ int readChars = str->doGetChars(nVals, line);
+ for ( ; readChars < nVals; readChars++) line[readChars] = EOF;
} 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
@@ -543,12 +551,17 @@ int StreamPredictor::lookChar() {
}
int StreamPredictor::getChar() {
- if (predIdx >= rowBytes) {
- if (!getNextLine()) {
- return EOF;
- }
+ return doGetChar();
+}
+
+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;
}
- return predLine[predIdx++];
+ return nChars;
}
GBool StreamPredictor::getNextLine() {
@@ -571,13 +584,15 @@ GBool StreamPredictor::getNextLine() {
}
// read the raw line, apply PNG (byte) predictor
+ int *rawCharLine = new int[rowBytes - pixBytes];
+ str->getRawChars(rowBytes - pixBytes, rawCharLine);
memset(upLeftBuf, 0, pixBytes + 1);
for (i = pixBytes; i < rowBytes; ++i) {
for (j = pixBytes; j > 0; --j) {
upLeftBuf[j] = upLeftBuf[j-1];
}
upLeftBuf[0] = predLine[i];
- if ((c = str->getRawChar()) == EOF) {
+ if ((c = rawCharLine[i - pixBytes]) == EOF) {
if (i > pixBytes) {
// this ought to return false, but some (broken) PDF files
// contain truncated image data, and Adobe apparently reads the
@@ -621,6 +636,7 @@ GBool StreamPredictor::getNextLine() {
break;
}
}
+ delete[] rawCharLine;
// apply TIFF (component) predictor
if (predictor == 2) {
@@ -1237,16 +1253,13 @@ int LZWStream::lookChar() {
return seqBuf[seqIndex];
}
+void LZWStream::getRawChars(int nChars, int *buffer) {
+ for (int i = 0; i < nChars; ++i)
+ buffer[i] = doGetRawChar();
+}
+
int LZWStream::getRawChar() {
- if (eof) {
- return EOF;
- }
- if (seqIndex >= seqLength) {
- if (!processNextCode()) {
- return EOF;
- }
- }
- return seqBuf[seqIndex++];
+ return doGetRawChar();
}
void LZWStream::reset() {
@@ -4231,20 +4244,20 @@ void FlateStream::reset() {
}
int FlateStream::getChar() {
- int c;
+ return doGetChar();
+}
+int FlateStream::getChars(int nChars, Guchar *buffer) {
if (pred) {
- return pred->getChar();
- }
- while (remain == 0) {
- if (endOfBlock && eof)
- return EOF;
- readSome();
+ return pred->getChars(nChars, buffer);
+ } else {
+ for (int i = 0; i < nChars; ++i) {
+ const int c = doGetChar();
+ if (likely(c != EOF)) buffer[i] = c;
+ else return i;
+ }
+ return nChars;
}
- c = buf[index];
- index = (index + 1) & flateMask;
- --remain;
- return c;
}
int FlateStream::lookChar() {
@@ -4262,18 +4275,13 @@ int FlateStream::lookChar() {
return c;
}
-int FlateStream::getRawChar() {
- int c;
+void FlateStream::getRawChars(int nChars, int *buffer) {
+ for (int i = 0; i < nChars; ++i)
+ buffer[i] = doGetRawChar();
+}
- while (remain == 0) {
- if (endOfBlock && eof)
- return EOF;
- readSome();
- }
- c = buf[index];
- index = (index + 1) & flateMask;
- --remain;
- return c;
+int FlateStream::getRawChar() {
+ return doGetRawChar();
}
GooString *FlateStream::getPSFilter(int psLevel, char *indent) {
diff --git a/poppler/Stream.h b/poppler/Stream.h
index 49ae8fb..583278f 100644
--- a/poppler/Stream.h
+++ b/poppler/Stream.h
@@ -15,7 +15,7 @@
//
// Copyright (C) 2005 Jeff Muizelaar <jeff at infidigm.net>
// Copyright (C) 2008 Julien Rebetez <julien at fhtagn.net>
-// Copyright (C) 2008 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2008, 2010 Albert Astals Cid <aacid at kde.org>
// Copyright (C) 2009 Carlos Garcia Campos <carlosgc at gnome.org>
// Copyright (C) 2009 Stefan Thomas <thomas at eload24.com>
// Copyright (C) 2010 Hib Eris <hib at hiberis.nl>
@@ -106,6 +106,56 @@ public:
// Close down the stream.
virtual void close();
+ inline int doGetChars(int nChars, Guchar *buffer)
+ {
+ if (hasGetChars()) {
+ return getChars(nChars, buffer);
+ } else {
+ for (int i = 0; i < nChars; ++i) {
+ const int c = getChar();
+ if (likely(c != EOF)) buffer[i] = c;
+ else return i;
+ }
+ return nChars;
+ }
+ }
+
+ inline void fillGooString(GooString *s)
+ {
+ Guchar readBuf[4096];
+ int readChars;
+ reset();
+ while ((readChars = doGetChars(4096, readBuf)) != 0) {
+ s->append((const char *)readBuf, readChars);
+ }
+ }
+
+ inline Guchar *toUnsignedChars(int *length, int initialSize = 4096, int sizeIncrement = 4096)
+ {
+ int readChars;
+ Guchar *buf = (Guchar *)gmalloc(initialSize);
+ int size = initialSize;
+ *length = 0;
+ int charsToRead = initialSize;
+ bool continueReading = true;
+ reset();
+ while (continueReading && (readChars = doGetChars(charsToRead, &buf[*length])) != 0) {
+ *length += readChars;
+ if (readChars == charsToRead) {
+ if (lookChar() != EOF) {
+ size += sizeIncrement;
+ charsToRead = initialSize;
+ buf = (Guchar *)grealloc(buf, size);
+ } else {
+ continueReading = false;
+ }
+ } else {
+ continueReading = false;
+ }
+ }
+ return buf;
+ }
+
// Get next char from stream.
virtual int getChar() = 0;
@@ -115,6 +165,7 @@ public:
// Get next char from stream without using the predictor.
// This is only used by StreamPredictor.
virtual int getRawChar();
+ virtual void getRawChars(int nChars, int *buffer);
// Get next char directly from stream source, without filtering it
virtual int getUnfilteredChar () = 0;
@@ -166,6 +217,8 @@ public:
Stream *addFilters(Object *dict);
private:
+ virtual GBool hasGetChars() { return false; }
+ virtual int getChars(int nChars, Guchar *buffer);
Stream *makeFilter(char *name, Stream *str, Object *params);
@@ -347,11 +400,21 @@ public:
int lookChar();
int getChar();
+ int getChars(int nChars, Guchar *buffer);
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
@@ -383,7 +446,7 @@ public:
virtual void reset();
virtual void close();
virtual int getChar()
- { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
+ { return doGetChar(); }
virtual int lookChar()
{ return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
virtual int getPos() { return bufPos + (bufPtr - buf); }
@@ -397,6 +460,20 @@ public:
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;
+ }
+ return nChars;
+ }
FILE *f;
Guint start;
@@ -596,11 +673,24 @@ public:
virtual int getChar();
virtual int lookChar();
virtual int getRawChar();
+ virtual void getRawChars(int nChars, int *buffer);
virtual GooString *getPSFilter(int psLevel, char *indent);
virtual GBool isBinary(GBool last = gTrue);
private:
+ inline int doGetRawChar() {
+ if (eof) {
+ return EOF;
+ }
+ if (seqIndex >= seqLength) {
+ if (!processNextCode()) {
+ return EOF;
+ }
+ }
+ return seqBuf[seqIndex++];
+ }
+
StreamPredictor *pred; // predictor
int early; // early parameter
GBool eof; // true if at eof
@@ -855,11 +945,35 @@ public:
virtual int getChar();
virtual int lookChar();
virtual int getRawChar();
+ virtual void getRawChars(int nChars, int *buffer);
virtual GooString *getPSFilter(int psLevel, char *indent);
virtual GBool isBinary(GBool last = gTrue);
virtual void unfilteredReset ();
private:
+ inline int doGetRawChar() {
+ int c;
+
+ while (remain == 0) {
+ if (endOfBlock && eof)
+ return EOF;
+ readSome();
+ }
+ c = buf[index];
+ index = (index + 1) & flateMask;
+ --remain;
+ return c;
+ }
+
+ inline int doGetChar() {
+ if (pred) {
+ return pred->getChar();
+ }
+ return doGetRawChar();
+ }
+
+ virtual GBool hasGetChars() { return true; }
+ virtual int getChars(int nChars, Guchar *buffer);
StreamPredictor *pred; // predictor
Guchar buf[flateWindow]; // output data buffer
More information about the poppler
mailing list