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 <[email protected]> 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 <[email protected]> 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 <[email protected]> +// Copyright (C) 2005, 2006, 2008-2010 Albert Astals Cid <[email protected]> // Copyright (C) 2005, 2006 Kristian Høgsberg <[email protected]> // Copyright (C) 2006 Takashi Iwai <[email protected]> // Copyright (C) 2007 Julien Rebetez <[email protected]> @@ -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 <[email protected]> +// Copyright 2008-2010 Albert Astals Cid <[email protected]> // // 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 <[email protected]> +// Copyright 2008, 2010 Albert Astals Cid <[email protected]> // // 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 <[email protected]> // Copyright (C) 2007,2010 Carlos Garcia Campos <[email protected]> // Copyright (C) 2008 Hugo Mercier <[email protected]> -// Copyright (C) 2008, 2009 Albert Astals Cid <[email protected]> +// Copyright (C) 2008-2010 Albert Astals Cid <[email protected]> // Copyright (C) 2009 Kovid Goyal <[email protected]> // Copyright (C) 2009 Ilya Gorenbein <[email protected]> // @@ -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 <[email protected]> -// Copyright (C) 2006-2009 Albert Astals Cid <[email protected]> +// Copyright (C) 2006-2010 Albert Astals Cid <[email protected]> // Copyright (C) 2007 Krzysztof Kowalczyk <[email protected]> // Copyright (C) 2008 Julien Rebetez <[email protected]> // Copyright (C) 2009 Carlos Garcia Campos <[email protected]> @@ -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 <[email protected]> // Copyright (C) 2008 Julien Rebetez <[email protected]> -// Copyright (C) 2008 Albert Astals Cid <[email protected]> +// Copyright (C) 2008, 2010 Albert Astals Cid <[email protected]> // Copyright (C) 2009 Carlos Garcia Campos <[email protected]> // Copyright (C) 2009 Stefan Thomas <[email protected]> // Copyright (C) 2010 Hib Eris <[email protected]> @@ -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
_______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
