View | Details | Raw Unified | Return to bug 190899
Collapse All | Expand All

(-)graphics/ipe/Makefile (-8 / +12 lines)
Lines 2-8 Link Here
2
# $FreeBSD: head/graphics/ipe/Makefile 340291 2014-01-19 13:46:19Z miwi $
2
# $FreeBSD: head/graphics/ipe/Makefile 340291 2014-01-19 13:46:19Z miwi $
3
3
4
PORTNAME=	ipe
4
PORTNAME=	ipe
5
PORTVERSION=	7.1.4
5
PORTVERSION=	7.1.5
6
DISTVERSIONSUFFIX=	-src
6
DISTVERSIONSUFFIX=	-src
7
CATEGORIES=	graphics
7
CATEGORIES=	graphics
8
MASTER_SITES=	SF/${PORTNAME}${PORTVERSION:R:R}/${PORTNAME}/${PORTVERSION:R}
8
MASTER_SITES=	SF/${PORTNAME}${PORTVERSION:R:R}/${PORTNAME}/${PORTVERSION:R}
Lines 12-29 Link Here
12
12
13
LICENSE=	GPLv3 # (or later)
13
LICENSE=	GPLv3 # (or later)
14
14
15
LIB_DEPENDS=	libcairo.so:${PORTSDIR}/graphics/cairo \
15
LIB_DEPENDS=	liblua-5.2.so:${PORTSDIR}/lang/lua52
16
		liblua-5.2.so:${PORTSDIR}/lang/lua52
17
RUN_DEPENDS=	xdg-open:${PORTSDIR}/devel/xdg-utils
16
RUN_DEPENDS=	xdg-open:${PORTSDIR}/devel/xdg-utils
18
17
19
OPTIONS_DEFINE=	DOCS
20
21
WRKSRC=		${WRKDIR}/${PORTNAME}-${PORTVERSION}/src
18
WRKSRC=		${WRKDIR}/${PORTNAME}-${PORTVERSION}/src
22
19
23
USES=		gmake iconv pkgconfig
20
USES=		dos2unix gmake iconv pkgconfig
21
DOS2UNIX_FILES=	ipelib/Makefile
22
USE_GNOME=	cairo
24
USE_QT4=	gui moc_build qmake_build rcc_build uic_build
23
USE_QT4=	gui moc_build qmake_build rcc_build uic_build
25
USE_TEX=	latex
24
USE_TEX=	latex
26
MAKE_ENV=	DLL_CFLAGS="-fPIC" \
25
MAKE_ENV=	DL_LIBS="" \
26
		DLL_CFLAGS="-fPIC" \
27
		ICONV_CFLAGS="-I${ICONV_PREFIX}/include" \
27
		ICONV_CFLAGS="-I${ICONV_PREFIX}/include" \
28
		ICONV_LIBS="-L${ICONV_PREFIX}/lib ${ICONV_LIB}" \
28
		ICONV_LIBS="-L${ICONV_PREFIX}/lib ${ICONV_LIB}" \
29
		INSTALL_DIR="${MKDIR}" \
29
		INSTALL_DIR="${MKDIR}" \
Lines 35-40 Link Here
35
		IPEDOCDIR="${DOCSDIR}" \
35
		IPEDOCDIR="${DOCSDIR}" \
36
		IPEMANDIR="${MANPREFIX}/man/man1" \
36
		IPEMANDIR="${MANPREFIX}/man/man1" \
37
		IPEPREFIX="${PREFIX}" \
37
		IPEPREFIX="${PREFIX}" \
38
		JPEG_CFLAGS="-I${LOCALBASE}/include" \
39
		JPEG_LIBS="-L${LOCALBASE}/lib -ljpeg" \
38
		LUA_CFLAGS="-I${LOCALBASE}/include/lua52" \
40
		LUA_CFLAGS="-I${LOCALBASE}/include/lua52" \
39
		LUA_LIBS="-L${LOCALBASE}/lib -llua-5.2" \
41
		LUA_LIBS="-L${LOCALBASE}/lib -llua-5.2" \
40
		MOC="${MOC}"
42
		MOC="${MOC}"
Lines 47-53 Link Here
47
DESKTOP_ENTRIES="Ipe" "" "${DATADIR}/${PORTVERSION}/ipe.png" \
49
DESKTOP_ENTRIES="Ipe" "" "${DATADIR}/${PORTVERSION}/ipe.png" \
48
		"${PORTNAME}" "" true
50
		"${PORTNAME}" "" true
49
51
50
.include <bsd.port.options.mk>
52
OPTIONS_DEFINE=	DOCS
51
53
52
post-patch:
54
post-patch:
53
	@cd ${WRKSRC}/../fontmaps && ${SED} -e \
55
	@cd ${WRKSRC}/../fontmaps && ${SED} -e \
Lines 63-68 Link Here
63
		'/$$(INSTALL_ROOT)$$(IPEDOCDIR)/s|^|#|' ${WRKSRC}/ipe/Makefile
65
		'/$$(INSTALL_ROOT)$$(IPEDOCDIR)/s|^|#|' ${WRKSRC}/ipe/Makefile
64
	@${REINPLACE_CMD} -e \
66
	@${REINPLACE_CMD} -e \
65
		'/%s/s|gnome-open|xdg-open|' ${WRKSRC}/ipe/lua/prefs.lua
67
		'/%s/s|gnome-open|xdg-open|' ${WRKSRC}/ipe/lua/prefs.lua
68
	@${REINPLACE_CMD} -e \
69
		's|QT__H|QT_H|' ${WRKSRC}/ipeui/ipeui_qt.h
66
70
67
post-install:
71
post-install:
68
	(cd ${WRKSRC}/../fontmaps && ${INSTALL_DATA} fontmap.xml \
72
	(cd ${WRKSRC}/../fontmaps && ${INSTALL_DATA} fontmap.xml \
(-)graphics/ipe/distinfo (-2 / +2 lines)
Lines 1-2 Link Here
1
SHA256 (ipe-7.1.4-src.tar.gz) = 50ccd74064595a7bbaa93ef8f8a9988fd4be31fd545ce9c6e85c604e0c8a44eb
1
SHA256 (ipe-7.1.5-src.tar.gz) = fe63a0511bd52d4e256b06f35ce8abc5610267a10594280ca0aaaf15c6e27b1a
2
SIZE (ipe-7.1.4-src.tar.gz) = 1502198
2
SIZE (ipe-7.1.5-src.tar.gz) = 1609566
(-)graphics/ipe/files/patch-ipe6upgrade__ipe6upgrade.cpp (-11 lines)
Lines 1-11 Link Here
1
--- ipe6upgrade/ipe6upgrade.cpp.orig
2
+++ ipe6upgrade/ipe6upgrade.cpp
3
@@ -30,6 +30,8 @@
4
 
5
 #include "ipexml.h"
6
 #include "ipeattributes.h"
7
+#include <cstdlib>
8
+#include <sys/types.h>
9
 
10
 using namespace ipe;
11
 
(-)graphics/ipe/files/patch-ipeextract__ipeextract.cpp (-10 lines)
Lines 1-10 Link Here
1
--- ipeextract/ipeextract.cpp.orig
2
+++ ipeextract/ipeextract.cpp
3
@@ -31,6 +31,7 @@
4
 #include "ipexml.h"
5
 #include "ipeutils.h"
6
 #include "ipepdfparser.h"
7
+#include <cstdlib>
8
 
9
 using namespace ipe;
10
 
(-)graphics/ipe/files/patch-ipelib__Makefile (+10 lines)
Line 0 Link Here
1
--- ipelib/Makefile.orig
2
+++ ipelib/Makefile
3
@@ -27,6 +27,7 @@
4
 	ipexml.cpp \
5
 	ipeattributes.cpp \
6
 	ipebitmap.cpp \
7
+	ipedct.cpp \
8
 	ipeshape.cpp \
9
 	ipegroup.cpp \
10
 	ipeimage.cpp \
(-)graphics/ipe/files/patch-ipelib__ipebase.cpp (-12 lines)
Lines 1-12 Link Here
1
--- ipelib/ipebase.cpp.orig
2
+++ ipelib/ipebase.cpp
3
@@ -29,7 +29,9 @@
4
 */
5
 
6
 #include "ipebase.h"
7
+#include <cstdlib>
8
 #include <cmath>
9
+#include <sys/types.h>
10
 
11
 using namespace ipe;
12
 
(-)graphics/ipe/files/patch-ipelib__ipebitmap.cpp (+47 lines)
Line 0 Link Here
1
--- ipelib/ipebitmap.cpp.orig
2
+++ ipelib/ipebitmap.cpp
3
@@ -32,10 +32,16 @@
4
 #include "ipeutils.h"
5
 #include <zlib.h>
6
 
7
+#if 0
8
 #include <turbojpeg.h>
9
+#endif
10
 
11
 using namespace ipe;
12
 
13
+#if 1
14
+extern bool dctDecode(Buffer dctData, Buffer pixelData);
15
+#endif
16
+
17
 // --------------------------------------------------------------------
18
 
19
 /*! \class ipe::Bitmap::MRenderData
20
@@ -331,6 +337,7 @@
21
 
22
 // --------------------------------------------------------------------
23
 
24
+#if 0
25
 bool dctDecode(Buffer dctData, Buffer pixelData, int components)
26
 {
27
   tjhandle handle = tjInitDecompress();
28
@@ -363,6 +370,7 @@
29
   tjDestroy(handle);
30
   return true;
31
 }
32
+#endif
33
 
34
 //! Convert bitmap data to a height x width pixel array in rgb format.
35
 /*! Returns empty buffer if it cannot decode the bitmap information.
36
@@ -387,7 +395,11 @@
37
       return Buffer();
38
   } else if (filter() == EDCTDecode) {
39
     pixels = Buffer(width() * height() * components());
40
+#if 0
41
     if (!dctDecode(stream, pixels, components()))
42
+#else
43
+    if (!dctDecode(stream, pixels))
44
+#endif
45
       return Buffer();
46
   }
47
   Buffer data(height() * width() * sizeof(uint));
(-)graphics/ipe/files/patch-ipelib__ipedct.cpp (-8 / +1466 lines)
Lines 1-10 Link Here
1
--- ipelib/ipedct.cpp.orig
1
--- ipelib/ipedct.cpp.orig
2
+++ ipelib/ipedct.cpp
2
+++ ipelib/ipedct.cpp
3
@@ -31,6 +31,7 @@
3
@@ -0,0 +1,1465 @@
4
 */
4
+//------------------------------------------------------------------------
5
 
5
+// Decoding a DCT stream (JPEG image)
6
 #include "ipebase.h"
6
+// This code has been taken from Xpdf,
7
+#include <sys/types.h>
7
+// Copyright 1996-2002 Glyph & Cog, LLC
8
 
8
+//------------------------------------------------------------------------
9
 using namespace ipe;
9
+/*
10
 
10
+
11
+    This file is part of the extensible drawing editor Ipe.
12
+    Copyright (C) 1993-2013  Otfried Cheong
13
+
14
+    Ipe is free software; you can redistribute it and/or modify it
15
+    under the terms of the GNU General Public License as published by
16
+    the Free Software Foundation; either version 3 of the License, or
17
+    (at your option) any later version.
18
+
19
+    As a special exception, you have permission to link Ipe with the
20
+    CGAL library and distribute executables, as long as you follow the
21
+    requirements of the Gnu General Public License in regard to all of
22
+    the software in the executable aside from CGAL.
23
+
24
+    Ipe is distributed in the hope that it will be useful, but WITHOUT
25
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26
+    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
27
+    License for more details.
28
+
29
+    You should have received a copy of the GNU General Public License
30
+    along with Ipe; if not, you can find it at
31
+    "http://www.gnu.org/copyleft/gpl.html", or write to the Free
32
+    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33
+
34
+*/
35
+
36
+#include "ipebase.h"
37
+
38
+using namespace ipe;
39
+
40
+// --------------------------------------------------------------------
41
+
42
+// DCT component info
43
+struct DCTCompInfo {
44
+  int id;			// component ID
45
+  int hSample, vSample;		// horiz/vert sampling resolutions
46
+  int quantTable;		// quantization table number
47
+  int prevDC;			// DC coefficient accumulator
48
+};
49
+
50
+struct DCTScanInfo {
51
+  bool comp[4];	                // comp[i] is set if component i is
52
+				//   included in this scan
53
+  int numComps;			// number of components in the scan
54
+  int dcHuffTable[4];		// DC Huffman table numbers
55
+  int acHuffTable[4];		// AC Huffman table numbers
56
+  int firstCoeff, lastCoeff;	// first and last DCT coefficient
57
+  int ah, al;			// successive approximation parameters
58
+};
59
+
60
+// DCT Huffman decoding table
61
+struct DCTHuffTable {
62
+  uchar firstSym[17];		// first symbol for this bit length
63
+  ushort firstCode[17];	        // first code for this bit length
64
+  ushort numCodes[17];		// number of codes of this bit length
65
+  uchar sym[256];		// symbols
66
+};
67
+
68
+// --------------------------------------------------------------------
69
+
70
+class DCTStream {
71
+public:
72
+
73
+  DCTStream(DataSource &source);
74
+  ~DCTStream();
75
+  void reset();
76
+  int getChar();
77
+
78
+private:
79
+  DataSource &iSource;
80
+
81
+  bool progressive;		// set if in progressive mode
82
+  bool interleaved;		// set if in interleaved mode
83
+  int width, height;		// image size
84
+  int mcuWidth, mcuHeight;	// size of min coding unit, in data units
85
+  int bufWidth, bufHeight;	// frameBuf size
86
+  DCTCompInfo compInfo[4];	// info for each component
87
+  DCTScanInfo scanInfo;		// info for the current scan
88
+  int numComps;			// number of components in image
89
+  int colorXform;		// need YCbCr-to-RGB transform?
90
+  bool gotAdobeMarker;		// set if APP14 Adobe marker was present
91
+  int restartInterval;		// restart interval, in MCUs
92
+  uchar quantTables[4][64];	// quantization tables
93
+  int numQuantTables;		// number of quantization tables
94
+  DCTHuffTable dcHuffTables[4];	// DC Huffman tables
95
+  DCTHuffTable acHuffTables[4];	// AC Huffman tables
96
+  int numDCHuffTables;		// number of DC Huffman tables
97
+  int numACHuffTables;		// number of AC Huffman tables
98
+  uchar *rowBuf[4][32];		// buffer for one MCU (non-progressive mode)
99
+  int *frameBuf[4];		// buffer for frame (progressive mode)
100
+  int comp, x, y, dy;		// current position within image/MCU
101
+  int restartCtr;		// MCUs left until restart
102
+  int restartMarker;		// next restart marker
103
+  int eobRun;			// number of EOBs left in the current run
104
+  int inputBuf;			// input buffer for variable length codes
105
+  int inputBits;		// number of valid bits in input buffer
106
+
107
+  void restart();
108
+  bool readMCURow();
109
+  void readScan();
110
+  bool readDataUnit(DCTHuffTable *dcHuffTable,
111
+		    DCTHuffTable *acHuffTable,
112
+		    int *prevDC, int data[64]);
113
+  bool readProgressiveDataUnit(DCTHuffTable *dcHuffTable,
114
+			       DCTHuffTable *acHuffTable,
115
+			       int *prevDC, int data[64]);
116
+  void decodeImage();
117
+  void transformDataUnit(uchar *quantTable,
118
+			 int dataIn[64], uchar dataOut[64]);
119
+  int readHuffSym(DCTHuffTable *table);
120
+  int readAmp(int size);
121
+  int readBit();
122
+  bool readHeader();
123
+  bool readBaselineSOF();
124
+  bool readProgressiveSOF();
125
+  bool readScanInfo();
126
+  bool readQuantTables();
127
+  bool readHuffmanTables();
128
+  bool readRestartInterval();
129
+  bool readAdobeMarker();
130
+  bool readTrailer();
131
+  int readMarker();
132
+  int read16();
133
+};
134
+
135
+// --------------------------------------------------------------------
136
+
137
+// IDCT constants (20.12 fixed point format)
138
+#define dctCos1    4017		// cos(pi/16)
139
+#define dctSin1     799		// sin(pi/16)
140
+#define dctCos3    3406		// cos(3*pi/16)
141
+#define dctSin3    2276		// sin(3*pi/16)
142
+#define dctCos6    1567		// cos(6*pi/16)
143
+#define dctSin6    3784		// sin(6*pi/16)
144
+#define dctSqrt2   5793		// sqrt(2)
145
+#define dctSqrt1d2 2896		// sqrt(2) / 2
146
+
147
+// color conversion parameters (16.16 fixed point format)
148
+#define dctCrToR   91881	//  1.4020
149
+#define dctCbToG  -22553	// -0.3441363
150
+#define dctCrToG  -46802	// -0.71413636
151
+#define dctCbToB  116130	//  1.772
152
+
153
+// clip [-256,511] --> [0,255]
154
+#define dctClipOffset 256
155
+static uchar dctClip[768];
156
+static int dctClipInit = 0;
157
+
158
+// zig zag decode map
159
+static int dctZigZag[64] = {
160
+   0,
161
+   1,  8,
162
+  16,  9,  2,
163
+   3, 10, 17, 24,
164
+  32, 25, 18, 11, 4,
165
+   5, 12, 19, 26, 33, 40,
166
+  48, 41, 34, 27, 20, 13,  6,
167
+   7, 14, 21, 28, 35, 42, 49, 56,
168
+  57, 50, 43, 36, 29, 22, 15,
169
+  23, 30, 37, 44, 51, 58,
170
+  59, 52, 45, 38, 31,
171
+  39, 46, 53, 60,
172
+  61, 54, 47,
173
+  55, 62,
174
+  63
175
+};
176
+
177
+// --------------------------------------------------------------------
178
+
179
+DCTStream::DCTStream(DataSource &source)
180
+  : iSource(source)
181
+{
182
+  int i, j;
183
+
184
+  progressive = interleaved = false;
185
+  width = height = 0;
186
+  mcuWidth = mcuHeight = 0;
187
+  numComps = 0;
188
+  comp = 0;
189
+  x = y = dy = 0;
190
+  for (i = 0; i < 4; ++i) {
191
+    for (j = 0; j < 32; ++j) {
192
+      rowBuf[i][j] = 0;
193
+    }
194
+    frameBuf[i] = 0;
195
+  }
196
+
197
+  if (!dctClipInit) {
198
+    for (i = -256; i < 0; ++i)
199
+      dctClip[dctClipOffset + i] = 0;
200
+    for (i = 0; i < 256; ++i)
201
+      dctClip[dctClipOffset + i] = uchar(i);
202
+    for (i = 256; i < 512; ++i)
203
+      dctClip[dctClipOffset + i] = 255;
204
+    dctClipInit = 1;
205
+  }
206
+}
207
+
208
+DCTStream::~DCTStream()
209
+{
210
+  int i, j;
211
+  if (progressive || !interleaved) {
212
+    for (i = 0; i < numComps; ++i) {
213
+      delete [] frameBuf[i];
214
+    }
215
+  } else {
216
+    for (i = 0; i < numComps; ++i) {
217
+      for (j = 0; j < mcuHeight; ++j) {
218
+	delete [] rowBuf[i][j];
219
+      }
220
+    }
221
+  }
222
+}
223
+
224
+void DCTStream::reset()
225
+{
226
+  int minHSample, minVSample;
227
+  int i, j;
228
+
229
+  progressive = interleaved = false;
230
+  width = height = 0;
231
+  numComps = 0;
232
+  numQuantTables = 0;
233
+  numDCHuffTables = 0;
234
+  numACHuffTables = 0;
235
+  colorXform = 0;
236
+  gotAdobeMarker = false;
237
+  restartInterval = 0;
238
+
239
+  if (!readHeader()) {
240
+    y = height;
241
+    return;
242
+  }
243
+
244
+  // compute MCU size
245
+  mcuWidth = minHSample = compInfo[0].hSample;
246
+  mcuHeight = minVSample = compInfo[0].vSample;
247
+  for (i = 1; i < numComps; ++i) {
248
+    if (compInfo[i].hSample < minHSample)
249
+      minHSample = compInfo[i].hSample;
250
+    if (compInfo[i].vSample < minVSample)
251
+      minVSample = compInfo[i].vSample;
252
+    if (compInfo[i].hSample > mcuWidth)
253
+      mcuWidth = compInfo[i].hSample;
254
+    if (compInfo[i].vSample > mcuHeight)
255
+      mcuHeight = compInfo[i].vSample;
256
+  }
257
+  for (i = 0; i < numComps; ++i) {
258
+    compInfo[i].hSample /= minHSample;
259
+    compInfo[i].vSample /= minVSample;
260
+  }
261
+  mcuWidth = (mcuWidth / minHSample) * 8;
262
+  mcuHeight = (mcuHeight / minVSample) * 8;
263
+
264
+  // figure out color transform
265
+  if (!gotAdobeMarker && numComps == 3) {
266
+    if (compInfo[0].id == 1 && compInfo[1].id == 2 && compInfo[2].id == 3) {
267
+      colorXform = 1;
268
+    }
269
+  }
270
+
271
+  if (progressive || !interleaved) {
272
+
273
+    // allocate a buffer for the whole image
274
+    bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
275
+    bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight;
276
+    for (i = 0; i < numComps; ++i) {
277
+      frameBuf[i] = new int[bufWidth * bufHeight];
278
+      memset(frameBuf[i], 0, bufWidth * bufHeight * sizeof(int));
279
+    }
280
+
281
+    // read the image data
282
+    do {
283
+      restartMarker = 0xd0;
284
+      restart();
285
+      readScan();
286
+    } while (readHeader());
287
+
288
+    // decode
289
+    decodeImage();
290
+
291
+    // initialize counters
292
+    comp = 0;
293
+    x = 0;
294
+    y = 0;
295
+
296
+  } else {
297
+
298
+    // allocate a buffer for one row of MCUs
299
+    bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
300
+    for (i = 0; i < numComps; ++i) {
301
+      for (j = 0; j < mcuHeight; ++j) {
302
+	rowBuf[i][j] = new uchar[bufWidth];
303
+      }
304
+    }
305
+
306
+    // initialize counters
307
+    comp = 0;
308
+    x = 0;
309
+    y = 0;
310
+    dy = mcuHeight;
311
+
312
+    restartMarker = 0xd0;
313
+    restart();
314
+  }
315
+}
316
+
317
+int DCTStream::getChar()
318
+{
319
+  int c;
320
+
321
+  if (y >= height) {
322
+    return EOF;
323
+  }
324
+  if (progressive || !interleaved) {
325
+    c = frameBuf[comp][y * bufWidth + x];
326
+    if (++comp == numComps) {
327
+      comp = 0;
328
+      if (++x == width) {
329
+	x = 0;
330
+	++y;
331
+      }
332
+    }
333
+  } else {
334
+    if (dy >= mcuHeight) {
335
+      if (!readMCURow()) {
336
+	y = height;
337
+	return EOF;
338
+      }
339
+      comp = 0;
340
+      x = 0;
341
+      dy = 0;
342
+    }
343
+    c = rowBuf[comp][dy][x];
344
+    if (++comp == numComps) {
345
+      comp = 0;
346
+      if (++x == width) {
347
+	x = 0;
348
+	++y;
349
+	++dy;
350
+	if (y == height) {
351
+	  readTrailer();
352
+	}
353
+      }
354
+    }
355
+  }
356
+  return c;
357
+}
358
+
359
+void DCTStream::restart()
360
+{
361
+  int i;
362
+
363
+  inputBits = 0;
364
+  restartCtr = restartInterval;
365
+  for (i = 0; i < numComps; ++i) {
366
+    compInfo[i].prevDC = 0;
367
+  }
368
+  eobRun = 0;
369
+}
370
+
371
+// Read one row of MCUs from a sequential JPEG stream.
372
+bool DCTStream::readMCURow()
373
+{
374
+  int data1[64];
375
+  uchar data2[64];
376
+  uchar *p1, *p2;
377
+  int pY, pCb, pCr, pR, pG, pB;
378
+  int h, v, horiz, vert, hSub, vSub;
379
+  int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
380
+  int c;
381
+
382
+  for (x1 = 0; x1 < width; x1 += mcuWidth) {
383
+
384
+    // deal with restart marker
385
+    if (restartInterval > 0 && restartCtr == 0) {
386
+      c = readMarker();
387
+      if (c != restartMarker) {
388
+	ipeDebug("Bad DCT data: incorrect restart marker");
389
+	return false;
390
+      }
391
+      if (++restartMarker == 0xd8)
392
+	restartMarker = 0xd0;
393
+      restart();
394
+    }
395
+
396
+    // read one MCU
397
+    for (cc = 0; cc < numComps; ++cc) {
398
+      h = compInfo[cc].hSample;
399
+      v = compInfo[cc].vSample;
400
+      horiz = mcuWidth / h;
401
+      vert = mcuHeight / v;
402
+      hSub = horiz / 8;
403
+      vSub = vert / 8;
404
+      for (y2 = 0; y2 < mcuHeight; y2 += vert) {
405
+	for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
406
+	  if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]],
407
+			    &acHuffTables[scanInfo.acHuffTable[cc]],
408
+			    &compInfo[cc].prevDC,
409
+			    data1)) {
410
+	    return false;
411
+	  }
412
+	  transformDataUnit(quantTables[compInfo[cc].quantTable],
413
+			    data1, data2);
414
+	  if (hSub == 1 && vSub == 1) {
415
+	    for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
416
+	      p1 = &rowBuf[cc][y2+y3][x1+x2];
417
+	      p1[0] = data2[i];
418
+	      p1[1] = data2[i+1];
419
+	      p1[2] = data2[i+2];
420
+	      p1[3] = data2[i+3];
421
+	      p1[4] = data2[i+4];
422
+	      p1[5] = data2[i+5];
423
+	      p1[6] = data2[i+6];
424
+	      p1[7] = data2[i+7];
425
+	    }
426
+	  } else if (hSub == 2 && vSub == 2) {
427
+	    for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
428
+	      p1 = &rowBuf[cc][y2+y3][x1+x2];
429
+	      p2 = &rowBuf[cc][y2+y3+1][x1+x2];
430
+	      p1[0] = p1[1] = p2[0] = p2[1] = data2[i];
431
+	      p1[2] = p1[3] = p2[2] = p2[3] = data2[i+1];
432
+	      p1[4] = p1[5] = p2[4] = p2[5] = data2[i+2];
433
+	      p1[6] = p1[7] = p2[6] = p2[7] = data2[i+3];
434
+	      p1[8] = p1[9] = p2[8] = p2[9] = data2[i+4];
435
+	      p1[10] = p1[11] = p2[10] = p2[11] = data2[i+5];
436
+	      p1[12] = p1[13] = p2[12] = p2[13] = data2[i+6];
437
+	      p1[14] = p1[15] = p2[14] = p2[15] = data2[i+7];
438
+	    }
439
+	  } else {
440
+	    i = 0;
441
+	    for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
442
+	      for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
443
+		for (y5 = 0; y5 < vSub; ++y5)
444
+		  for (x5 = 0; x5 < hSub; ++x5)
445
+		    rowBuf[cc][y2+y4+y5][x1+x2+x4+x5] = data2[i];
446
+		++i;
447
+	      }
448
+	    }
449
+	  }
450
+	}
451
+      }
452
+    }
453
+    --restartCtr;
454
+
455
+    // color space conversion
456
+    if (colorXform) {
457
+      // convert YCbCr to RGB
458
+      if (numComps == 3) {
459
+	for (y2 = 0; y2 < mcuHeight; ++y2) {
460
+	  for (x2 = 0; x2 < mcuWidth; ++x2) {
461
+	    pY = rowBuf[0][y2][x1+x2];
462
+	    pCb = rowBuf[1][y2][x1+x2] - 128;
463
+	    pCr = rowBuf[2][y2][x1+x2] - 128;
464
+	    pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
465
+	    rowBuf[0][y2][x1+x2] = dctClip[dctClipOffset + pR];
466
+	    pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
467
+	    rowBuf[1][y2][x1+x2] = dctClip[dctClipOffset + pG];
468
+	    pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
469
+	    rowBuf[2][y2][x1+x2] = dctClip[dctClipOffset + pB];
470
+	  }
471
+	}
472
+      // convert YCbCrK to CMYK (K is passed through unchanged)
473
+      } else if (numComps == 4) {
474
+	for (y2 = 0; y2 < mcuHeight; ++y2) {
475
+	  for (x2 = 0; x2 < mcuWidth; ++x2) {
476
+	    pY = rowBuf[0][y2][x1+x2];
477
+	    pCb = rowBuf[1][y2][x1+x2] - 128;
478
+	    pCr = rowBuf[2][y2][x1+x2] - 128;
479
+	    pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
480
+	    rowBuf[0][y2][x1+x2] = uchar(255 - dctClip[dctClipOffset + pR]);
481
+	    pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
482
+	    rowBuf[1][y2][x1+x2] = uchar(255 - dctClip[dctClipOffset + pG]);
483
+	    pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
484
+	    rowBuf[2][y2][x1+x2] = uchar(255 - dctClip[dctClipOffset + pB]);
485
+	  }
486
+	}
487
+      }
488
+    }
489
+  }
490
+  return true;
491
+}
492
+
493
+// Read one scan from a progressive or non-interleaved JPEG stream.
494
+void DCTStream::readScan()
495
+{
496
+  int data[64];
497
+  int x1, y1, dy1, x2, y2, y3, cc, i;
498
+  int h, v, horiz, vert, vSub;
499
+  int *p1;
500
+  int c;
501
+
502
+  if (scanInfo.numComps == 1) {
503
+    for (cc = 0; cc < numComps; ++cc) {
504
+      if (scanInfo.comp[cc]) {
505
+	break;
506
+      }
507
+    }
508
+    dy1 = mcuHeight / compInfo[cc].vSample;
509
+  } else {
510
+    dy1 = mcuHeight;
511
+  }
512
+
513
+  for (y1 = 0; y1 < bufHeight; y1 += dy1) {
514
+    for (x1 = 0; x1 < bufWidth; x1 += mcuWidth) {
515
+
516
+      // deal with restart marker
517
+      if (restartInterval > 0 && restartCtr == 0) {
518
+	c = readMarker();
519
+	if (c != restartMarker) {
520
+	  ipeDebug("Bad DCT data: incorrect restart marker");
521
+	  return;
522
+	}
523
+	if (++restartMarker == 0xd8) {
524
+	  restartMarker = 0xd0;
525
+	}
526
+	restart();
527
+      }
528
+
529
+      // read one MCU
530
+      for (cc = 0; cc < numComps; ++cc) {
531
+	if (!scanInfo.comp[cc]) {
532
+	  continue;
533
+	}
534
+
535
+	h = compInfo[cc].hSample;
536
+	v = compInfo[cc].vSample;
537
+	horiz = mcuWidth / h;
538
+	vert = mcuHeight / v;
539
+	// hSub = horiz / 8;
540
+	vSub = vert / 8;
541
+	for (y2 = 0; y2 < dy1; y2 += vert) {
542
+	  for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
543
+
544
+	    // pull out the current values
545
+	    p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
546
+	    for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
547
+	      data[i] = p1[0];
548
+	      data[i+1] = p1[1];
549
+	      data[i+2] = p1[2];
550
+	      data[i+3] = p1[3];
551
+	      data[i+4] = p1[4];
552
+	      data[i+5] = p1[5];
553
+	      data[i+6] = p1[6];
554
+	      data[i+7] = p1[7];
555
+	      p1 += bufWidth * vSub;
556
+	    }
557
+
558
+	    // read one data unit
559
+	    if (progressive) {
560
+	      if (!readProgressiveDataUnit(
561
+		       &dcHuffTables[scanInfo.dcHuffTable[cc]],
562
+		       &acHuffTables[scanInfo.acHuffTable[cc]],
563
+		       &compInfo[cc].prevDC,
564
+		       data)) {
565
+		return;
566
+	      }
567
+	    } else {
568
+	      if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]],
569
+				&acHuffTables[scanInfo.acHuffTable[cc]],
570
+				&compInfo[cc].prevDC,
571
+				data)) {
572
+		return;
573
+	      }
574
+	    }
575
+
576
+	    // add the data unit into frameBuf
577
+	    p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
578
+	    for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
579
+	      p1[0] = data[i];
580
+	      p1[1] = data[i+1];
581
+	      p1[2] = data[i+2];
582
+	      p1[3] = data[i+3];
583
+	      p1[4] = data[i+4];
584
+	      p1[5] = data[i+5];
585
+	      p1[6] = data[i+6];
586
+	      p1[7] = data[i+7];
587
+	      p1 += bufWidth * vSub;
588
+	    }
589
+	  }
590
+	}
591
+      }
592
+      --restartCtr;
593
+    }
594
+  }
595
+}
596
+
597
+// Read one data unit from a sequential JPEG stream.
598
+bool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
599
+			     DCTHuffTable *acHuffTable,
600
+			     int *prevDC, int data[64])
601
+{
602
+  int run, size, amp;
603
+  int c;
604
+  int i, j;
605
+
606
+  if ((size = readHuffSym(dcHuffTable)) == 9999) {
607
+    return false;
608
+  }
609
+  if (size > 0) {
610
+    if ((amp = readAmp(size)) == 9999) {
611
+      return false;
612
+    }
613
+  } else {
614
+    amp = 0;
615
+  }
616
+  data[0] = *prevDC += amp;
617
+  for (i = 1; i < 64; ++i) {
618
+    data[i] = 0;
619
+  }
620
+  i = 1;
621
+  while (i < 64) {
622
+    run = 0;
623
+    while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30) {
624
+      run += 0x10;
625
+    }
626
+    if (c == 9999) {
627
+      return false;
628
+    }
629
+    if (c == 0x00) {
630
+      break;
631
+    } else {
632
+      run += (c >> 4) & 0x0f;
633
+      size = c & 0x0f;
634
+      amp = readAmp(size);
635
+      if (amp == 9999) {
636
+	return false;
637
+      }
638
+      i += run;
639
+      j = dctZigZag[i++];
640
+      data[j] = amp;
641
+    }
642
+  }
643
+  return true;
644
+}
645
+
646
+// Read one data unit from a sequential JPEG stream.
647
+bool DCTStream::readProgressiveDataUnit(DCTHuffTable *dcHuffTable,
648
+					DCTHuffTable *acHuffTable,
649
+					int *prevDC, int data[64])
650
+{
651
+  int run, size, amp, bit, c;
652
+  int i, j, k;
653
+
654
+  // get the DC coefficient
655
+  i = scanInfo.firstCoeff;
656
+  if (i == 0) {
657
+    if (scanInfo.ah == 0) {
658
+      if ((size = readHuffSym(dcHuffTable)) == 9999) {
659
+	return false;
660
+      }
661
+      if (size > 0) {
662
+	if ((amp = readAmp(size)) == 9999) {
663
+	  return false;
664
+	}
665
+      } else {
666
+	amp = 0;
667
+      }
668
+      data[0] += (*prevDC += amp) << scanInfo.al;
669
+    } else {
670
+      if ((bit = readBit()) == 9999) {
671
+	return false;
672
+      }
673
+      data[0] += bit << scanInfo.al;
674
+    }
675
+    ++i;
676
+  }
677
+  if (scanInfo.lastCoeff == 0) {
678
+    return true;
679
+  }
680
+
681
+  // check for an EOB run
682
+  if (eobRun > 0) {
683
+    while (i <= scanInfo.lastCoeff) {
684
+      j = dctZigZag[i++];
685
+      if (data[j] != 0) {
686
+	if ((bit = readBit()) == EOF) {
687
+	  return false;
688
+	}
689
+	if (bit) {
690
+	  data[j] += 1 << scanInfo.al;
691
+	}
692
+      }
693
+    }
694
+    --eobRun;
695
+    return true;
696
+  }
697
+
698
+  // read the AC coefficients
699
+  while (i <= scanInfo.lastCoeff) {
700
+    if ((c = readHuffSym(acHuffTable)) == 9999) {
701
+      return false;
702
+    }
703
+
704
+    // ZRL
705
+    if (c == 0xf0) {
706
+      k = 0;
707
+      while (k < 16) {
708
+	j = dctZigZag[i++];
709
+	if (data[j] == 0) {
710
+	  ++k;
711
+	} else {
712
+	  if ((bit = readBit()) == EOF) {
713
+	    return false;
714
+	  }
715
+	  if (bit) {
716
+	    data[j] += 1 << scanInfo.al;
717
+	  }
718
+	}
719
+      }
720
+
721
+    // EOB run
722
+    } else if ((c & 0x0f) == 0x00) {
723
+      j = c >> 4;
724
+      eobRun = 0;
725
+      for (k = 0; k < j; ++k) {
726
+	if ((bit = readBit()) == EOF) {
727
+	  return 9999;
728
+	}
729
+	eobRun = (eobRun << 1) | bit;
730
+      }
731
+      eobRun += 1 << j;
732
+      while (i <= scanInfo.lastCoeff) {
733
+	j = dctZigZag[i++];
734
+	if (data[j] != 0) {
735
+	  if ((bit = readBit()) == EOF) {
736
+	    return false;
737
+	  }
738
+	  if (bit) {
739
+	    data[j] += 1 << scanInfo.al;
740
+	  }
741
+	}
742
+      }
743
+      --eobRun;
744
+      break;
745
+
746
+    // zero run and one AC coefficient
747
+    } else {
748
+      run = (c >> 4) & 0x0f;
749
+      size = c & 0x0f;
750
+      if ((amp = readAmp(size)) == 9999) {
751
+	return false;
752
+      }
753
+      k = 0;
754
+      do {
755
+	j = dctZigZag[i++];
756
+	while (data[j] != 0) {
757
+	  if ((bit = readBit()) == EOF) {
758
+	    return false;
759
+	  }
760
+	  if (bit) {
761
+	    data[j] += 1 << scanInfo.al;
762
+	  }
763
+	  j = dctZigZag[i++];
764
+	}
765
+	++k;
766
+      } while (k <= run);
767
+      data[j] = amp << scanInfo.al;
768
+    }
769
+  }
770
+
771
+  return true;
772
+}
773
+
774
+// Decode a progressive JPEG image.
775
+void DCTStream::decodeImage()
776
+{
777
+  int dataIn[64];
778
+  uchar dataOut[64];
779
+  uchar *quantTable;
780
+  int pY, pCb, pCr, pR, pG, pB;
781
+  int x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
782
+  int h, v, horiz, vert, hSub, vSub;
783
+  int *p0, *p1, *p2;
784
+
785
+  for (y1 = 0; y1 < bufHeight; y1 += mcuHeight) {
786
+    for (x1 = 0; x1 < bufWidth; x1 += mcuWidth) {
787
+      for (cc = 0; cc < numComps; ++cc) {
788
+	quantTable = quantTables[compInfo[cc].quantTable];
789
+	h = compInfo[cc].hSample;
790
+	v = compInfo[cc].vSample;
791
+	horiz = mcuWidth / h;
792
+	vert = mcuHeight / v;
793
+	hSub = horiz / 8;
794
+	vSub = vert / 8;
795
+	for (y2 = 0; y2 < mcuHeight; y2 += vert) {
796
+	  for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
797
+
798
+	    // pull out the coded data unit
799
+	    p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
800
+	    for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
801
+	      dataIn[i]   = p1[0];
802
+	      dataIn[i+1] = p1[1];
803
+	      dataIn[i+2] = p1[2];
804
+	      dataIn[i+3] = p1[3];
805
+	      dataIn[i+4] = p1[4];
806
+	      dataIn[i+5] = p1[5];
807
+	      dataIn[i+6] = p1[6];
808
+	      dataIn[i+7] = p1[7];
809
+	      p1 += bufWidth * vSub;
810
+	    }
811
+
812
+	    // transform
813
+	    transformDataUnit(quantTable, dataIn, dataOut);
814
+
815
+	    // store back into frameBuf, doing replication for
816
+	    // subsampled components
817
+	    p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
818
+	    if (hSub == 1 && vSub == 1) {
819
+	      for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
820
+		p1[0] = dataOut[i] & 0xff;
821
+		p1[1] = dataOut[i+1] & 0xff;
822
+		p1[2] = dataOut[i+2] & 0xff;
823
+		p1[3] = dataOut[i+3] & 0xff;
824
+		p1[4] = dataOut[i+4] & 0xff;
825
+		p1[5] = dataOut[i+5] & 0xff;
826
+		p1[6] = dataOut[i+6] & 0xff;
827
+		p1[7] = dataOut[i+7] & 0xff;
828
+		p1 += bufWidth;
829
+	      }
830
+	    } else if (hSub == 2 && vSub == 2) {
831
+	      p2 = p1 + bufWidth;
832
+	      for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
833
+		p1[0] = p1[1] = p2[0] = p2[1] = dataOut[i] & 0xff;
834
+		p1[2] = p1[3] = p2[2] = p2[3] = dataOut[i+1] & 0xff;
835
+		p1[4] = p1[5] = p2[4] = p2[5] = dataOut[i+2] & 0xff;
836
+		p1[6] = p1[7] = p2[6] = p2[7] = dataOut[i+3] & 0xff;
837
+		p1[8] = p1[9] = p2[8] = p2[9] = dataOut[i+4] & 0xff;
838
+		p1[10] = p1[11] = p2[10] = p2[11] = dataOut[i+5] & 0xff;
839
+		p1[12] = p1[13] = p2[12] = p2[13] = dataOut[i+6] & 0xff;
840
+		p1[14] = p1[15] = p2[14] = p2[15] = dataOut[i+7] & 0xff;
841
+		p1 += bufWidth * 2;
842
+		p2 += bufWidth * 2;
843
+	      }
844
+	    } else {
845
+	      i = 0;
846
+	      for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
847
+		for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
848
+		  p2 = p1 + x4;
849
+		  for (y5 = 0; y5 < vSub; ++y5) {
850
+		    for (x5 = 0; x5 < hSub; ++x5) {
851
+		      p2[x5] = dataOut[i] & 0xff;
852
+		    }
853
+		    p2 += bufWidth;
854
+		  }
855
+		  ++i;
856
+		}
857
+		p1 += bufWidth * vSub;
858
+	      }
859
+	    }
860
+	  }
861
+	}
862
+      }
863
+
864
+      // color space conversion
865
+      if (colorXform) {
866
+	// convert YCbCr to RGB
867
+	if (numComps == 3) {
868
+	  for (y2 = 0; y2 < mcuHeight; ++y2) {
869
+	    p0 = &frameBuf[0][(y1+y2) * bufWidth + x1];
870
+	    p1 = &frameBuf[1][(y1+y2) * bufWidth + x1];
871
+	    p2 = &frameBuf[2][(y1+y2) * bufWidth + x1];
872
+	    for (x2 = 0; x2 < mcuWidth; ++x2) {
873
+	      pY = *p0;
874
+	      pCb = *p1 - 128;
875
+	      pCr = *p2 - 128;
876
+	      pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
877
+	      *p0++ = dctClip[dctClipOffset + pR];
878
+	      pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr +
879
+		    32768) >> 16;
880
+	      *p1++ = dctClip[dctClipOffset + pG];
881
+	      pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
882
+	      *p2++ = dctClip[dctClipOffset + pB];
883
+	    }
884
+	  }
885
+	// convert YCbCrK to CMYK (K is passed through unchanged)
886
+	} else if (numComps == 4) {
887
+	  for (y2 = 0; y2 < mcuHeight; ++y2) {
888
+	    p0 = &frameBuf[0][(y1+y2) * bufWidth + x1];
889
+	    p1 = &frameBuf[1][(y1+y2) * bufWidth + x1];
890
+	    p2 = &frameBuf[2][(y1+y2) * bufWidth + x1];
891
+	    for (x2 = 0; x2 < mcuWidth; ++x2) {
892
+	      pY = *p0;
893
+	      pCb = *p1 - 128;
894
+	      pCr = *p2 - 128;
895
+	      pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
896
+	      *p0++ = 255 - dctClip[dctClipOffset + pR];
897
+	      pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr +
898
+		    32768) >> 16;
899
+	      *p1++ = 255 - dctClip[dctClipOffset + pG];
900
+	      pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
901
+	      *p2++ = 255 - dctClip[dctClipOffset + pB];
902
+	    }
903
+	  }
904
+	}
905
+      }
906
+    }
907
+  }
908
+}
909
+
910
+// Transform one data unit -- this performs the dequantization and
911
+// IDCT steps.  This IDCT algorithm is taken from:
912
+//   Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
913
+//   "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
914
+//   IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
915
+//   988-991.
916
+// The stage numbers mentioned in the comments refer to Figure 1 in this
917
+// paper.
918
+void DCTStream::transformDataUnit(uchar *quantTable,
919
+				  int dataIn[64], uchar dataOut[64])
920
+{
921
+  int v0, v1, v2, v3, v4, v5, v6, v7, t;
922
+  int *p;
923
+  int i;
924
+
925
+  // dequant
926
+  for (i = 0; i < 64; ++i) {
927
+    dataIn[i] *= quantTable[i];
928
+  }
929
+
930
+  // inverse DCT on rows
931
+  for (i = 0; i < 64; i += 8) {
932
+    p = dataIn + i;
933
+
934
+    // check for all-zero AC coefficients
935
+    if (p[1] == 0 && p[2] == 0 && p[3] == 0 &&
936
+	p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] == 0) {
937
+      t = (dctSqrt2 * p[0] + 512) >> 10;
938
+      p[0] = t;
939
+      p[1] = t;
940
+      p[2] = t;
941
+      p[3] = t;
942
+      p[4] = t;
943
+      p[5] = t;
944
+      p[6] = t;
945
+      p[7] = t;
946
+      continue;
947
+    }
948
+
949
+    // stage 4
950
+    v0 = (dctSqrt2 * p[0] + 128) >> 8;
951
+    v1 = (dctSqrt2 * p[4] + 128) >> 8;
952
+    v2 = p[2];
953
+    v3 = p[6];
954
+    v4 = (dctSqrt1d2 * (p[1] - p[7]) + 128) >> 8;
955
+    v7 = (dctSqrt1d2 * (p[1] + p[7]) + 128) >> 8;
956
+    v5 = p[3] << 4;
957
+    v6 = p[5] << 4;
958
+
959
+    // stage 3
960
+    t = (v0 - v1+ 1) >> 1;
961
+    v0 = (v0 + v1 + 1) >> 1;
962
+    v1 = t;
963
+    t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
964
+    v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8;
965
+    v3 = t;
966
+    t = (v4 - v6 + 1) >> 1;
967
+    v4 = (v4 + v6 + 1) >> 1;
968
+    v6 = t;
969
+    t = (v7 + v5 + 1) >> 1;
970
+    v5 = (v7 - v5 + 1) >> 1;
971
+    v7 = t;
972
+
973
+    // stage 2
974
+    t = (v0 - v3 + 1) >> 1;
975
+    v0 = (v0 + v3 + 1) >> 1;
976
+    v3 = t;
977
+    t = (v1 - v2 + 1) >> 1;
978
+    v1 = (v1 + v2 + 1) >> 1;
979
+    v2 = t;
980
+    t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
981
+    v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
982
+    v7 = t;
983
+    t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
984
+    v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
985
+    v6 = t;
986
+
987
+    // stage 1
988
+    p[0] = v0 + v7;
989
+    p[7] = v0 - v7;
990
+    p[1] = v1 + v6;
991
+    p[6] = v1 - v6;
992
+    p[2] = v2 + v5;
993
+    p[5] = v2 - v5;
994
+    p[3] = v3 + v4;
995
+    p[4] = v3 - v4;
996
+  }
997
+
998
+  // inverse DCT on columns
999
+  for (i = 0; i < 8; ++i) {
1000
+    p = dataIn + i;
1001
+
1002
+    // check for all-zero AC coefficients
1003
+    if (p[1*8] == 0 && p[2*8] == 0 && p[3*8] == 0 &&
1004
+	p[4*8] == 0 && p[5*8] == 0 && p[6*8] == 0 && p[7*8] == 0) {
1005
+      t = (dctSqrt2 * dataIn[i+0] + 8192) >> 14;
1006
+      p[0*8] = t;
1007
+      p[1*8] = t;
1008
+      p[2*8] = t;
1009
+      p[3*8] = t;
1010
+      p[4*8] = t;
1011
+      p[5*8] = t;
1012
+      p[6*8] = t;
1013
+      p[7*8] = t;
1014
+      continue;
1015
+    }
1016
+
1017
+    // stage 4
1018
+    v0 = (dctSqrt2 * p[0*8] + 2048) >> 12;
1019
+    v1 = (dctSqrt2 * p[4*8] + 2048) >> 12;
1020
+    v2 = p[2*8];
1021
+    v3 = p[6*8];
1022
+    v4 = (dctSqrt1d2 * (p[1*8] - p[7*8]) + 2048) >> 12;
1023
+    v7 = (dctSqrt1d2 * (p[1*8] + p[7*8]) + 2048) >> 12;
1024
+    v5 = p[3*8];
1025
+    v6 = p[5*8];
1026
+
1027
+    // stage 3
1028
+    t = (v0 - v1 + 1) >> 1;
1029
+    v0 = (v0 + v1 + 1) >> 1;
1030
+    v1 = t;
1031
+    t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
1032
+    v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12;
1033
+    v3 = t;
1034
+    t = (v4 - v6 + 1) >> 1;
1035
+    v4 = (v4 + v6 + 1) >> 1;
1036
+    v6 = t;
1037
+    t = (v7 + v5 + 1) >> 1;
1038
+    v5 = (v7 - v5 + 1) >> 1;
1039
+    v7 = t;
1040
+
1041
+    // stage 2
1042
+    t = (v0 - v3 + 1) >> 1;
1043
+    v0 = (v0 + v3 + 1) >> 1;
1044
+    v3 = t;
1045
+    t = (v1 - v2 + 1) >> 1;
1046
+    v1 = (v1 + v2 + 1) >> 1;
1047
+    v2 = t;
1048
+    t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
1049
+    v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
1050
+    v7 = t;
1051
+    t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
1052
+    v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
1053
+    v6 = t;
1054
+
1055
+    // stage 1
1056
+    p[0*8] = v0 + v7;
1057
+    p[7*8] = v0 - v7;
1058
+    p[1*8] = v1 + v6;
1059
+    p[6*8] = v1 - v6;
1060
+    p[2*8] = v2 + v5;
1061
+    p[5*8] = v2 - v5;
1062
+    p[3*8] = v3 + v4;
1063
+    p[4*8] = v3 - v4;
1064
+  }
1065
+
1066
+  // convert to 8-bit integers
1067
+  for (i = 0; i < 64; ++i) {
1068
+    dataOut[i] = dctClip[dctClipOffset + 128 + ((dataIn[i] + 8) >> 4)];
1069
+  }
1070
+}
1071
+
1072
+int DCTStream::readHuffSym(DCTHuffTable *table)
1073
+{
1074
+  ushort code;
1075
+  int bit;
1076
+  int codeBits;
1077
+
1078
+  code = 0;
1079
+  codeBits = 0;
1080
+  do {
1081
+    // add a bit to the code
1082
+    if ((bit = readBit()) == EOF)
1083
+      return 9999;
1084
+    code = ushort((code << 1) + bit);
1085
+    ++codeBits;
1086
+
1087
+    // look up code
1088
+    if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
1089
+      code -= table->firstCode[codeBits];
1090
+      return table->sym[table->firstSym[codeBits] + code];
1091
+    }
1092
+  } while (codeBits < 16);
1093
+
1094
+  ipeDebug("Bad Huffman code in DCT stream");
1095
+  return 9999;
1096
+}
1097
+
1098
+int DCTStream::readAmp(int size)
1099
+{
1100
+  int amp, bit;
1101
+  int bits;
1102
+
1103
+  amp = 0;
1104
+  for (bits = 0; bits < size; ++bits) {
1105
+    if ((bit = readBit()) == EOF)
1106
+      return 9999;
1107
+    amp = (amp << 1) + bit;
1108
+  }
1109
+  if (amp < (1 << (size - 1)))
1110
+    amp -= (1 << size) - 1;
1111
+  return amp;
1112
+}
1113
+
1114
+int DCTStream::readBit()
1115
+{
1116
+  int bit;
1117
+  int c, c2;
1118
+
1119
+  if (inputBits == 0) {
1120
+    if ((c = iSource.getChar()) == EOF)
1121
+      return EOF;
1122
+    if (c == 0xff) {
1123
+      do {
1124
+	c2 = iSource.getChar();
1125
+      } while (c2 == 0xff);
1126
+      if (c2 != 0x00) {
1127
+	ipeDebug("Bad DCT data: missing 00 after ff");
1128
+	return EOF;
1129
+      }
1130
+    }
1131
+    inputBuf = c;
1132
+    inputBits = 8;
1133
+  }
1134
+  bit = (inputBuf >> (inputBits - 1)) & 1;
1135
+  --inputBits;
1136
+  return bit;
1137
+}
1138
+
1139
+bool DCTStream::readHeader()
1140
+{
1141
+  bool doScan;
1142
+  int n;
1143
+  int c;
1144
+  int i;
1145
+
1146
+  // read headers
1147
+  doScan = false;
1148
+  while (!doScan) {
1149
+    c = readMarker();
1150
+    switch (c) {
1151
+    case 0xc0:			// SOF0
1152
+      if (!readBaselineSOF()) {
1153
+	return false;
1154
+      }
1155
+      break;
1156
+    case 0xc2:			// SOF2
1157
+      if (!readProgressiveSOF()) {
1158
+	return false;
1159
+      }
1160
+      break;
1161
+    case 0xc4:			// DHT
1162
+      if (!readHuffmanTables()) {
1163
+	return false;
1164
+      }
1165
+      break;
1166
+    case 0xd8:			// SOI
1167
+      break;
1168
+    case 0xd9:			// EOI
1169
+      return false;
1170
+    case 0xda:			// SOS
1171
+      if (!readScanInfo()) {
1172
+	return false;
1173
+      }
1174
+      doScan = true;
1175
+      break;
1176
+    case 0xdb:			// DQT
1177
+      if (!readQuantTables()) {
1178
+	return false;
1179
+      }
1180
+      break;
1181
+    case 0xdd:			// DRI
1182
+      if (!readRestartInterval()) {
1183
+	return false;
1184
+      }
1185
+      break;
1186
+    case 0xee:			// APP14
1187
+      if (!readAdobeMarker()) {
1188
+	return false;
1189
+      }
1190
+      break;
1191
+    case EOF:
1192
+      ipeDebug("Bad DCT header");
1193
+      return false;
1194
+    default:
1195
+      // skip APPn / COM / etc.
1196
+      if (c >= 0xe0) {
1197
+	n = read16() - 2;
1198
+	for (i = 0; i < n; ++i) {
1199
+	  iSource.getChar();
1200
+	}
1201
+      } else {
1202
+	ipeDebug("Unknown DCT marker <%02x>", c);
1203
+	return false;
1204
+      }
1205
+      break;
1206
+    }
1207
+  }
1208
+
1209
+  return true;
1210
+}
1211
+
1212
+bool DCTStream::readBaselineSOF()
1213
+{
1214
+  (void) read16(); // length
1215
+  int prec = iSource.getChar();
1216
+  height = read16();
1217
+  width = read16();
1218
+  numComps = iSource.getChar();
1219
+  if (prec != 8) {
1220
+    ipeDebug("Bad DCT precision %d", prec);
1221
+    return false;
1222
+  }
1223
+  for (int i = 0; i < numComps; ++i) {
1224
+    compInfo[i].id = iSource.getChar();
1225
+    int c = iSource.getChar();
1226
+    compInfo[i].hSample = (c >> 4) & 0x0f;
1227
+    compInfo[i].vSample = c & 0x0f;
1228
+    compInfo[i].quantTable = iSource.getChar();
1229
+  }
1230
+  progressive = false;
1231
+  return true;
1232
+}
1233
+
1234
+bool DCTStream::readProgressiveSOF()
1235
+{
1236
+  (void) read16(); // length
1237
+  int prec = iSource.getChar();
1238
+  height = read16();
1239
+  width = read16();
1240
+  numComps = iSource.getChar();
1241
+  if (prec != 8) {
1242
+    ipeDebug("Bad DCT precision %d", prec);
1243
+    return false;
1244
+  }
1245
+  for (int i = 0; i < numComps; ++i) {
1246
+    compInfo[i].id = iSource.getChar();
1247
+    int c = iSource.getChar();
1248
+    compInfo[i].hSample = (c >> 4) & 0x0f;
1249
+    compInfo[i].vSample = c & 0x0f;
1250
+    compInfo[i].quantTable = iSource.getChar();
1251
+  }
1252
+  progressive = true;
1253
+  return true;
1254
+}
1255
+
1256
+bool DCTStream::readScanInfo()
1257
+{
1258
+  int length;
1259
+  int id, c;
1260
+  int i, j;
1261
+
1262
+  length = read16() - 2;
1263
+  scanInfo.numComps = iSource.getChar();
1264
+  --length;
1265
+  if (length != 2 * scanInfo.numComps + 3) {
1266
+    ipeDebug("Bad DCT scan info block");
1267
+    return false;
1268
+  }
1269
+  interleaved = scanInfo.numComps == numComps;
1270
+  for (j = 0; j < numComps; ++j) {
1271
+    scanInfo.comp[j] = false;
1272
+  }
1273
+  for (i = 0; i < scanInfo.numComps; ++i) {
1274
+    id = iSource.getChar();
1275
+    for (j = 0; j < numComps; ++j) {
1276
+      if (id == compInfo[j].id) {
1277
+	break;
1278
+      }
1279
+    }
1280
+    if (j == numComps) {
1281
+      ipeDebug("Bad DCT component ID in scan info block");
1282
+      return false;
1283
+    }
1284
+    scanInfo.comp[j] = true;
1285
+    c = iSource.getChar();
1286
+    scanInfo.dcHuffTable[j] = (c >> 4) & 0x0f;
1287
+    scanInfo.acHuffTable[j] = c & 0x0f;
1288
+  }
1289
+  scanInfo.firstCoeff = iSource.getChar();
1290
+  scanInfo.lastCoeff = iSource.getChar();
1291
+  c = iSource.getChar();
1292
+  scanInfo.ah = (c >> 4) & 0x0f;
1293
+  scanInfo.al = c & 0x0f;
1294
+  return true;
1295
+}
1296
+
1297
+bool DCTStream::readQuantTables()
1298
+{
1299
+  int length;
1300
+  int i;
1301
+  int index;
1302
+
1303
+  length = read16() - 2;
1304
+  while (length > 0) {
1305
+    index = iSource.getChar();
1306
+    if ((index & 0xf0) || index >= 4) {
1307
+      ipeDebug("Bad DCT quantization table");
1308
+      return false;
1309
+    }
1310
+    if (index == numQuantTables)
1311
+      numQuantTables = index + 1;
1312
+    for (i = 0; i < 64; ++i)
1313
+      quantTables[index][dctZigZag[i]] = uchar(iSource.getChar());
1314
+    length -= 65;
1315
+  }
1316
+  return true;
1317
+}
1318
+
1319
+bool DCTStream::readHuffmanTables()
1320
+{
1321
+  DCTHuffTable *tbl;
1322
+  int length;
1323
+  int index;
1324
+  ushort code;
1325
+  uchar sym;
1326
+  int i;
1327
+  int c;
1328
+
1329
+  length = read16() - 2;
1330
+  while (length > 0) {
1331
+    index = iSource.getChar();
1332
+    --length;
1333
+    if ((index & 0x0f) >= 4) {
1334
+      ipeDebug("Bad DCT Huffman table");
1335
+      return false;
1336
+    }
1337
+    if (index & 0x10) {
1338
+      index &= 0x0f;
1339
+      if (index >= numACHuffTables)
1340
+	numACHuffTables = index+1;
1341
+      tbl = &acHuffTables[index];
1342
+    } else {
1343
+      if (index >= numDCHuffTables)
1344
+	numDCHuffTables = index+1;
1345
+      tbl = &dcHuffTables[index];
1346
+    }
1347
+    sym = 0;
1348
+    code = 0;
1349
+    for (i = 1; i <= 16; ++i) {
1350
+      c = iSource.getChar();
1351
+      tbl->firstSym[i] = sym;
1352
+      tbl->firstCode[i] = code;
1353
+      tbl->numCodes[i] = ushort(c);
1354
+      sym += uchar(c);
1355
+      code = ushort((code + c) << 1);
1356
+    }
1357
+    length -= 16;
1358
+    for (i = 0; i < sym; ++i)
1359
+      tbl->sym[i] = uchar(iSource.getChar());
1360
+    length -= sym;
1361
+  }
1362
+  return true;
1363
+}
1364
+
1365
+bool DCTStream::readRestartInterval()
1366
+{
1367
+  int length;
1368
+
1369
+  length = read16();
1370
+  if (length != 4) {
1371
+    ipeDebug("Bad DCT restart interval");
1372
+    return false;
1373
+  }
1374
+  restartInterval = read16();
1375
+  return true;
1376
+}
1377
+
1378
+bool DCTStream::readAdobeMarker()
1379
+{
1380
+  int length, i;
1381
+  char buf[12];
1382
+  int c;
1383
+
1384
+  length = read16();
1385
+  if (length < 14) {
1386
+    goto err;
1387
+  }
1388
+  for (i = 0; i < 12; ++i) {
1389
+    if ((c = iSource.getChar()) == EOF) {
1390
+      goto err;
1391
+    }
1392
+    buf[i] = char(c);
1393
+  }
1394
+  if (::strncmp(buf, "Adobe", 5)) {
1395
+    goto err;
1396
+  }
1397
+  colorXform = buf[11];
1398
+  gotAdobeMarker = true;
1399
+  for (i = 14; i < length; ++i) {
1400
+    if (iSource.getChar() == EOF) {
1401
+      goto err;
1402
+    }
1403
+  }
1404
+  return true;
1405
+
1406
+ err:
1407
+  ipeDebug("Bad DCT Adobe APP14 marker");
1408
+  return false;
1409
+}
1410
+
1411
+bool DCTStream::readTrailer()
1412
+{
1413
+  int c;
1414
+
1415
+  c = readMarker();
1416
+  if (c != 0xd9) {		// EOI
1417
+    ipeDebug("Bad DCT trailer");
1418
+    return false;
1419
+  }
1420
+  return true;
1421
+}
1422
+
1423
+int DCTStream::readMarker()
1424
+{
1425
+  int c;
1426
+
1427
+  do {
1428
+    do {
1429
+      c = iSource.getChar();
1430
+    } while (c != 0xff);
1431
+    do {
1432
+      c = iSource.getChar();
1433
+    } while (c == 0xff);
1434
+  } while (c == 0x00);
1435
+  return c;
1436
+}
1437
+
1438
+int DCTStream::read16()
1439
+{
1440
+  int c1, c2;
1441
+
1442
+  if ((c1 = iSource.getChar()) == EOF)
1443
+    return EOF;
1444
+  if ((c2 = iSource.getChar()) == EOF)
1445
+    return EOF;
1446
+  return (c1 << 8) + c2;
1447
+}
1448
+
1449
+// --------------------------------------------------------------------
1450
+
1451
+bool dctDecode(Buffer dctData, Buffer pixelData)
1452
+{
1453
+  // ipeDebug("dctDecode %d, %d", dctData.size(), pixelData.size());
1454
+  BufferSource source(dctData);
1455
+  DCTStream dct(source);
1456
+  dct.reset();
1457
+  char *p = pixelData.data();
1458
+  int n = pixelData.size();
1459
+  while (n--) {
1460
+    int c = dct.getChar();
1461
+    if (c == EOF)
1462
+      return false;
1463
+    *p++ = char(c);
1464
+  }
1465
+  return true;
1466
+}
1467
+
1468
+// --------------------------------------------------------------------
(-)graphics/ipe/files/patch-ipelib__ipepdfparser.cpp (-10 lines)
Lines 1-10 Link Here
1
--- ipelib/ipepdfparser.cpp.orig
2
+++ ipelib/ipepdfparser.cpp
3
@@ -30,6 +30,7 @@
4
 
5
 #include "ipepdfparser.h"
6
 #include "ipeutils.h"
7
+#include <cstdlib>
8
 
9
 using namespace ipe;
10
 
(-)graphics/ipe/files/patch-ipetoipe__ipetoipe.cpp (-10 lines)
Lines 1-10 Link Here
1
--- ipetoipe/ipetoipe.cpp.orig
2
+++ ipetoipe/ipetoipe.cpp
3
@@ -29,6 +29,7 @@
4
 */
5
 
6
 #include "ipedoc.h"
7
+#include <cstdlib>
8
 
9
 using ipe::Document;
10
 using ipe::String;

Return to bug 190899