1
//========================================================================
5
// Copyright 1996-2003 Glyph & Cog, LLC
7
//========================================================================
9
//========================================================================
11
// Modified under the Poppler project - http://poppler.freedesktop.org
13
// All changes made under the Poppler project to this file are licensed
14
// under GPL version 2 or later
16
// Copyright (C) 2005 Jeff Muizelaar <jeff@infidigm.net>
17
// Copyright (C) 2006-2010 Albert Astals Cid <aacid@kde.org>
18
// Copyright (C) 2007 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
19
// Copyright (C) 2008 Julien Rebetez <julien@fhtagn.net>
20
// Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
21
// Copyright (C) 2009 Glenn Ganz <glenn.ganz@uptime.ch>
22
// Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
23
// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
24
// Copyright (C) 2010 Tomas Hoger <thoger@redhat.com>
26
// To see a description of the changes please see the Changelog file that
27
// came with your tarball or type make ChangeLog if you are building from git
29
//========================================================================
33
#ifdef USE_GCC_PRAGMAS
34
#pragma implementation
47
#include "goo/gfile.h"
48
#include "poppler-config.h"
54
#include "JBIG2Stream.h"
55
#include "Stream-CCITT.h"
56
#include "CachedFile.h"
59
#include "DCTStream.h"
63
#include "FlateStream.h"
66
#ifdef ENABLE_LIBOPENJPEG
67
#include "JPEG2000Stream.h"
69
#include "JPXStream.h"
73
static GBool setDJSYSFLAGS = gFalse;
84
//------------------------------------------------------------------------
85
// Stream (base class)
86
//------------------------------------------------------------------------
95
void Stream::close() {
98
int Stream::getRawChar() {
99
error(-1, "Internal: called getRawChar() on non-predictor stream");
103
int Stream::getChars(int nChars, Guchar *buffer) {
104
error(-1, "Internal: called getChars() on non-predictor stream");
108
void Stream::getRawChars(int nChars, int *buffer) {
109
error(-1, "Internal: called getRawChars() on non-predictor stream");
112
char *Stream::getLine(char *buf, int size) {
116
if (lookChar() == EOF)
118
for (i = 0; i < size - 1; ++i) {
120
if (c == EOF || c == '\n')
123
if ((c = lookChar()) == '\n')
133
GooString *Stream::getPSFilter(int psLevel, char *indent) {
134
return new GooString();
137
Stream *Stream::addFilters(Object *dict) {
139
Object params, params2;
144
dict->dictLookup("Filter", &obj);
147
dict->dictLookup("F", &obj);
149
dict->dictLookup("DecodeParms", ¶ms);
150
if (params.isNull()) {
152
dict->dictLookup("DP", ¶ms);
155
str = makeFilter(obj.getName(), str, ¶ms);
156
} else if (obj.isArray()) {
157
for (i = 0; i < obj.arrayGetLength(); ++i) {
158
obj.arrayGet(i, &obj2);
159
if (params.isArray())
160
params.arrayGet(i, ¶ms2);
164
str = makeFilter(obj2.getName(), str, ¶ms2);
166
error(getPos(), "Bad filter name");
167
str = new EOFStream(str);
172
} else if (!obj.isNull()) {
173
error(getPos(), "Bad 'Filter' attribute in stream");
181
Stream *Stream::makeFilter(char *name, Stream *str, Object *params) {
182
int pred; // parameters
187
GBool endOfLine, byteAlign, endOfBlock, black;
192
if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
193
str = new ASCIIHexStream(str);
194
} else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) {
195
str = new ASCII85Stream(str);
196
} else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) {
202
if (params->isDict()) {
203
params->dictLookup("Predictor", &obj);
207
params->dictLookup("Columns", &obj);
209
columns = obj.getInt();
211
params->dictLookup("Colors", &obj);
213
colors = obj.getInt();
215
params->dictLookup("BitsPerComponent", &obj);
219
params->dictLookup("EarlyChange", &obj);
221
early = obj.getInt();
224
str = new LZWStream(str, pred, columns, colors, bits, early);
225
} else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) {
226
str = new RunLengthStream(str);
227
} else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) {
235
if (params->isDict()) {
236
params->dictLookup("K", &obj);
238
encoding = obj.getInt();
241
params->dictLookup("EndOfLine", &obj);
243
endOfLine = obj.getBool();
246
params->dictLookup("EncodedByteAlign", &obj);
248
byteAlign = obj.getBool();
251
params->dictLookup("Columns", &obj);
253
columns = obj.getInt();
256
params->dictLookup("Rows", &obj);
261
params->dictLookup("EndOfBlock", &obj);
263
endOfBlock = obj.getBool();
266
params->dictLookup("BlackIs1", &obj);
268
black = obj.getBool();
272
str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign,
273
columns, rows, endOfBlock, black);
274
} else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) {
276
if (params->isDict()) {
277
if (params->dictLookup("ColorTransform", &obj)->isInt()) {
278
colorXform = obj.getInt();
282
str = new DCTStream(str, colorXform);
283
} else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) {
288
if (params->isDict()) {
289
params->dictLookup("Predictor", &obj);
293
params->dictLookup("Columns", &obj);
295
columns = obj.getInt();
297
params->dictLookup("Colors", &obj);
299
colors = obj.getInt();
301
params->dictLookup("BitsPerComponent", &obj);
306
str = new FlateStream(str, pred, columns, colors, bits);
307
} else if (!strcmp(name, "JBIG2Decode")) {
308
if (params->isDict()) {
309
params->dictLookup("JBIG2Globals", &globals);
311
str = new JBIG2Stream(str, &globals);
313
} else if (!strcmp(name, "JPXDecode")) {
314
str = new JPXStream(str);
316
error(getPos(), "Unknown filter '%s'", name);
317
str = new EOFStream(str);
322
//------------------------------------------------------------------------
324
//------------------------------------------------------------------------
325
OutStream::OutStream ()
330
OutStream::~OutStream ()
334
//------------------------------------------------------------------------
336
//------------------------------------------------------------------------
337
FileOutStream::FileOutStream (FILE* fa, Guint startA)
343
FileOutStream::~FileOutStream ()
348
void FileOutStream::close ()
353
int FileOutStream::getPos ()
358
void FileOutStream::put (char c)
363
void FileOutStream::printf(const char *format, ...)
366
va_start (argptr, format);
367
vfprintf(f, format, argptr);
372
//------------------------------------------------------------------------
374
//------------------------------------------------------------------------
376
BaseStream::BaseStream(Object *dictA, Guint lengthA) {
381
BaseStream::~BaseStream() {
385
//------------------------------------------------------------------------
387
//------------------------------------------------------------------------
389
FilterStream::FilterStream(Stream *strA) {
393
FilterStream::~FilterStream() {
396
void FilterStream::close() {
400
void FilterStream::setPos(Guint pos, int dir) {
401
error(-1, "Internal: called setPos() on FilterStream");
404
//------------------------------------------------------------------------
406
//------------------------------------------------------------------------
408
ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) {
416
nVals = width * nComps;
418
imgLineSize = (nVals + 7) & ~7;
422
if (width > INT_MAX / nComps) {
423
// force a call to gmallocn(-1,...), which will throw an exception
426
imgLine = (Guchar *)gmallocn(imgLineSize, sizeof(Guchar));
430
ImageStream::~ImageStream() {
434
void ImageStream::reset() {
438
void ImageStream::close() {
442
GBool ImageStream::getPixel(Guchar *pix) {
445
if (imgIdx >= nVals) {
449
for (i = 0; i < nComps; ++i) {
450
pix[i] = imgLine[imgIdx++];
455
Guchar *ImageStream::getLine() {
462
for (i = 0; i < nVals; i += 8) {
464
imgLine[i+0] = (Guchar)((c >> 7) & 1);
465
imgLine[i+1] = (Guchar)((c >> 6) & 1);
466
imgLine[i+2] = (Guchar)((c >> 5) & 1);
467
imgLine[i+3] = (Guchar)((c >> 4) & 1);
468
imgLine[i+4] = (Guchar)((c >> 3) & 1);
469
imgLine[i+5] = (Guchar)((c >> 2) & 1);
470
imgLine[i+6] = (Guchar)((c >> 1) & 1);
471
imgLine[i+7] = (Guchar)(c & 1);
473
} else if (nBits == 8) {
474
Guchar *line = imgLine;
475
int readChars = str->doGetChars(nVals, line);
476
for ( ; readChars < nVals; readChars++) line[readChars] = EOF;
477
} else if (nBits == 16) {
478
// this is a hack to support 16 bits images, everywhere
479
// we assume a component fits in 8 bits, with this hack
480
// we treat 16 bit images as 8 bit ones until it's fixed correctly.
481
// The hack has another part on GfxImageColorMap::GfxImageColorMap
482
for (i = 0; i < nVals; ++i) {
483
imgLine[i] = str->getChar();
487
bitMask = (1 << nBits) - 1;
490
for (i = 0; i < nVals; ++i) {
492
buf = (buf << 8) | (str->getChar() & 0xff);
495
imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask);
502
void ImageStream::skipLine() {
505
n = (nVals * nBits + 7) >> 3;
506
for (i = 0; i < n; ++i) {
511
//------------------------------------------------------------------------
513
//------------------------------------------------------------------------
515
StreamPredictor::StreamPredictor(Stream *strA, int predictorA,
516
int widthA, int nCompsA, int nBitsA) {
518
predictor = predictorA;
525
nVals = width * nComps;
526
pixBytes = (nComps * nBits + 7) >> 3;
527
rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
528
if (width <= 0 || nComps <= 0 || nBits <= 0 ||
529
nComps > gfxColorMaxComps ||
531
width >= INT_MAX / nComps || // check for overflow in nVals
532
nVals >= (INT_MAX - 7) / nBits) { // check for overflow in rowBytes
535
predLine = (Guchar *)gmalloc(rowBytes);
536
memset(predLine, 0, rowBytes);
542
StreamPredictor::~StreamPredictor() {
546
int StreamPredictor::lookChar() {
547
if (predIdx >= rowBytes) {
548
if (!getNextLine()) {
552
return predLine[predIdx];
555
int StreamPredictor::getChar() {
559
int StreamPredictor::getChars(int nChars, Guchar *buffer)
561
for (int i = 0; i < nChars; ++i) {
562
const int c = doGetChar();
563
if (likely(c != EOF)) buffer[i] = c;
569
GBool StreamPredictor::getNextLine() {
571
Guchar upLeftBuf[gfxColorMaxComps * 2 + 1];
572
int left, up, upLeft, p, pa, pb, pc;
574
Gulong inBuf, outBuf, bitMask;
578
// get PNG optimum predictor number
579
if (predictor >= 10) {
580
if ((curPred = str->getRawChar()) == EOF) {
588
// read the raw line, apply PNG (byte) predictor
589
int *rawCharLine = new int[rowBytes - pixBytes];
590
str->getRawChars(rowBytes - pixBytes, rawCharLine);
591
memset(upLeftBuf, 0, pixBytes + 1);
592
for (i = pixBytes; i < rowBytes; ++i) {
593
for (j = pixBytes; j > 0; --j) {
594
upLeftBuf[j] = upLeftBuf[j-1];
596
upLeftBuf[0] = predLine[i];
597
if ((c = rawCharLine[i - pixBytes]) == EOF) {
599
// this ought to return false, but some (broken) PDF files
600
// contain truncated image data, and Adobe apparently reads the
604
delete[] rawCharLine;
609
predLine[i] = predLine[i - pixBytes] + (Guchar)c;
612
predLine[i] = predLine[i] + (Guchar)c;
614
case 13: // PNG average
615
predLine[i] = ((predLine[i - pixBytes] + predLine[i]) >> 1) +
618
case 14: // PNG Paeth
619
left = predLine[i - pixBytes];
621
upLeft = upLeftBuf[pixBytes];
622
p = left + up - upLeft;
623
if ((pa = p - left) < 0)
625
if ((pb = p - up) < 0)
627
if ((pc = p - upLeft) < 0)
629
if (pa <= pb && pa <= pc)
630
predLine[i] = left + (Guchar)c;
632
predLine[i] = up + (Guchar)c;
634
predLine[i] = upLeft + (Guchar)c;
637
default: // no predictor or TIFF predictor
638
predLine[i] = (Guchar)c;
642
delete[] rawCharLine;
644
// apply TIFF (component) predictor
645
if (predictor == 2) {
647
inBuf = predLine[pixBytes - 1];
648
for (i = pixBytes; i < rowBytes; i += 8) {
649
// 1-bit add is just xor
650
inBuf = (inBuf << 8) | predLine[i];
651
predLine[i] ^= inBuf >> nComps;
653
} else if (nBits == 8) {
654
for (i = pixBytes; i < rowBytes; ++i) {
655
predLine[i] += predLine[i - nComps];
658
memset(upLeftBuf, 0, nComps + 1);
659
bitMask = (1 << nBits) - 1;
661
inBits = outBits = 0;
663
for (i = 0; i < width; ++i) {
664
for (kk = 0; kk < nComps; ++kk) {
665
if (inBits < nBits) {
666
inBuf = (inBuf << 8) | (predLine[j++] & 0xff);
669
upLeftBuf[kk] = (Guchar)((upLeftBuf[kk] +
670
(inBuf >> (inBits - nBits))) & bitMask);
672
outBuf = (outBuf << nBits) | upLeftBuf[kk];
675
predLine[k++] = (Guchar)(outBuf >> (outBits - 8));
681
predLine[k++] = (Guchar)((outBuf << (8 - outBits)) +
682
(inBuf & ((1 << (8 - outBits)) - 1)));
687
// reset to start of line
693
//------------------------------------------------------------------------
695
//------------------------------------------------------------------------
697
FileStream::FileStream(FILE *fA, Guint startA, GBool limitedA,
698
Guint lengthA, Object *dictA):
699
BaseStream(dictA, lengthA) {
704
bufPtr = bufEnd = buf;
710
FileStream::~FileStream() {
714
Stream *FileStream::makeSubStream(Guint startA, GBool limitedA,
715
Guint lengthA, Object *dictA) {
716
return new FileStream(f, startA, limitedA, lengthA, dictA);
719
void FileStream::reset() {
721
savePos = (Guint)ftello(f);
722
fseeko(f, start, SEEK_SET);
724
savePos = (Guint)ftell64(f);
725
fseek64(f, start, SEEK_SET);
727
savePos = (Guint)ftell(f);
728
fseek(f, start, SEEK_SET);
731
bufPtr = bufEnd = buf;
735
void FileStream::close() {
738
fseeko(f, savePos, SEEK_SET);
740
fseek64(f, savePos, SEEK_SET);
742
fseek(f, savePos, SEEK_SET);
748
GBool FileStream::fillBuf() {
751
bufPos += bufEnd - buf;
752
bufPtr = bufEnd = buf;
753
if (limited && bufPos >= start + length) {
756
if (limited && bufPos + fileStreamBufSize > start + length) {
757
n = start + length - bufPos;
759
n = fileStreamBufSize;
761
n = fread(buf, 1, n, f);
763
if (bufPtr >= bufEnd) {
769
void FileStream::setPos(Guint pos, int dir) {
774
fseeko(f, pos, SEEK_SET);
776
fseek64(f, pos, SEEK_SET);
778
fseek(f, pos, SEEK_SET);
783
fseeko(f, 0, SEEK_END);
784
size = (Guint)ftello(f);
786
fseek64(f, 0, SEEK_END);
787
size = (Guint)ftell64(f);
789
fseek(f, 0, SEEK_END);
790
size = (Guint)ftell(f);
795
//~ work around a bug in cygwin's implementation of fseek
799
fseeko(f, -(int)pos, SEEK_END);
800
bufPos = (Guint)ftello(f);
802
fseek64(f, -(int)pos, SEEK_END);
803
bufPos = (Guint)ftell64(f);
805
fseek(f, -(int)pos, SEEK_END);
806
bufPos = (Guint)ftell(f);
809
bufPtr = bufEnd = buf;
812
void FileStream::moveStart(int delta) {
814
bufPtr = bufEnd = buf;
818
//------------------------------------------------------------------------
820
//------------------------------------------------------------------------
822
CachedFileStream::CachedFileStream(CachedFile *ccA, Guint startA,
823
GBool limitedA, Guint lengthA, Object *dictA)
824
: BaseStream(dictA, lengthA)
830
bufPtr = bufEnd = buf;
836
CachedFileStream::~CachedFileStream()
842
Stream *CachedFileStream::makeSubStream(Guint startA, GBool limitedA,
843
Guint lengthA, Object *dictA)
846
return new CachedFileStream(cc, startA, limitedA, lengthA, dictA);
849
void CachedFileStream::reset()
851
savePos = (Guint)cc->tell();
852
cc->seek(start, SEEK_SET);
855
bufPtr = bufEnd = buf;
859
void CachedFileStream::close()
862
cc->seek(savePos, SEEK_SET);
867
GBool CachedFileStream::fillBuf()
871
bufPos += bufEnd - buf;
872
bufPtr = bufEnd = buf;
873
if (limited && bufPos >= start + length) {
876
if (limited && bufPos + cachedStreamBufSize > start + length) {
877
n = start + length - bufPos;
879
n = cachedStreamBufSize - (bufPos % cachedStreamBufSize);
883
if (bufPtr >= bufEnd) {
889
void CachedFileStream::setPos(Guint pos, int dir)
894
cc->seek(pos, SEEK_SET);
897
cc->seek(0, SEEK_END);
898
size = (Guint)cc->tell();
903
cc->seek(-(int)pos, SEEK_END);
904
bufPos = (Guint)cc->tell();
907
bufPtr = bufEnd = buf;
910
void CachedFileStream::moveStart(int delta)
913
bufPtr = bufEnd = buf;
917
//------------------------------------------------------------------------
919
//------------------------------------------------------------------------
921
MemStream::MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA):
922
BaseStream(dictA, lengthA) {
926
bufEnd = buf + start + length;
927
bufPtr = buf + start;
931
MemStream::~MemStream() {
937
Stream *MemStream::makeSubStream(Guint startA, GBool limited,
938
Guint lengthA, Object *dictA) {
942
if (!limited || startA + lengthA > start + length) {
943
newLength = start + length - startA;
947
subStr = new MemStream(buf, startA, newLength, dictA);
951
void MemStream::reset() {
952
bufPtr = buf + start;
955
void MemStream::close() {
958
void MemStream::setPos(Guint pos, int dir) {
964
i = start + length - pos;
968
} else if (i > start + length) {
974
void MemStream::moveStart(int delta) {
977
bufPtr = buf + start;
980
//------------------------------------------------------------------------
982
//------------------------------------------------------------------------
984
EmbedStream::EmbedStream(Stream *strA, Object *dictA,
985
GBool limitedA, Guint lengthA):
986
BaseStream(dictA, lengthA) {
992
EmbedStream::~EmbedStream() {
995
Stream *EmbedStream::makeSubStream(Guint start, GBool limitedA,
996
Guint lengthA, Object *dictA) {
997
error(-1, "Internal: called makeSubStream() on EmbedStream");
1001
int EmbedStream::getChar() {
1002
if (limited && !length) {
1006
return str->getChar();
1009
int EmbedStream::lookChar() {
1010
if (limited && !length) {
1013
return str->lookChar();
1016
void EmbedStream::setPos(Guint pos, int dir) {
1017
error(-1, "Internal: called setPos() on EmbedStream");
1020
Guint EmbedStream::getStart() {
1021
error(-1, "Internal: called getStart() on EmbedStream");
1025
void EmbedStream::moveStart(int delta) {
1026
error(-1, "Internal: called moveStart() on EmbedStream");
1029
//------------------------------------------------------------------------
1031
//------------------------------------------------------------------------
1033
ASCIIHexStream::ASCIIHexStream(Stream *strA):
1034
FilterStream(strA) {
1039
ASCIIHexStream::~ASCIIHexStream() {
1043
void ASCIIHexStream::reset() {
1049
int ASCIIHexStream::lookChar() {
1059
c1 = str->getChar();
1060
} while (isspace(c1));
1067
c2 = str->getChar();
1068
} while (isspace(c2));
1073
if (c1 >= '0' && c1 <= '9') {
1074
x = (c1 - '0') << 4;
1075
} else if (c1 >= 'A' && c1 <= 'F') {
1076
x = (c1 - 'A' + 10) << 4;
1077
} else if (c1 >= 'a' && c1 <= 'f') {
1078
x = (c1 - 'a' + 10) << 4;
1079
} else if (c1 == EOF) {
1083
error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c1);
1086
if (c2 >= '0' && c2 <= '9') {
1088
} else if (c2 >= 'A' && c2 <= 'F') {
1090
} else if (c2 >= 'a' && c2 <= 'f') {
1092
} else if (c2 == EOF) {
1096
error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c2);
1102
GooString *ASCIIHexStream::getPSFilter(int psLevel, char *indent) {
1108
if (!(s = str->getPSFilter(psLevel, indent))) {
1111
s->append(indent)->append("/ASCIIHexDecode filter\n");
1115
GBool ASCIIHexStream::isBinary(GBool last) {
1116
return str->isBinary(gFalse);
1119
//------------------------------------------------------------------------
1121
//------------------------------------------------------------------------
1123
ASCII85Stream::ASCII85Stream(Stream *strA):
1124
FilterStream(strA) {
1129
ASCII85Stream::~ASCII85Stream() {
1133
void ASCII85Stream::reset() {
1139
int ASCII85Stream::lookChar() {
1148
c[0] = str->getChar();
1149
} while (Lexer::isSpace(c[0]));
1150
if (c[0] == '~' || c[0] == EOF) {
1154
} else if (c[0] == 'z') {
1155
b[0] = b[1] = b[2] = b[3] = 0;
1158
for (k = 1; k < 5; ++k) {
1160
c[k] = str->getChar();
1161
} while (Lexer::isSpace(c[k]));
1162
if (c[k] == '~' || c[k] == EOF)
1166
if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
1167
for (++k; k < 5; ++k)
1172
for (k = 0; k < 5; ++k)
1173
t = t * 85 + (c[k] - 0x21);
1174
for (k = 3; k >= 0; --k) {
1175
b[k] = (int)(t & 0xff);
1183
GooString *ASCII85Stream::getPSFilter(int psLevel, char *indent) {
1189
if (!(s = str->getPSFilter(psLevel, indent))) {
1192
s->append(indent)->append("/ASCII85Decode filter\n");
1196
GBool ASCII85Stream::isBinary(GBool last) {
1197
return str->isBinary(gFalse);
1200
//------------------------------------------------------------------------
1202
//------------------------------------------------------------------------
1204
LZWStream::LZWStream(Stream *strA, int predictor, int columns, int colors,
1205
int bits, int earlyA):
1206
FilterStream(strA) {
1207
if (predictor != 1) {
1208
pred = new StreamPredictor(this, predictor, columns, colors, bits);
1209
if (!pred->isOk()) {
1222
LZWStream::~LZWStream() {
1229
int LZWStream::getChar() {
1231
return pred->getChar();
1236
if (seqIndex >= seqLength) {
1237
if (!processNextCode()) {
1241
return seqBuf[seqIndex++];
1244
int LZWStream::lookChar() {
1246
return pred->lookChar();
1251
if (seqIndex >= seqLength) {
1252
if (!processNextCode()) {
1256
return seqBuf[seqIndex];
1259
void LZWStream::getRawChars(int nChars, int *buffer) {
1260
for (int i = 0; i < nChars; ++i)
1261
buffer[i] = doGetRawChar();
1264
int LZWStream::getRawChar() {
1265
return doGetRawChar();
1268
void LZWStream::reset() {
1275
GBool LZWStream::processNextCode() {
1285
// check for eod and clear-table codes
1288
if (code == EOF || code == 257) {
1296
if (nextCode >= 4097) {
1297
error(getPos(), "Bad LZW stream - expected clear-table code");
1301
// process the next code
1302
nextLength = seqLength + 1;
1306
} else if (code < nextCode) {
1307
seqLength = table[code].length;
1308
for (i = seqLength - 1, j = code; i > 0; --i) {
1309
seqBuf[i] = table[j].tail;
1313
} else if (code == nextCode) {
1314
seqBuf[seqLength] = newChar;
1317
error(getPos(), "Bad LZW stream - unexpected code");
1321
newChar = seqBuf[0];
1325
table[nextCode].length = nextLength;
1326
table[nextCode].head = prevCode;
1327
table[nextCode].tail = newChar;
1329
if (nextCode + early == 512)
1331
else if (nextCode + early == 1024)
1333
else if (nextCode + early == 2048)
1344
void LZWStream::clearTable() {
1347
seqIndex = seqLength = 0;
1351
int LZWStream::getCode() {
1355
while (inputBits < nextBits) {
1356
if ((c = str->getChar()) == EOF)
1358
inputBuf = (inputBuf << 8) | (c & 0xff);
1361
code = (inputBuf >> (inputBits - nextBits)) & ((1 << nextBits) - 1);
1362
inputBits -= nextBits;
1366
GooString *LZWStream::getPSFilter(int psLevel, char *indent) {
1369
if (psLevel < 2 || pred) {
1372
if (!(s = str->getPSFilter(psLevel, indent))) {
1375
s->append(indent)->append("<< ");
1377
s->append("/EarlyChange 0 ");
1379
s->append(">> /LZWDecode filter\n");
1383
GBool LZWStream::isBinary(GBool last) {
1384
return str->isBinary(gTrue);
1387
//------------------------------------------------------------------------
1389
//------------------------------------------------------------------------
1391
RunLengthStream::RunLengthStream(Stream *strA):
1392
FilterStream(strA) {
1393
bufPtr = bufEnd = buf;
1397
RunLengthStream::~RunLengthStream() {
1401
void RunLengthStream::reset() {
1403
bufPtr = bufEnd = buf;
1407
GooString *RunLengthStream::getPSFilter(int psLevel, char *indent) {
1413
if (!(s = str->getPSFilter(psLevel, indent))) {
1416
s->append(indent)->append("/RunLengthDecode filter\n");
1420
GBool RunLengthStream::isBinary(GBool last) {
1421
return str->isBinary(gTrue);
1424
GBool RunLengthStream::fillBuf() {
1431
if (c == 0x80 || c == EOF) {
1437
for (i = 0; i < n; ++i)
1438
buf[i] = (char)str->getChar();
1442
for (i = 0; i < n; ++i)
1450
//------------------------------------------------------------------------
1452
//------------------------------------------------------------------------
1454
CCITTFaxStream::CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
1455
GBool byteAlignA, int columnsA, int rowsA,
1456
GBool endOfBlockA, GBool blackA):
1457
FilterStream(strA) {
1458
encoding = encodingA;
1459
endOfLine = endOfLineA;
1460
byteAlign = byteAlignA;
1464
} else if (columns > INT_MAX - 2) {
1465
columns = INT_MAX - 2;
1468
endOfBlock = endOfBlockA;
1470
// 0 <= codingLine[0] < codingLine[1] < ... < codingLine[n] = columns
1471
// ---> max codingLine size = columns + 1
1472
// refLine has one extra guard entry at the end
1473
// ---> max refLine size = columns + 2
1474
codingLine = (int *)gmallocn_checkoverflow(columns + 1, sizeof(int));
1475
refLine = (int *)gmallocn_checkoverflow(columns + 2, sizeof(int));
1477
if (codingLine != NULL && refLine != NULL) {
1479
codingLine[0] = columns;
1484
nextLine2D = encoding < 0;
1492
CCITTFaxStream::~CCITTFaxStream() {
1498
void CCITTFaxStream::unfilteredReset () {
1502
nextLine2D = encoding < 0;
1509
void CCITTFaxStream::reset() {
1514
if (codingLine != NULL && refLine != NULL) {
1516
codingLine[0] = columns;
1521
// skip any initial zero bits and end-of-line marker, and get the 2D
1523
while ((code1 = lookBits(12)) == 0) {
1526
if (code1 == 0x001) {
1530
nextLine2D = !lookBits(1);
1535
inline void CCITTFaxStream::addPixels(int a1, int blackPixels) {
1536
if (a1 > codingLine[a0i]) {
1538
error(getPos(), "CCITTFax row is wrong length (%d)", a1);
1542
if ((a0i & 1) ^ blackPixels) {
1545
codingLine[a0i] = a1;
1549
inline void CCITTFaxStream::addPixelsNeg(int a1, int blackPixels) {
1550
if (a1 > codingLine[a0i]) {
1552
error(getPos(), "CCITTFax row is wrong length (%d)", a1);
1556
if ((a0i & 1) ^ blackPixels) {
1559
codingLine[a0i] = a1;
1560
} else if (a1 < codingLine[a0i]) {
1562
error(getPos(), "Invalid CCITTFax code");
1566
while (a0i > 0 && a1 <= codingLine[a0i - 1]) {
1569
codingLine[a0i] = a1;
1573
int CCITTFaxStream::lookChar() {
1574
short code1, code2, code3;
1575
int b1i, blackPixels, i, bits;
1582
// read the next row
1583
if (outputBits == 0) {
1585
// if at eof just return EOF
1594
for (i = 0; codingLine[i] < columns; ++i) {
1595
refLine[i] = codingLine[i];
1597
refLine[i++] = columns;
1598
refLine[i] = columns;
1604
// refLine[b1i-1] <= codingLine[a0i] < refLine[b1i] < refLine[b1i+1]
1606
// exception at left edge:
1607
// codingLine[a0i = 0] = refLine[b1i = 0] = 0 is possible
1608
// exception at right edge:
1609
// refLine[b1i] = refLine[b1i+1] = columns is possible
1610
while (codingLine[a0i] < columns) {
1611
code1 = getTwoDimCode();
1614
addPixels(refLine[b1i + 1], blackPixels);
1615
if (refLine[b1i + 1] < columns) {
1623
code1 += code3 = getBlackCode();
1624
} while (code3 >= 64);
1626
code2 += code3 = getWhiteCode();
1627
} while (code3 >= 64);
1630
code1 += code3 = getWhiteCode();
1631
} while (code3 >= 64);
1633
code2 += code3 = getBlackCode();
1634
} while (code3 >= 64);
1636
addPixels(codingLine[a0i] + code1, blackPixels);
1637
if (codingLine[a0i] < columns) {
1638
addPixels(codingLine[a0i] + code2, blackPixels ^ 1);
1640
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1645
addPixels(refLine[b1i] + 3, blackPixels);
1647
if (codingLine[a0i] < columns) {
1649
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1655
addPixels(refLine[b1i] + 2, blackPixels);
1657
if (codingLine[a0i] < columns) {
1659
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1665
addPixels(refLine[b1i] + 1, blackPixels);
1667
if (codingLine[a0i] < columns) {
1669
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1675
addPixels(refLine[b1i], blackPixels);
1677
if (codingLine[a0i] < columns) {
1679
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1685
addPixelsNeg(refLine[b1i] - 3, blackPixels);
1687
if (codingLine[a0i] < columns) {
1693
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1699
addPixelsNeg(refLine[b1i] - 2, blackPixels);
1701
if (codingLine[a0i] < columns) {
1707
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1713
addPixelsNeg(refLine[b1i] - 1, blackPixels);
1715
if (codingLine[a0i] < columns) {
1721
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1727
addPixels(columns, 0);
1731
error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1);
1732
addPixels(columns, 0);
1743
while (codingLine[a0i] < columns) {
1747
code1 += code3 = getBlackCode();
1748
} while (code3 >= 64);
1751
code1 += code3 = getWhiteCode();
1752
} while (code3 >= 64);
1754
addPixels(codingLine[a0i] + code1, blackPixels);
1759
// byte-align the row
1764
// check for end-of-line marker, skipping over any extra zero bits
1766
if (!endOfBlock && row == rows - 1) {
1769
code1 = lookBits(12);
1770
while (code1 == 0) {
1772
code1 = lookBits(12);
1774
if (code1 == 0x001) {
1777
} else if (code1 == EOF) {
1782
// get 2D encoding tag
1783
if (!eof && encoding > 0) {
1784
nextLine2D = !lookBits(1);
1788
// check for end-of-block marker
1789
if (endOfBlock && gotEOL) {
1790
code1 = lookBits(12);
1791
if (code1 == 0x001) {
1797
if (encoding >= 0) {
1798
for (i = 0; i < 4; ++i) {
1799
code1 = lookBits(12);
1800
if (code1 != 0x001) {
1801
error(getPos(), "Bad RTC code in CCITTFax stream");
1813
// look for an end-of-line marker after an error -- we only do
1814
// this if we know the stream contains end-of-line markers because
1815
// the "just plow on" technique tends to work better otherwise
1816
} else if (err && endOfLine) {
1818
code1 = lookBits(13);
1823
if ((code1 >> 1) == 0x001) {
1831
nextLine2D = !(code1 & 1);
1835
// set up for output
1836
if (codingLine[0] > 0) {
1837
outputBits = codingLine[a0i = 0];
1839
outputBits = codingLine[a0i = 1];
1846
if (outputBits >= 8) {
1847
buf = (a0i & 1) ? 0x00 : 0xff;
1849
if (outputBits == 0 && codingLine[a0i] < columns) {
1851
outputBits = codingLine[a0i] - codingLine[a0i - 1];
1857
if (outputBits > bits) {
1860
buf |= 0xff >> (8 - bits);
1867
buf |= 0xff >> (8 - outputBits);
1871
if (codingLine[a0i] < columns) {
1873
outputBits = codingLine[a0i] - codingLine[a0i - 1];
1874
} else if (bits > 0) {
1887
short CCITTFaxStream::getTwoDimCode() {
1892
code = 0; // make gcc happy
1895
p = &twoDimTab1[code];
1901
for (n = 1; n <= 7; ++n) {
1906
p = &twoDimTab1[code];
1913
error(getPos(), "Bad two dim code (%04x) in CCITTFax stream", code);
1917
short CCITTFaxStream::getWhiteCode() {
1922
code = 0; // make gcc happy
1924
code = lookBits(12);
1928
if ((code >> 5) == 0) {
1929
p = &whiteTab1[code];
1931
p = &whiteTab2[code >> 3];
1938
for (n = 1; n <= 9; ++n) {
1946
p = &whiteTab2[code];
1952
for (n = 11; n <= 12; ++n) {
1960
p = &whiteTab1[code];
1967
error(getPos(), "Bad white code (%04x) in CCITTFax stream", code);
1968
// eat a bit and return a positive number so that the caller doesn't
1969
// go into an infinite loop
1974
short CCITTFaxStream::getBlackCode() {
1979
code = 0; // make gcc happy
1981
code = lookBits(13);
1985
if ((code >> 7) == 0) {
1986
p = &blackTab1[code];
1987
} else if ((code >> 9) == 0 && (code >> 7) != 0) {
1988
p = &blackTab2[(code >> 1) - 64];
1990
p = &blackTab3[code >> 7];
1997
for (n = 2; n <= 6; ++n) {
2005
p = &blackTab3[code];
2011
for (n = 7; n <= 12; ++n) {
2020
p = &blackTab2[code - 64];
2027
for (n = 10; n <= 13; ++n) {
2035
p = &blackTab1[code];
2042
error(getPos(), "Bad black code (%04x) in CCITTFax stream", code);
2043
// eat a bit and return a positive number so that the caller doesn't
2044
// go into an infinite loop
2049
short CCITTFaxStream::lookBits(int n) {
2052
while (inputBits < n) {
2053
if ((c = str->getChar()) == EOF) {
2054
if (inputBits == 0) {
2057
// near the end of the stream, the caller may ask for more bits
2058
// than are available, but there may still be a valid code in
2059
// however many bits are available -- we need to return correct
2060
// data in this case
2061
return (inputBuf << (n - inputBits)) & (0xffff >> (16 - n));
2063
inputBuf = (inputBuf << 8) + c;
2066
return (inputBuf >> (inputBits - n)) & (0xffff >> (16 - n));
2069
GooString *CCITTFaxStream::getPSFilter(int psLevel, char *indent) {
2076
if (!(s = str->getPSFilter(psLevel, indent))) {
2079
s->append(indent)->append("<< ");
2080
if (encoding != 0) {
2081
sprintf(s1, "/K %d ", encoding);
2085
s->append("/EndOfLine true ");
2088
s->append("/EncodedByteAlign true ");
2090
sprintf(s1, "/Columns %d ", columns);
2093
sprintf(s1, "/Rows %d ", rows);
2097
s->append("/EndOfBlock false ");
2100
s->append("/BlackIs1 true ");
2102
s->append(">> /CCITTFaxDecode filter\n");
2106
GBool CCITTFaxStream::isBinary(GBool last) {
2107
return str->isBinary(gTrue);
2110
#ifndef ENABLE_LIBJPEG
2112
//------------------------------------------------------------------------
2114
//------------------------------------------------------------------------
2116
// IDCT constants (20.12 fixed point format)
2117
#define dctCos1 4017 // cos(pi/16)
2118
#define dctSin1 799 // sin(pi/16)
2119
#define dctCos3 3406 // cos(3*pi/16)
2120
#define dctSin3 2276 // sin(3*pi/16)
2121
#define dctCos6 1567 // cos(6*pi/16)
2122
#define dctSin6 3784 // sin(6*pi/16)
2123
#define dctSqrt2 5793 // sqrt(2)
2124
#define dctSqrt1d2 2896 // sqrt(2) / 2
2126
// color conversion parameters (16.16 fixed point format)
2127
#define dctCrToR 91881 // 1.4020
2128
#define dctCbToG -22553 // -0.3441363
2129
#define dctCrToG -46802 // -0.71413636
2130
#define dctCbToB 116130 // 1.772
2132
// clip [-256,511] --> [0,255]
2133
#define dctClipOffset 256
2134
static Guchar dctClip[768];
2135
static int dctClipInit = 0;
2137
// zig zag decode map
2138
static const int dctZigZag[64] = {
2144
5, 12, 19, 26, 33, 40,
2145
48, 41, 34, 27, 20, 13, 6,
2146
7, 14, 21, 28, 35, 42, 49, 56,
2147
57, 50, 43, 36, 29, 22, 15,
2148
23, 30, 37, 44, 51, 58,
2156
DCTStream::DCTStream(Stream *strA, int colorXformA):
2157
FilterStream(strA) {
2160
colorXform = colorXformA;
2161
progressive = interleaved = gFalse;
2163
mcuWidth = mcuHeight = 0;
2167
for (i = 0; i < 4; ++i) {
2168
for (j = 0; j < 32; ++j) {
2169
rowBuf[i][j] = NULL;
2175
for (i = -256; i < 0; ++i)
2176
dctClip[dctClipOffset + i] = 0;
2177
for (i = 0; i < 256; ++i)
2178
dctClip[dctClipOffset + i] = i;
2179
for (i = 256; i < 512; ++i)
2180
dctClip[dctClipOffset + i] = 255;
2185
DCTStream::~DCTStream() {
2190
void DCTStream::unfilteredReset() {
2193
progressive = interleaved = gFalse;
2197
numDCHuffTables = 0;
2198
numACHuffTables = 0;
2199
gotJFIFMarker = gFalse;
2200
gotAdobeMarker = gFalse;
2201
restartInterval = 0;
2205
void DCTStream::reset() {
2210
if (!readHeader()) {
2216
if (numComps == 1) {
2217
compInfo[0].hSample = compInfo[0].vSample = 1;
2219
mcuWidth = compInfo[0].hSample;
2220
mcuHeight = compInfo[0].vSample;
2221
for (i = 1; i < numComps; ++i) {
2222
if (compInfo[i].hSample > mcuWidth) {
2223
mcuWidth = compInfo[i].hSample;
2225
if (compInfo[i].vSample > mcuHeight) {
2226
mcuHeight = compInfo[i].vSample;
2232
// figure out color transform
2233
if (colorXform == -1) {
2234
if (numComps == 3) {
2235
if (gotJFIFMarker) {
2237
} else if (compInfo[0].id == 82 && compInfo[1].id == 71 &&
2238
compInfo[2].id == 66) { // ASCII "RGB"
2248
if (progressive || !interleaved) {
2250
// allocate a buffer for the whole image
2251
bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2252
bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight;
2253
if (bufWidth <= 0 || bufHeight <= 0 ||
2254
bufWidth > INT_MAX / bufWidth / (int)sizeof(int)) {
2255
error(getPos(), "Invalid image size in DCT stream");
2259
for (i = 0; i < numComps; ++i) {
2260
frameBuf[i] = (int *)gmallocn(bufWidth * bufHeight, sizeof(int));
2261
memset(frameBuf[i], 0, bufWidth * bufHeight * sizeof(int));
2264
// read the image data
2266
restartMarker = 0xd0;
2269
} while (readHeader());
2274
// initialize counters
2281
// allocate a buffer for one row of MCUs
2282
bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2283
for (i = 0; i < numComps; ++i) {
2284
for (j = 0; j < mcuHeight; ++j) {
2285
rowBuf[i][j] = (Guchar *)gmallocn(bufWidth, sizeof(Guchar));
2289
// initialize counters
2295
restartMarker = 0xd0;
2300
void DCTStream::close() {
2303
for (i = 0; i < 4; ++i) {
2304
for (j = 0; j < 32; ++j) {
2305
gfree(rowBuf[i][j]);
2306
rowBuf[i][j] = NULL;
2311
FilterStream::close();
2314
int DCTStream::getChar() {
2320
if (progressive || !interleaved) {
2321
c = frameBuf[comp][y * bufWidth + x];
2322
if (++comp == numComps) {
2330
if (dy >= mcuHeight) {
2331
if (!readMCURow()) {
2339
c = rowBuf[comp][dy][x];
2340
if (++comp == numComps) {
2355
int DCTStream::lookChar() {
2359
if (progressive || !interleaved) {
2360
return frameBuf[comp][y * bufWidth + x];
2362
if (dy >= mcuHeight) {
2363
if (!readMCURow()) {
2371
return rowBuf[comp][dy][x];
2375
void DCTStream::restart() {
2379
restartCtr = restartInterval;
2380
for (i = 0; i < numComps; ++i) {
2381
compInfo[i].prevDC = 0;
2386
// Read one row of MCUs from a sequential JPEG stream.
2387
GBool DCTStream::readMCURow() {
2391
int pY, pCb, pCr, pR, pG, pB;
2392
int h, v, horiz, vert, hSub, vSub;
2393
int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
2396
for (x1 = 0; x1 < width; x1 += mcuWidth) {
2398
// deal with restart marker
2399
if (restartInterval > 0 && restartCtr == 0) {
2401
if (c != restartMarker) {
2402
error(getPos(), "Bad DCT data: incorrect restart marker");
2405
if (++restartMarker == 0xd8)
2406
restartMarker = 0xd0;
2411
for (cc = 0; cc < numComps; ++cc) {
2412
h = compInfo[cc].hSample;
2413
v = compInfo[cc].vSample;
2414
horiz = mcuWidth / h;
2415
vert = mcuHeight / v;
2418
for (y2 = 0; y2 < mcuHeight; y2 += vert) {
2419
for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
2420
if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]],
2421
&acHuffTables[scanInfo.acHuffTable[cc]],
2422
&compInfo[cc].prevDC,
2426
transformDataUnit(quantTables[compInfo[cc].quantTable],
2428
if (hSub == 1 && vSub == 1) {
2429
for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2430
p1 = &rowBuf[cc][y2+y3][x1+x2];
2440
} else if (hSub == 2 && vSub == 2) {
2441
for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
2442
p1 = &rowBuf[cc][y2+y3][x1+x2];
2443
p2 = &rowBuf[cc][y2+y3+1][x1+x2];
2444
p1[0] = p1[1] = p2[0] = p2[1] = data2[i];
2445
p1[2] = p1[3] = p2[2] = p2[3] = data2[i+1];
2446
p1[4] = p1[5] = p2[4] = p2[5] = data2[i+2];
2447
p1[6] = p1[7] = p2[6] = p2[7] = data2[i+3];
2448
p1[8] = p1[9] = p2[8] = p2[9] = data2[i+4];
2449
p1[10] = p1[11] = p2[10] = p2[11] = data2[i+5];
2450
p1[12] = p1[13] = p2[12] = p2[13] = data2[i+6];
2451
p1[14] = p1[15] = p2[14] = p2[15] = data2[i+7];
2455
for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
2456
for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
2457
for (y5 = 0; y5 < vSub; ++y5)
2458
for (x5 = 0; x5 < hSub; ++x5)
2459
rowBuf[cc][y2+y4+y5][x1+x2+x4+x5] = data2[i];
2469
// color space conversion
2471
// convert YCbCr to RGB
2472
if (numComps == 3) {
2473
for (y2 = 0; y2 < mcuHeight; ++y2) {
2474
for (x2 = 0; x2 < mcuWidth; ++x2) {
2475
pY = rowBuf[0][y2][x1+x2];
2476
pCb = rowBuf[1][y2][x1+x2] - 128;
2477
pCr = rowBuf[2][y2][x1+x2] - 128;
2478
pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2479
rowBuf[0][y2][x1+x2] = dctClip[dctClipOffset + pR];
2480
pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
2481
rowBuf[1][y2][x1+x2] = dctClip[dctClipOffset + pG];
2482
pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2483
rowBuf[2][y2][x1+x2] = dctClip[dctClipOffset + pB];
2486
// convert YCbCrK to CMYK (K is passed through unchanged)
2487
} else if (numComps == 4) {
2488
for (y2 = 0; y2 < mcuHeight; ++y2) {
2489
for (x2 = 0; x2 < mcuWidth; ++x2) {
2490
pY = rowBuf[0][y2][x1+x2];
2491
pCb = rowBuf[1][y2][x1+x2] - 128;
2492
pCr = rowBuf[2][y2][x1+x2] - 128;
2493
pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2494
rowBuf[0][y2][x1+x2] = 255 - dctClip[dctClipOffset + pR];
2495
pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
2496
rowBuf[1][y2][x1+x2] = 255 - dctClip[dctClipOffset + pG];
2497
pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2498
rowBuf[2][y2][x1+x2] = 255 - dctClip[dctClipOffset + pB];
2507
// Read one scan from a progressive or non-interleaved JPEG stream.
2508
void DCTStream::readScan() {
2510
int x1, y1, dx1, dy1, x2, y2, y3, cc, i;
2511
int h, v, horiz, vert, vSub;
2515
if (scanInfo.numComps == 1) {
2516
for (cc = 0; cc < numComps; ++cc) {
2517
if (scanInfo.comp[cc]) {
2521
dx1 = mcuWidth / compInfo[cc].hSample;
2522
dy1 = mcuHeight / compInfo[cc].vSample;
2528
for (y1 = 0; y1 < height; y1 += dy1) {
2529
for (x1 = 0; x1 < width; x1 += dx1) {
2531
// deal with restart marker
2532
if (restartInterval > 0 && restartCtr == 0) {
2534
if (c != restartMarker) {
2535
error(getPos(), "Bad DCT data: incorrect restart marker");
2538
if (++restartMarker == 0xd8) {
2539
restartMarker = 0xd0;
2545
for (cc = 0; cc < numComps; ++cc) {
2546
if (!scanInfo.comp[cc]) {
2550
h = compInfo[cc].hSample;
2551
v = compInfo[cc].vSample;
2552
horiz = mcuWidth / h;
2553
vert = mcuHeight / v;
2555
for (y2 = 0; y2 < dy1; y2 += vert) {
2556
for (x2 = 0; x2 < dx1; x2 += horiz) {
2558
// pull out the current values
2559
p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
2560
for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2569
p1 += bufWidth * vSub;
2572
// read one data unit
2574
if (!readProgressiveDataUnit(
2575
&dcHuffTables[scanInfo.dcHuffTable[cc]],
2576
&acHuffTables[scanInfo.acHuffTable[cc]],
2577
&compInfo[cc].prevDC,
2582
if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]],
2583
&acHuffTables[scanInfo.acHuffTable[cc]],
2584
&compInfo[cc].prevDC,
2590
// add the data unit into frameBuf
2591
p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
2592
for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2601
p1 += bufWidth * vSub;
2611
// Read one data unit from a sequential JPEG stream.
2612
GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
2613
DCTHuffTable *acHuffTable,
2614
int *prevDC, int data[64]) {
2619
if ((size = readHuffSym(dcHuffTable)) == 9999) {
2623
if ((amp = readAmp(size)) == 9999) {
2629
data[0] = *prevDC += amp;
2630
for (i = 1; i < 64; ++i) {
2636
while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30) {
2645
run += (c >> 4) & 0x0f;
2647
amp = readAmp(size);
2661
// Read one data unit from a sequential JPEG stream.
2662
GBool DCTStream::readProgressiveDataUnit(DCTHuffTable *dcHuffTable,
2663
DCTHuffTable *acHuffTable,
2664
int *prevDC, int data[64]) {
2665
int run, size, amp, bit, c;
2668
// get the DC coefficient
2669
i = scanInfo.firstCoeff;
2671
if (scanInfo.ah == 0) {
2672
if ((size = readHuffSym(dcHuffTable)) == 9999) {
2676
if ((amp = readAmp(size)) == 9999) {
2682
data[0] += (*prevDC += amp) << scanInfo.al;
2684
if ((bit = readBit()) == 9999) {
2687
data[0] += bit << scanInfo.al;
2691
if (scanInfo.lastCoeff == 0) {
2695
// check for an EOB run
2697
while (i <= scanInfo.lastCoeff) {
2700
if ((bit = readBit()) == EOF) {
2704
data[j] += 1 << scanInfo.al;
2712
// read the AC coefficients
2713
while (i <= scanInfo.lastCoeff) {
2714
if ((c = readHuffSym(acHuffTable)) == 9999) {
2726
if ((bit = readBit()) == EOF) {
2730
data[j] += 1 << scanInfo.al;
2736
} else if ((c & 0x0f) == 0x00) {
2739
for (k = 0; k < j; ++k) {
2740
if ((bit = readBit()) == EOF) {
2743
eobRun = (eobRun << 1) | bit;
2746
while (i <= scanInfo.lastCoeff) {
2749
if ((bit = readBit()) == EOF) {
2753
data[j] += 1 << scanInfo.al;
2760
// zero run and one AC coefficient
2762
run = (c >> 4) & 0x0f;
2764
if ((amp = readAmp(size)) == 9999) {
2770
while (data[j] != 0) {
2771
if ((bit = readBit()) == EOF) {
2775
data[j] += 1 << scanInfo.al;
2781
data[j] = amp << scanInfo.al;
2788
// Decode a progressive JPEG image.
2789
void DCTStream::decodeImage() {
2792
Gushort *quantTable;
2793
int pY, pCb, pCr, pR, pG, pB;
2794
int x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
2795
int h, v, horiz, vert, hSub, vSub;
2798
for (y1 = 0; y1 < bufHeight; y1 += mcuHeight) {
2799
for (x1 = 0; x1 < bufWidth; x1 += mcuWidth) {
2800
for (cc = 0; cc < numComps; ++cc) {
2801
quantTable = quantTables[compInfo[cc].quantTable];
2802
h = compInfo[cc].hSample;
2803
v = compInfo[cc].vSample;
2804
horiz = mcuWidth / h;
2805
vert = mcuHeight / v;
2808
for (y2 = 0; y2 < mcuHeight; y2 += vert) {
2809
for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
2811
// pull out the coded data unit
2812
p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
2813
for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2815
dataIn[i+1] = p1[1];
2816
dataIn[i+2] = p1[2];
2817
dataIn[i+3] = p1[3];
2818
dataIn[i+4] = p1[4];
2819
dataIn[i+5] = p1[5];
2820
dataIn[i+6] = p1[6];
2821
dataIn[i+7] = p1[7];
2822
p1 += bufWidth * vSub;
2826
transformDataUnit(quantTable, dataIn, dataOut);
2828
// store back into frameBuf, doing replication for
2829
// subsampled components
2830
p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
2831
if (hSub == 1 && vSub == 1) {
2832
for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2833
p1[0] = dataOut[i] & 0xff;
2834
p1[1] = dataOut[i+1] & 0xff;
2835
p1[2] = dataOut[i+2] & 0xff;
2836
p1[3] = dataOut[i+3] & 0xff;
2837
p1[4] = dataOut[i+4] & 0xff;
2838
p1[5] = dataOut[i+5] & 0xff;
2839
p1[6] = dataOut[i+6] & 0xff;
2840
p1[7] = dataOut[i+7] & 0xff;
2843
} else if (hSub == 2 && vSub == 2) {
2845
for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
2846
p1[0] = p1[1] = p2[0] = p2[1] = dataOut[i] & 0xff;
2847
p1[2] = p1[3] = p2[2] = p2[3] = dataOut[i+1] & 0xff;
2848
p1[4] = p1[5] = p2[4] = p2[5] = dataOut[i+2] & 0xff;
2849
p1[6] = p1[7] = p2[6] = p2[7] = dataOut[i+3] & 0xff;
2850
p1[8] = p1[9] = p2[8] = p2[9] = dataOut[i+4] & 0xff;
2851
p1[10] = p1[11] = p2[10] = p2[11] = dataOut[i+5] & 0xff;
2852
p1[12] = p1[13] = p2[12] = p2[13] = dataOut[i+6] & 0xff;
2853
p1[14] = p1[15] = p2[14] = p2[15] = dataOut[i+7] & 0xff;
2859
for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
2860
for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
2862
for (y5 = 0; y5 < vSub; ++y5) {
2863
for (x5 = 0; x5 < hSub; ++x5) {
2864
p2[x5] = dataOut[i] & 0xff;
2870
p1 += bufWidth * vSub;
2877
// color space conversion
2879
// convert YCbCr to RGB
2880
if (numComps == 3) {
2881
for (y2 = 0; y2 < mcuHeight; ++y2) {
2882
p0 = &frameBuf[0][(y1+y2) * bufWidth + x1];
2883
p1 = &frameBuf[1][(y1+y2) * bufWidth + x1];
2884
p2 = &frameBuf[2][(y1+y2) * bufWidth + x1];
2885
for (x2 = 0; x2 < mcuWidth; ++x2) {
2889
pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2890
*p0++ = dctClip[dctClipOffset + pR];
2891
pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr +
2893
*p1++ = dctClip[dctClipOffset + pG];
2894
pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2895
*p2++ = dctClip[dctClipOffset + pB];
2898
// convert YCbCrK to CMYK (K is passed through unchanged)
2899
} else if (numComps == 4) {
2900
for (y2 = 0; y2 < mcuHeight; ++y2) {
2901
p0 = &frameBuf[0][(y1+y2) * bufWidth + x1];
2902
p1 = &frameBuf[1][(y1+y2) * bufWidth + x1];
2903
p2 = &frameBuf[2][(y1+y2) * bufWidth + x1];
2904
for (x2 = 0; x2 < mcuWidth; ++x2) {
2908
pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2909
*p0++ = 255 - dctClip[dctClipOffset + pR];
2910
pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr +
2912
*p1++ = 255 - dctClip[dctClipOffset + pG];
2913
pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2914
*p2++ = 255 - dctClip[dctClipOffset + pB];
2923
// Transform one data unit -- this performs the dequantization and
2924
// IDCT steps. This IDCT algorithm is taken from:
2925
// Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
2926
// "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
2927
// IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
2929
// The stage numbers mentioned in the comments refer to Figure 1 in this
2931
void DCTStream::transformDataUnit(Gushort *quantTable,
2932
int dataIn[64], Guchar dataOut[64]) {
2933
int v0, v1, v2, v3, v4, v5, v6, v7, t;
2938
for (i = 0; i < 64; ++i) {
2939
dataIn[i] *= quantTable[i];
2942
// inverse DCT on rows
2943
for (i = 0; i < 64; i += 8) {
2946
// check for all-zero AC coefficients
2947
if (p[1] == 0 && p[2] == 0 && p[3] == 0 &&
2948
p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] == 0) {
2949
t = (dctSqrt2 * p[0] + 512) >> 10;
2962
v0 = (dctSqrt2 * p[0] + 128) >> 8;
2963
v1 = (dctSqrt2 * p[4] + 128) >> 8;
2966
v4 = (dctSqrt1d2 * (p[1] - p[7]) + 128) >> 8;
2967
v7 = (dctSqrt1d2 * (p[1] + p[7]) + 128) >> 8;
2972
t = (v0 - v1+ 1) >> 1;
2973
v0 = (v0 + v1 + 1) >> 1;
2975
t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
2976
v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8;
2978
t = (v4 - v6 + 1) >> 1;
2979
v4 = (v4 + v6 + 1) >> 1;
2981
t = (v7 + v5 + 1) >> 1;
2982
v5 = (v7 - v5 + 1) >> 1;
2986
t = (v0 - v3 + 1) >> 1;
2987
v0 = (v0 + v3 + 1) >> 1;
2989
t = (v1 - v2 + 1) >> 1;
2990
v1 = (v1 + v2 + 1) >> 1;
2992
t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
2993
v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
2995
t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
2996
v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
3010
// inverse DCT on columns
3011
for (i = 0; i < 8; ++i) {
3014
// check for all-zero AC coefficients
3015
if (p[1*8] == 0 && p[2*8] == 0 && p[3*8] == 0 &&
3016
p[4*8] == 0 && p[5*8] == 0 && p[6*8] == 0 && p[7*8] == 0) {
3017
t = (dctSqrt2 * dataIn[i+0] + 8192) >> 14;
3030
v0 = (dctSqrt2 * p[0*8] + 2048) >> 12;
3031
v1 = (dctSqrt2 * p[4*8] + 2048) >> 12;
3034
v4 = (dctSqrt1d2 * (p[1*8] - p[7*8]) + 2048) >> 12;
3035
v7 = (dctSqrt1d2 * (p[1*8] + p[7*8]) + 2048) >> 12;
3040
t = (v0 - v1 + 1) >> 1;
3041
v0 = (v0 + v1 + 1) >> 1;
3043
t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
3044
v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12;
3046
t = (v4 - v6 + 1) >> 1;
3047
v4 = (v4 + v6 + 1) >> 1;
3049
t = (v7 + v5 + 1) >> 1;
3050
v5 = (v7 - v5 + 1) >> 1;
3054
t = (v0 - v3 + 1) >> 1;
3055
v0 = (v0 + v3 + 1) >> 1;
3057
t = (v1 - v2 + 1) >> 1;
3058
v1 = (v1 + v2 + 1) >> 1;
3060
t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
3061
v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
3063
t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
3064
v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
3078
// convert to 8-bit integers
3079
for (i = 0; i < 64; ++i) {
3080
dataOut[i] = dctClip[dctClipOffset + 128 + ((dataIn[i] + 8) >> 4)];
3084
int DCTStream::readHuffSym(DCTHuffTable *table) {
3092
// add a bit to the code
3093
if ((bit = readBit()) == EOF)
3095
code = (code << 1) + bit;
3099
if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
3100
code -= table->firstCode[codeBits];
3101
return table->sym[table->firstSym[codeBits] + code];
3103
} while (codeBits < 16);
3105
error(getPos(), "Bad Huffman code in DCT stream");
3109
int DCTStream::readAmp(int size) {
3114
for (bits = 0; bits < size; ++bits) {
3115
if ((bit = readBit()) == EOF)
3117
amp = (amp << 1) + bit;
3119
if (amp < (1 << (size - 1)))
3120
amp -= (1 << size) - 1;
3124
int DCTStream::readBit() {
3128
if (inputBits == 0) {
3129
if ((c = str->getChar()) == EOF)
3133
c2 = str->getChar();
3134
} while (c2 == 0xff);
3136
error(getPos(), "Bad DCT data: missing 00 after ff");
3143
bit = (inputBuf >> (inputBits - 1)) & 1;
3148
GBool DCTStream::readHeader() {
3159
case 0xc0: // SOF0 (sequential)
3160
case 0xc1: // SOF1 (extended sequential)
3161
if (!readBaselineSOF()) {
3165
case 0xc2: // SOF2 (progressive)
3166
if (!readProgressiveSOF()) {
3171
if (!readHuffmanTables()) {
3180
if (!readScanInfo()) {
3186
if (!readQuantTables()) {
3191
if (!readRestartInterval()) {
3196
if (!readJFIFMarker()) {
3201
if (!readAdobeMarker()) {
3206
error(getPos(), "Bad DCT header");
3209
// skip APPn / COM / etc.
3212
for (i = 0; i < n; ++i) {
3216
error(getPos(), "Unknown DCT marker <%02x>", c);
3226
GBool DCTStream::readBaselineSOF() {
3233
prec = str->getChar();
3236
numComps = str->getChar();
3237
if (numComps <= 0 || numComps > 4) {
3238
error(getPos(), "Bad number of components in DCT stream");
3243
error(getPos(), "Bad DCT precision %d", prec);
3246
for (i = 0; i < numComps; ++i) {
3247
compInfo[i].id = str->getChar();
3249
compInfo[i].hSample = (c >> 4) & 0x0f;
3250
compInfo[i].vSample = c & 0x0f;
3251
compInfo[i].quantTable = str->getChar();
3253
progressive = gFalse;
3257
GBool DCTStream::readProgressiveSOF() {
3264
prec = str->getChar();
3267
numComps = str->getChar();
3269
error(getPos(), "Bad DCT precision %d", prec);
3272
for (i = 0; i < numComps; ++i) {
3273
compInfo[i].id = str->getChar();
3275
compInfo[i].hSample = (c >> 4) & 0x0f;
3276
compInfo[i].vSample = c & 0x0f;
3277
compInfo[i].quantTable = str->getChar();
3279
progressive = gTrue;
3283
GBool DCTStream::readScanInfo() {
3288
length = read16() - 2;
3289
scanInfo.numComps = str->getChar();
3290
if (scanInfo.numComps <= 0 || scanInfo.numComps > 4) {
3291
error(getPos(), "Bad number of components in DCT stream");
3292
scanInfo.numComps = 0;
3296
if (length != 2 * scanInfo.numComps + 3) {
3297
error(getPos(), "Bad DCT scan info block");
3300
interleaved = scanInfo.numComps == numComps;
3301
for (j = 0; j < numComps; ++j) {
3302
scanInfo.comp[j] = gFalse;
3303
scanInfo.dcHuffTable[j] = 0;
3304
scanInfo.acHuffTable[j] = 0;
3306
for (i = 0; i < scanInfo.numComps; ++i) {
3307
id = str->getChar();
3308
// some (broken) DCT streams reuse ID numbers, but at least they
3309
// keep the components in order, so we check compInfo[i] first to
3310
// work around the problem
3311
if (id == compInfo[i].id) {
3314
for (j = 0; j < numComps; ++j) {
3315
if (id == compInfo[j].id) {
3319
if (j == numComps) {
3320
error(getPos(), "Bad DCT component ID in scan info block");
3324
scanInfo.comp[j] = gTrue;
3326
scanInfo.dcHuffTable[j] = (c >> 4) & 0x0f;
3327
scanInfo.acHuffTable[j] = c & 0x0f;
3329
scanInfo.firstCoeff = str->getChar();
3330
scanInfo.lastCoeff = str->getChar();
3331
if (scanInfo.firstCoeff < 0 || scanInfo.lastCoeff > 63 ||
3332
scanInfo.firstCoeff > scanInfo.lastCoeff) {
3333
error(getPos(), "Bad DCT coefficient numbers in scan info block");
3337
scanInfo.ah = (c >> 4) & 0x0f;
3338
scanInfo.al = c & 0x0f;
3342
GBool DCTStream::readQuantTables() {
3343
int length, prec, i, index;
3345
length = read16() - 2;
3346
while (length > 0) {
3347
index = str->getChar();
3348
prec = (index >> 4) & 0x0f;
3350
if (prec > 1 || index >= 4) {
3351
error(getPos(), "Bad DCT quantization table");
3354
if (index == numQuantTables) {
3355
numQuantTables = index + 1;
3357
for (i = 0; i < 64; ++i) {
3359
quantTables[index][dctZigZag[i]] = read16();
3361
quantTables[index][dctZigZag[i]] = str->getChar();
3373
GBool DCTStream::readHuffmanTables() {
3382
length = read16() - 2;
3383
while (length > 0) {
3384
index = str->getChar();
3386
if ((index & 0x0f) >= 4) {
3387
error(getPos(), "Bad DCT Huffman table");
3392
if (index >= numACHuffTables)
3393
numACHuffTables = index+1;
3394
tbl = &acHuffTables[index];
3397
if (index >= numDCHuffTables)
3398
numDCHuffTables = index+1;
3399
tbl = &dcHuffTables[index];
3403
for (i = 1; i <= 16; ++i) {
3405
tbl->firstSym[i] = sym;
3406
tbl->firstCode[i] = code;
3407
tbl->numCodes[i] = c;
3409
code = (code + c) << 1;
3412
for (i = 0; i < sym; ++i)
3413
tbl->sym[i] = str->getChar();
3419
GBool DCTStream::readRestartInterval() {
3424
error(getPos(), "Bad DCT restart interval");
3427
restartInterval = read16();
3431
GBool DCTStream::readJFIFMarker() {
3439
for (i = 0; i < 5; ++i) {
3440
if ((c = str->getChar()) == EOF) {
3441
error(getPos(), "Bad DCT APP0 marker");
3447
if (!memcmp(buf, "JFIF\0", 5)) {
3448
gotJFIFMarker = gTrue;
3451
while (length > 0) {
3452
if (str->getChar() == EOF) {
3453
error(getPos(), "Bad DCT APP0 marker");
3461
GBool DCTStream::readAdobeMarker() {
3470
for (i = 0; i < 12; ++i) {
3471
if ((c = str->getChar()) == EOF) {
3476
if (strncmp(buf, "Adobe", 5)) {
3479
colorXform = buf[11];
3480
gotAdobeMarker = gTrue;
3481
for (i = 14; i < length; ++i) {
3482
if (str->getChar() == EOF) {
3489
error(getPos(), "Bad DCT Adobe APP14 marker");
3493
GBool DCTStream::readTrailer() {
3497
if (c != 0xd9) { // EOI
3498
error(getPos(), "Bad DCT trailer");
3504
int DCTStream::readMarker() {
3510
} while (c != 0xff && c != EOF);
3514
} while (c == 0x00);
3518
int DCTStream::read16() {
3521
if ((c1 = str->getChar()) == EOF)
3523
if ((c2 = str->getChar()) == EOF)
3525
return (c1 << 8) + c2;
3528
GooString *DCTStream::getPSFilter(int psLevel, char *indent) {
3534
if (!(s = str->getPSFilter(psLevel, indent))) {
3537
s->append(indent)->append("<< >> /DCTDecode filter\n");
3541
GBool DCTStream::isBinary(GBool last) {
3542
return str->isBinary(gTrue);
3548
//------------------------------------------------------------------------
3550
//------------------------------------------------------------------------
3552
int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = {
3553
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
3556
FlateDecode FlateStream::lengthDecode[flateMaxLitCodes-257] = {
3590
FlateDecode FlateStream::distDecode[flateMaxDistCodes] = {
3623
static FlateCode flateFixedLitCodeTabCodes[512] = {
4138
FlateHuffmanTab FlateStream::fixedLitCodeTab = {
4139
flateFixedLitCodeTabCodes, 9
4142
static FlateCode flateFixedDistCodeTabCodes[32] = {
4177
FlateHuffmanTab FlateStream::fixedDistCodeTab = {
4178
flateFixedDistCodeTabCodes, 5
4181
FlateStream::FlateStream(Stream *strA, int predictor, int columns,
4182
int colors, int bits):
4183
FilterStream(strA) {
4184
if (predictor != 1) {
4185
pred = new StreamPredictor(this, predictor, columns, colors, bits);
4186
if (!pred->isOk()) {
4193
litCodeTab.codes = NULL;
4194
distCodeTab.codes = NULL;
4195
memset(buf, 0, flateWindow);
4198
FlateStream::~FlateStream() {
4199
if (litCodeTab.codes != fixedLitCodeTab.codes) {
4200
gfree(litCodeTab.codes);
4202
if (distCodeTab.codes != fixedDistCodeTab.codes) {
4203
gfree(distCodeTab.codes);
4211
void FlateStream::unfilteredReset() {
4216
compressedBlock = gFalse;
4223
void FlateStream::reset() {
4229
//~ need to look at window size?
4230
endOfBlock = eof = gTrue;
4231
cmf = str->getChar();
4232
flg = str->getChar();
4233
if (cmf == EOF || flg == EOF)
4235
if ((cmf & 0x0f) != 0x08) {
4236
error(getPos(), "Unknown compression method in flate stream");
4239
if ((((cmf << 8) + flg) % 31) != 0) {
4240
error(getPos(), "Bad FCHECK in flate stream");
4244
error(getPos(), "FDICT bit set in flate stream");
4251
int FlateStream::getChar() {
4255
int FlateStream::getChars(int nChars, Guchar *buffer) {
4257
return pred->getChars(nChars, buffer);
4259
for (int i = 0; i < nChars; ++i) {
4260
const int c = doGetChar();
4261
if (likely(c != EOF)) buffer[i] = c;
4268
int FlateStream::lookChar() {
4272
return pred->lookChar();
4274
while (remain == 0) {
4275
if (endOfBlock && eof)
4283
void FlateStream::getRawChars(int nChars, int *buffer) {
4284
for (int i = 0; i < nChars; ++i)
4285
buffer[i] = doGetRawChar();
4288
int FlateStream::getRawChar() {
4289
return doGetRawChar();
4292
GooString *FlateStream::getPSFilter(int psLevel, char *indent) {
4295
if (psLevel < 3 || pred) {
4298
if (!(s = str->getPSFilter(psLevel, indent))) {
4301
s->append(indent)->append("<< >> /FlateDecode filter\n");
4305
GBool FlateStream::isBinary(GBool last) {
4306
return str->isBinary(gTrue);
4309
void FlateStream::readSome() {
4320
if (compressedBlock) {
4321
if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF)
4326
} else if (code1 == 256) {
4331
code2 = lengthDecode[code1].bits;
4332
if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
4334
len = lengthDecode[code1].first + code2;
4335
if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF)
4337
code2 = distDecode[code1].bits;
4338
if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
4340
dist = distDecode[code1].first + code2;
4342
j = (index - dist) & flateMask;
4343
for (k = 0; k < len; ++k) {
4345
i = (i + 1) & flateMask;
4346
j = (j + 1) & flateMask;
4352
len = (blockLen < flateWindow) ? blockLen : flateWindow;
4353
for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) {
4354
if ((c = str->getChar()) == EOF) {
4355
endOfBlock = eof = gTrue;
4369
error(getPos(), "Unexpected end of file in flate stream");
4370
endOfBlock = eof = gTrue;
4374
GBool FlateStream::startBlock() {
4379
// free the code tables from the previous block
4380
if (litCodeTab.codes != fixedLitCodeTab.codes) {
4381
gfree(litCodeTab.codes);
4383
litCodeTab.codes = NULL;
4384
if (distCodeTab.codes != fixedDistCodeTab.codes) {
4385
gfree(distCodeTab.codes);
4387
distCodeTab.codes = NULL;
4389
// read block header
4390
blockHdr = getCodeWord(3);
4395
// uncompressed block
4396
if (blockHdr == 0) {
4397
compressedBlock = gFalse;
4398
if ((c = str->getChar()) == EOF)
4400
blockLen = c & 0xff;
4401
if ((c = str->getChar()) == EOF)
4403
blockLen |= (c & 0xff) << 8;
4404
if ((c = str->getChar()) == EOF)
4407
if ((c = str->getChar()) == EOF)
4409
check |= (c & 0xff) << 8;
4410
if (check != (~blockLen & 0xffff))
4411
error(getPos(), "Bad uncompressed block length in flate stream");
4415
// compressed block with fixed codes
4416
} else if (blockHdr == 1) {
4417
compressedBlock = gTrue;
4420
// compressed block with dynamic codes
4421
} else if (blockHdr == 2) {
4422
compressedBlock = gTrue;
4423
if (!readDynamicCodes()) {
4427
// unknown block type
4432
endOfBlock = gFalse;
4436
error(getPos(), "Bad block header in flate stream");
4437
endOfBlock = eof = gTrue;
4441
void FlateStream::loadFixedCodes() {
4442
litCodeTab.codes = fixedLitCodeTab.codes;
4443
litCodeTab.maxLen = fixedLitCodeTab.maxLen;
4444
distCodeTab.codes = fixedDistCodeTab.codes;
4445
distCodeTab.maxLen = fixedDistCodeTab.maxLen;
4448
GBool FlateStream::readDynamicCodes() {
4449
int numCodeLenCodes;
4452
int codeLenCodeLengths[flateMaxCodeLenCodes];
4453
FlateHuffmanTab codeLenCodeTab;
4454
int len, repeat, code;
4457
codeLenCodeTab.codes = NULL;
4460
if ((numLitCodes = getCodeWord(5)) == EOF) {
4464
if ((numDistCodes = getCodeWord(5)) == EOF) {
4468
if ((numCodeLenCodes = getCodeWord(4)) == EOF) {
4471
numCodeLenCodes += 4;
4472
if (numLitCodes > flateMaxLitCodes ||
4473
numDistCodes > flateMaxDistCodes ||
4474
numCodeLenCodes > flateMaxCodeLenCodes) {
4478
// build the code length code table
4479
for (i = 0; i < flateMaxCodeLenCodes; ++i) {
4480
codeLenCodeLengths[i] = 0;
4482
for (i = 0; i < numCodeLenCodes; ++i) {
4483
if ((codeLenCodeLengths[codeLenCodeMap[i]] = getCodeWord(3)) == -1) {
4487
compHuffmanCodes(codeLenCodeLengths, flateMaxCodeLenCodes, &codeLenCodeTab);
4489
// build the literal and distance code tables
4493
while (i < numLitCodes + numDistCodes) {
4494
if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF) {
4498
if ((repeat = getCodeWord(2)) == EOF) {
4502
if (i + repeat > numLitCodes + numDistCodes) {
4505
for (; repeat > 0; --repeat) {
4506
codeLengths[i++] = len;
4508
} else if (code == 17) {
4509
if ((repeat = getCodeWord(3)) == EOF) {
4513
if (i + repeat > numLitCodes + numDistCodes) {
4517
for (; repeat > 0; --repeat) {
4518
codeLengths[i++] = 0;
4520
} else if (code == 18) {
4521
if ((repeat = getCodeWord(7)) == EOF) {
4525
if (i + repeat > numLitCodes + numDistCodes) {
4529
for (; repeat > 0; --repeat) {
4530
codeLengths[i++] = 0;
4533
codeLengths[i++] = len = code;
4536
compHuffmanCodes(codeLengths, numLitCodes, &litCodeTab);
4537
compHuffmanCodes(codeLengths + numLitCodes, numDistCodes, &distCodeTab);
4539
gfree(codeLenCodeTab.codes);
4543
error(getPos(), "Bad dynamic code table in flate stream");
4544
gfree(codeLenCodeTab.codes);
4548
// Convert an array <lengths> of <n> lengths, in value order, into a
4549
// Huffman code lookup table.
4550
void FlateStream::compHuffmanCodes(int *lengths, int n, FlateHuffmanTab *tab) {
4551
int tabSize, len, code, code2, skip, val, i, t;
4553
// find max code length
4555
for (val = 0; val < n; ++val) {
4556
if (lengths[val] > tab->maxLen) {
4557
tab->maxLen = lengths[val];
4561
// allocate the table
4562
tabSize = 1 << tab->maxLen;
4563
tab->codes = (FlateCode *)gmallocn(tabSize, sizeof(FlateCode));
4566
for (i = 0; i < tabSize; ++i) {
4567
tab->codes[i].len = 0;
4568
tab->codes[i].val = 0;
4572
for (len = 1, code = 0, skip = 2;
4574
++len, code <<= 1, skip <<= 1) {
4575
for (val = 0; val < n; ++val) {
4576
if (lengths[val] == len) {
4578
// bit-reverse the code
4581
for (i = 0; i < len; ++i) {
4582
code2 = (code2 << 1) | (t & 1);
4586
// fill in the table entries
4587
for (i = code2; i < tabSize; i += skip) {
4588
tab->codes[i].len = (Gushort)len;
4589
tab->codes[i].val = (Gushort)val;
4598
int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) {
4602
while (codeSize < tab->maxLen) {
4603
if ((c = str->getChar()) == EOF) {
4606
codeBuf |= (c & 0xff) << codeSize;
4609
code = &tab->codes[codeBuf & ((1 << tab->maxLen) - 1)];
4610
if (codeSize == 0 || codeSize < code->len || code->len == 0) {
4613
codeBuf >>= code->len;
4614
codeSize -= code->len;
4615
return (int)code->val;
4618
int FlateStream::getCodeWord(int bits) {
4621
while (codeSize < bits) {
4622
if ((c = str->getChar()) == EOF)
4624
codeBuf |= (c & 0xff) << codeSize;
4627
c = codeBuf & ((1 << bits) - 1);
4634
//------------------------------------------------------------------------
4636
//------------------------------------------------------------------------
4638
EOFStream::EOFStream(Stream *strA):
4639
FilterStream(strA) {
4642
EOFStream::~EOFStream() {
4646
//------------------------------------------------------------------------
4647
// FixedLengthEncoder
4648
//------------------------------------------------------------------------
4650
FixedLengthEncoder::FixedLengthEncoder(Stream *strA, int lengthA):
4651
FilterStream(strA) {
4656
FixedLengthEncoder::~FixedLengthEncoder() {
4657
if (str->isEncoder())
4661
void FixedLengthEncoder::reset() {
4666
int FixedLengthEncoder::getChar() {
4667
if (length >= 0 && count >= length)
4670
return str->getChar();
4673
int FixedLengthEncoder::lookChar() {
4674
if (length >= 0 && count >= length)
4676
return str->getChar();
4679
GBool FixedLengthEncoder::isBinary(GBool last) {
4680
return str->isBinary(gTrue);
4683
//------------------------------------------------------------------------
4685
//------------------------------------------------------------------------
4687
ASCIIHexEncoder::ASCIIHexEncoder(Stream *strA):
4688
FilterStream(strA) {
4689
bufPtr = bufEnd = buf;
4694
ASCIIHexEncoder::~ASCIIHexEncoder() {
4695
if (str->isEncoder()) {
4700
void ASCIIHexEncoder::reset() {
4702
bufPtr = bufEnd = buf;
4707
GBool ASCIIHexEncoder::fillBuf() {
4708
static const char *hex = "0123456789abcdef";
4714
bufPtr = bufEnd = buf;
4715
if ((c = str->getChar()) == EOF) {
4719
if (lineLen >= 64) {
4723
*bufEnd++ = hex[(c >> 4) & 0x0f];
4724
*bufEnd++ = hex[c & 0x0f];
4730
//------------------------------------------------------------------------
4732
//------------------------------------------------------------------------
4734
ASCII85Encoder::ASCII85Encoder(Stream *strA):
4735
FilterStream(strA) {
4736
bufPtr = bufEnd = buf;
4741
ASCII85Encoder::~ASCII85Encoder() {
4742
if (str->isEncoder())
4746
void ASCII85Encoder::reset() {
4748
bufPtr = bufEnd = buf;
4753
GBool ASCII85Encoder::fillBuf() {
4762
c0 = str->getChar();
4763
c1 = str->getChar();
4764
c2 = str->getChar();
4765
c3 = str->getChar();
4766
bufPtr = bufEnd = buf;
4775
} else if (c2 == EOF) {
4777
t = (c0 << 24) | (c1 << 16);
4780
t = (c0 << 24) | (c1 << 16) | (c2 << 8);
4782
for (i = 4; i >= 0; --i) {
4783
buf1[i] = (char)(t % 85 + 0x21);
4786
for (i = 0; i <= n; ++i) {
4787
*bufEnd++ = buf1[i];
4788
if (++lineLen == 65) {
4798
t = (c0 << 24) | (c1 << 16) | (c2 << 8) | c3;
4801
if (++lineLen == 65) {
4806
for (i = 4; i >= 0; --i) {
4807
buf1[i] = (char)(t % 85 + 0x21);
4810
for (i = 0; i <= 4; ++i) {
4811
*bufEnd++ = buf1[i];
4812
if (++lineLen == 65) {
4822
//------------------------------------------------------------------------
4824
//------------------------------------------------------------------------
4826
RunLengthEncoder::RunLengthEncoder(Stream *strA):
4827
FilterStream(strA) {
4828
bufPtr = bufEnd = nextEnd = buf;
4832
RunLengthEncoder::~RunLengthEncoder() {
4833
if (str->isEncoder())
4837
void RunLengthEncoder::reset() {
4839
bufPtr = bufEnd = nextEnd = buf;
4844
// When fillBuf finishes, buf[] looks like this:
4845
// +-----+--------------+-----------------+--
4846
// + tag | ... data ... | next 0, 1, or 2 |
4847
// +-----+--------------+-----------------+--
4849
// bufPtr bufEnd nextEnd
4851
GBool RunLengthEncoder::fillBuf() {
4860
if (nextEnd < bufEnd + 1) {
4861
if ((c1 = str->getChar()) == EOF) {
4866
c1 = bufEnd[0] & 0xff;
4868
if (nextEnd < bufEnd + 2) {
4869
if ((c2 = str->getChar()) == EOF) {
4878
c2 = bufEnd[1] & 0xff;
4882
c = 0; // make gcc happy
4885
while (n < 128 && (c = str->getChar()) == c1)
4887
buf[0] = (char)(257 - n);
4892
} else if (n < 128) {
4899
// get up to 128 chars
4905
if ((c = str->getChar()) == EOF) {
4911
if (buf[n] == buf[n-1])
4914
if (buf[n] == buf[n-1]) {
4915
buf[0] = (char)(n-2-1);
4917
nextEnd = &buf[n+1];
4919
buf[0] = (char)(n-1);
4920
bufEnd = nextEnd = &buf[n+1];