1 /*******************************************************************************
2  * Copyright (c) 2000, 2014 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * This source file is based in part on the work of the Independent JPEG Group (IJG)
12  * and is made available under the terms contained in the about_files/IJG_README
13  * file accompanying this program.
14  *
15  * Contributors:
16  *     IBM Corporation - initial API and implementation
17  *******************************************************************************/
18 package org.eclipse.swt.internal.image;
19 
20 
21 import org.eclipse.swt.*;
22 import org.eclipse.swt.graphics.*;
23 import java.io.*;
24 
25 public final class JPEGFileFormat extends FileFormat {
26 	int restartInterval;
27 	JPEGFrameHeader frameHeader;
28 	int imageWidth, imageHeight;
29 	int interleavedMcuCols, interleavedMcuRows;
30 	int maxV, maxH;
31 	boolean progressive;
32 	int samplePrecision;
33 	int nComponents;
34 	int[][] frameComponents;
35 	int[] componentIds;
36 	byte[][] imageComponents;
37 	int[] dataUnit;
38 	int[][][] dataUnits;
39 	int[] precedingDCs;
40 	JPEGScanHeader scanHeader;
41 	byte[] dataBuffer;
42 	int currentBitCount;
43 	int bufferCurrentPosition;
44 	int restartsToGo;
45 	int nextRestartNumber;
46 	JPEGHuffmanTable[] acHuffmanTables;
47 	JPEGHuffmanTable[] dcHuffmanTables;
48 	int[][] quantizationTables;
49 	int currentByte;
50 	int encoderQFactor = 75;
51 	int eobrun = 0;
52 	/* JPEGConstants */
53 	public static final int DCTSIZE = 8;
54 	public static final int DCTSIZESQR = 64;
55 	/* JPEGFixedPointConstants */
56 	public static final int FIX_0_899976223 = 7373;
57 	public static final int FIX_1_961570560 = 16069;
58 	public static final int FIX_2_053119869 = 16819;
59 	public static final int FIX_0_298631336 = 2446;
60 	public static final int FIX_1_847759065 = 15137;
61 	public static final int FIX_1_175875602 = 9633;
62 	public static final int FIX_3_072711026 = 25172;
63 	public static final int FIX_0_765366865 = 6270;
64 	public static final int FIX_2_562915447 = 20995;
65 	public static final int FIX_0_541196100 = 4433;
66 	public static final int FIX_0_390180644 = 3196;
67 	public static final int FIX_1_501321110 = 12299;
68 	/* JPEGMarkerCodes */
69 	public static final int APP0  = 0xFFE0;
70 	public static final int APP15 = 0xFFEF;
71 	public static final int COM   = 0xFFFE;
72 	public static final int DAC   = 0xFFCC;
73 	public static final int DHP   = 0xFFDE;
74 	public static final int DHT   = 0xFFC4;
75 	public static final int DNL   = 0xFFDC;
76 	public static final int DRI   = 0xFFDD;
77 	public static final int DQT   = 0xFFDB;
78 	public static final int EOI   = 0xFFD9;
79 	public static final int EXP   = 0xFFDF;
80 	public static final int JPG   = 0xFFC8;
81 	public static final int JPG0  = 0xFFF0;
82 	public static final int JPG13 = 0xFFFD;
83 	public static final int RST0  = 0xFFD0;
84 	public static final int RST1  = 0xFFD1;
85 	public static final int RST2  = 0xFFD2;
86 	public static final int RST3  = 0xFFD3;
87 	public static final int RST4  = 0xFFD4;
88 	public static final int RST5  = 0xFFD5;
89 	public static final int RST6  = 0xFFD6;
90 	public static final int RST7  = 0xFFD7;
91 	public static final int SOF0  = 0xFFC0;
92 	public static final int SOF1  = 0xFFC1;
93 	public static final int SOF2  = 0xFFC2;
94 	public static final int SOF3  = 0xFFC3;
95 	public static final int SOF5  = 0xFFC5;
96 	public static final int SOF6  = 0xFFC6;
97 	public static final int SOF7  = 0xFFC7;
98 	public static final int SOF9  = 0xFFC9;
99 	public static final int SOF10 = 0xFFCA;
100 	public static final int SOF11 = 0xFFCB;
101 	public static final int SOF13 = 0xFFCD;
102 	public static final int SOF14 = 0xFFCE;
103 	public static final int SOF15 = 0xFFCF;
104 	public static final int SOI   = 0xFFD8;
105 	public static final int SOS   = 0xFFDA;
106 	public static final int TEM   = 0xFF01;
107 	/* JPEGFrameComponentParameterConstants */
108 	public static final int TQI	= 0;
109 	public static final int HI	= 1;
110 	public static final int VI	= 2;
111 	public static final int CW	= 3;
112 	public static final int CH	= 4;
113 	/* JPEGScanComponentParameterConstants */
114 	public static final int DC	= 0;
115 	public static final int AC	= 1;
116 	/* JFIF Component Constants */
117 	public static final int ID_Y		= 1 - 1;
118 	public static final int ID_CB	= 2 - 1;
119 	public static final int ID_CR	= 3 - 1;
120 	public static final RGB[] RGB16 = new RGB[] {
121 		new RGB(0,0,0),
122 		new RGB(0x80,0,0),
123 		new RGB(0,0x80,0),
124 		new RGB(0x80,0x80,0),
125 		new RGB(0,0,0x80),
126 		new RGB(0x80,0,0x80),
127 		new RGB(0,0x80,0x80),
128 		new RGB(0xC0,0xC0,0xC0),
129 		new RGB(0x80,0x80,0x80),
130 		new RGB(0xFF,0,0),
131 		new RGB(0,0xFF,0),
132 		new RGB(0xFF,0xFF,0),
133 		new RGB(0,0,0xFF),
134 		new RGB(0xFF,0,0xFF),
135 		new RGB(0,0xFF,0xFF),
136 		new RGB(0xFF,0xFF,0xFF),
137 	};
138 	public static final int[] ExtendTest = {
139 		0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
140 		4096, 8192, 16384, 32768, 65536, 131072, 262144
141 	};
142 	public static final int[] ExtendOffset = new int[] {
143 		0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047,
144 		-4095, -8191, -16383, -32767, -65535, -131071, -262143
145 	};
146 	public static final int[] ZigZag8x8 = {
147 		0, 1, 8, 16, 9, 2, 3, 10,
148 		17, 24, 32, 25, 18, 11, 4, 5,
149 		12, 19, 26, 33, 40, 48, 41, 34,
150 		27, 20, 13, 6, 7, 14, 21, 28,
151 		35, 42, 49, 56, 57, 50, 43, 36,
152 		29, 22, 15, 23, 30, 37, 44, 51,
153 		58, 59, 52, 45, 38, 31, 39, 46,
154 		53, 60, 61, 54, 47, 55, 62, 63
155 	};
156 
157 	public static final int[] CrRTable, CbBTable, CrGTable, CbGTable;
158 	public static final int[] RYTable, GYTable, BYTable,
159 		RCbTable, GCbTable, BCbTable, RCrTable, GCrTable, BCrTable, NBitsTable;
160 	static {
161 		/* Initialize RGB-YCbCr Tables */
162 		int [] rYTable = new int[256];
163 		int [] gYTable = new int[256];
164 		int [] bYTable = new int[256];
165 		int [] rCbTable = new int[256];
166 		int [] gCbTable = new int[256];
167 		int [] bCbTable = new int[256];
168 		int [] gCrTable = new int[256];
169 		int [] bCrTable = new int[256];
170 		for (int i = 0; i < 256; i++) {
171 			rYTable[i] = i * 19595;
172 			gYTable[i] = i * 38470;
173 			bYTable[i] = i * 7471 + 32768;
174 			rCbTable[i] = i * -11059;
175 			gCbTable[i] = i * -21709;
176 			bCbTable[i] = i * 32768 + 8388608;
177 			gCrTable[i] = i * -27439;
178 			bCrTable[i] = i * -5329;
179 		}
180 		RYTable = rYTable;
181 		GYTable = gYTable;
182 		BYTable = bYTable;
183 		RCbTable = rCbTable;
184 		GCbTable = gCbTable;
185 		BCbTable = bCbTable;
186 		RCrTable = bCbTable;
187 		GCrTable = gCrTable;
188 		BCrTable = bCrTable;
189 
190 		/* Initialize YCbCr-RGB Tables */
191 		int [] crRTable = new int[256];
192 		int [] cbBTable = new int[256];
193 		int [] crGTable = new int[256];
194 		int [] cbGTable = new int[256];
195 		for (int i = 0; i < 256; i++) {
196 			int x2 = 2 * i - 255;
197 			crRTable[i] = (45941 * x2 + 32768) >> 16;
198 			cbBTable[i] = (58065 * x2 + 32768) >> 16;
199 			crGTable[i] = -23401 * x2;
200 			cbGTable[i] = -11277 * x2 + 32768;
201 		}
202 		CrRTable = crRTable;
203 		CbBTable = cbBTable;
204 		CrGTable = crGTable;
205 		CbGTable = cbGTable;
206 
207 		/* Initialize BitCount Table */
208 		int nBits = 1;
209 		int power2 = 2;
210 		int [] nBitsTable = new int[2048];
211 		nBitsTable[0] = 0;
212 		for (int i = 1; i < nBitsTable.length; i++) {
213 			if (!(i < power2)) {
214 				nBits++;
215 				power2 *= 2;
216 			}
217 			nBitsTable[i] = nBits;
218 		}
219 		NBitsTable = nBitsTable;
220 	}
compress(ImageData image, byte[] dataYComp, byte[] dataCbComp, byte[] dataCrComp)221 void compress(ImageData image, byte[] dataYComp, byte[] dataCbComp, byte[] dataCrComp) {
222 	int srcWidth = image.width;
223 	int srcHeight = image.height;
224 	int vhFactor = maxV * maxH;
225 	int[] frameComponent;
226 	imageComponents = new byte[nComponents][];
227 	for (int i = 0; i < nComponents; i++) {
228 		frameComponent = frameComponents[componentIds[i]];
229 		imageComponents[i] = new byte[frameComponent[CW] * frameComponent[CH]];
230 	}
231 	frameComponent = frameComponents[componentIds[ID_Y]];
232 	for (int yPos = 0; yPos < srcHeight; yPos++) {
233 		int srcOfs = yPos * srcWidth;
234 		int dstOfs = yPos * frameComponent[CW];
235 		System.arraycopy(dataYComp, srcOfs, imageComponents[ID_Y], dstOfs, srcWidth);
236 	}
237 	frameComponent = frameComponents[componentIds[ID_CB]];
238 	for (int yPos = 0; yPos < srcHeight / maxV; yPos++) {
239 		int destRowIndex = yPos * frameComponent[CW];
240 		for (int xPos = 0; xPos < srcWidth / maxH; xPos++) {
241 			int sum = 0;
242 			for (int iv = 0; iv < maxV; iv++) {
243 				int srcIndex = (yPos * maxV + iv) * srcWidth + (xPos * maxH);
244 				for (int ih = 0; ih < maxH; ih++) {
245 					sum += dataCbComp[srcIndex + ih] & 0xFF;
246 				}
247 			}
248 			imageComponents[ID_CB][destRowIndex + xPos] = (byte)(sum / vhFactor);
249 		}
250 	}
251 	frameComponent = frameComponents[componentIds[ID_CR]];
252 	for (int yPos = 0; yPos < srcHeight / maxV; yPos++) {
253 		int destRowIndex = yPos * frameComponent[CW];
254 		for (int xPos = 0; xPos < srcWidth / maxH; xPos++) {
255 			int sum = 0;
256 			for (int iv = 0; iv < maxV; iv++) {
257 				int srcIndex = (yPos * maxV + iv) * srcWidth + (xPos * maxH);
258 				for (int ih = 0; ih < maxH; ih++) {
259 					sum += dataCrComp[srcIndex + ih] & 0xFF;
260 				}
261 			}
262 			imageComponents[ID_CR][destRowIndex + xPos] = (byte)(sum / vhFactor);
263 		}
264 	}
265 	for (int iComp = 0; iComp < nComponents; iComp++) {
266 		byte[] imageComponent = imageComponents[iComp];
267 		frameComponent = frameComponents[componentIds[iComp]];
268 		int hFactor = frameComponent[HI];
269 		int vFactor = frameComponent[VI];
270 		int componentWidth = frameComponent[CW];
271 		int componentHeight = frameComponent[CH];
272 		int compressedWidth = srcWidth / (maxH / hFactor);
273 		int compressedHeight = srcHeight / (maxV / vFactor);
274 		if (compressedWidth < componentWidth) {
275 			int delta = componentWidth - compressedWidth;
276 			for (int yPos = 0; yPos < compressedHeight; yPos++) {
277 				int dstOfs = ((yPos + 1) * componentWidth - delta);
278 				int dataValue = imageComponent[(dstOfs > 0) ? dstOfs - 1 : 0] & 0xFF;
279 				for (int i = 0; i < delta; i++) {
280 					imageComponent[dstOfs + i] = (byte)dataValue;
281 				}
282 			}
283 		}
284 		if (compressedHeight < componentHeight) {
285 			int srcOfs = (compressedHeight > 0) ? (compressedHeight - 1) * componentWidth : 1;
286 			for (int yPos = (compressedHeight > 0) ? compressedHeight : 1; yPos <= componentHeight; yPos++) {
287 				int dstOfs = (yPos - 1) * componentWidth;
288 				System.arraycopy(imageComponent, srcOfs, imageComponent, dstOfs, componentWidth);
289 			}
290 		}
291 	}
292 }
convert4BitRGBToYCbCr(ImageData image)293 void convert4BitRGBToYCbCr(ImageData image) {
294 	RGB[] rgbs = image.getRGBs();
295 	int paletteSize = rgbs.length;
296 	byte[] yComp = new byte[paletteSize];
297 	byte[] cbComp = new byte[paletteSize];
298 	byte[] crComp = new byte[paletteSize];
299 	int srcWidth = image.width;
300 	int srcHeight = image.height;
301 	for (int i = 0; i < paletteSize; i++) {
302 		RGB color = rgbs[i];
303 		int r = color.red;
304 		int g = color.green;
305 		int b = color.blue;
306 		int n = RYTable[r] + GYTable[g] + BYTable[b];
307 		yComp[i] = (byte)(n >> 16);
308 		if ((n < 0) && ((n & 0xFFFF) != 0)) yComp[i]--;
309 		n = RCbTable[r] + GCbTable[g] + BCbTable[b];
310 		cbComp[i] = (byte)(n >> 16);
311 		if ((n < 0) && ((n & 0xFFFF) != 0)) cbComp[i]--;
312 		n = RCrTable[r] + GCrTable[g] + BCrTable[b];
313 		crComp[i] = (byte)(n >> 16);
314 		if ((n < 0) && ((n & 0xFFFF) != 0)) crComp[i]--;
315 	}
316 	int bSize = srcWidth * srcHeight;
317 	byte[] dataYComp = new byte[bSize];
318 	byte[] dataCbComp = new byte[bSize];
319 	byte[] dataCrComp = new byte[bSize];
320 	byte[] origData = image.data;
321 	int bytesPerLine = image.bytesPerLine;
322 	int maxScanlineByte = srcWidth >> 1;
323 	for (int yPos = 0; yPos < srcHeight; yPos++) {
324 		for (int xPos = 0; xPos < maxScanlineByte; xPos++) {
325 			int srcIndex = yPos * bytesPerLine + xPos;
326 			int dstIndex = yPos * srcWidth + (xPos * 2);
327 			int value2 = origData[srcIndex] & 0xFF;
328 			int value1 = value2 >> 4;
329 			value2 &= 0x0F;
330 			dataYComp[dstIndex] = yComp[value1];
331 			dataCbComp[dstIndex] = cbComp[value1];
332 			dataCrComp[dstIndex] = crComp[value1];
333 			dataYComp[dstIndex + 1] = yComp[value2];
334 			dataCbComp[dstIndex + 1] = cbComp[value2];
335 			dataCrComp[dstIndex + 1] = crComp[value2];
336 		}
337 	}
338 	compress(image, dataYComp, dataCbComp, dataCrComp);
339 }
convert8BitRGBToYCbCr(ImageData image)340 void convert8BitRGBToYCbCr(ImageData image) {
341 	RGB[] rgbs = image.getRGBs();
342 	int paletteSize = rgbs.length;
343 	byte[] yComp = new byte[paletteSize];
344 	byte[] cbComp = new byte[paletteSize];
345 	byte[] crComp = new byte[paletteSize];
346 	int srcWidth = image.width;
347 	int srcHeight = image.height;
348 	for (int i = 0; i < paletteSize; i++) {
349 		RGB color = rgbs[i];
350 		int r = color.red;
351 		int g = color.green;
352 		int b = color.blue;
353 		int n = RYTable[r] + GYTable[g] + BYTable[b];
354 		yComp[i] = (byte)(n >> 16);
355 		if ((n < 0) && ((n & 0xFFFF) != 0)) yComp[i]--;
356 		n = RCbTable[r] + GCbTable[g] + BCbTable[b];
357 		cbComp[i] = (byte)(n >> 16);
358 		if ((n < 0) && ((n & 0xFFFF) != 0)) cbComp[i]--;
359 		n = RCrTable[r] + GCrTable[g] + BCrTable[b];
360 		crComp[i] = (byte)(n >> 16);
361 		if ((n < 0) && ((n & 0xFFFF) != 0)) crComp[i]--;
362 	}
363 	int dstWidth = image.width;
364 	int dstHeight = srcHeight;
365 	int stride = ((srcWidth + 3) >> 2) << 2;
366 	int bSize = dstWidth * dstHeight;
367 	byte[] dataYComp = new byte[bSize];
368 	byte[] dataCbComp = new byte[bSize];
369 	byte[] dataCrComp = new byte[bSize];
370 	byte[] origData = image.data;
371 	for (int yPos = 0; yPos < srcHeight; yPos++) {
372 		int srcRowIndex = yPos * stride;
373 		int dstRowIndex = yPos * dstWidth;
374 		for (int xPos = 0; xPos < srcWidth; xPos++) {
375 			int value = origData[srcRowIndex + xPos] & 0xFF;
376 			int dstIndex = dstRowIndex + xPos;
377 			dataYComp[dstIndex] = yComp[value];
378 			dataCbComp[dstIndex] = cbComp[value];
379 			dataCrComp[dstIndex] = crComp[value];
380 		}
381 	}
382 	compress(image, dataYComp, dataCbComp, dataCrComp);
383 }
convertCMYKToRGB()384 byte[] convertCMYKToRGB() {
385 	/* Unsupported CMYK format. Answer an empty byte array. */
386 	return new byte[0];
387 }
convertImageToYCbCr(ImageData image)388 void convertImageToYCbCr(ImageData image) {
389 	switch (image.depth) {
390 		case 4:
391 			convert4BitRGBToYCbCr(image);
392 			return;
393 		case 8:
394 			convert8BitRGBToYCbCr(image);
395 			return;
396 		case 16:
397 		case 24:
398 		case 32:
399 			convertMultiRGBToYCbCr(image);
400 			return;
401 		default:
402 			SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
403 	}
404 	return;
405 }
convertMultiRGBToYCbCr(ImageData image)406 void convertMultiRGBToYCbCr(ImageData image) {
407 	int srcWidth = image.width;
408 	int srcHeight = image.height;
409 	int bSize = srcWidth * srcHeight;
410 	byte[] dataYComp = new byte[bSize];
411 	byte[] dataCbComp = new byte[bSize];
412 	byte[] dataCrComp = new byte[bSize];
413 	PaletteData palette = image.palette;
414 	int[] buffer = new int[srcWidth];
415 	if (palette.isDirect) {
416 		int redMask = palette.redMask;
417 		int greenMask = palette.greenMask;
418 		int blueMask = palette.blueMask;
419 		int redShift = palette.redShift;
420 		int greenShift = palette.greenShift;
421 		int blueShift = palette.blueShift;
422 		for (int yPos = 0; yPos < srcHeight; yPos++) {
423 			image.getPixels(0, yPos, srcWidth, buffer, 0);
424 			int dstRowIndex = yPos * srcWidth;
425 			for (int xPos = 0; xPos < srcWidth; xPos++) {
426 				int pixel = buffer[xPos];
427 				int dstDataIndex = dstRowIndex + xPos;
428 				int r = pixel & redMask;
429 				r = (redShift < 0) ? r >>> -redShift : r << redShift;
430 				int g = pixel & greenMask;
431 				g = (greenShift < 0) ? g >>> -greenShift : g << greenShift;
432 				int b = pixel & blueMask;
433 				b = (blueShift < 0) ? b >>> -blueShift : b << blueShift;
434 				dataYComp[dstDataIndex] = (byte)((RYTable[r] + GYTable[g] + BYTable[b]) >> 16);
435 				dataCbComp[dstDataIndex] = (byte)((RCbTable[r] + GCbTable[g] + BCbTable[b]) >> 16);
436 				dataCrComp[dstDataIndex] = (byte)((RCrTable[r] + GCrTable[g] + BCrTable[b]) >> 16);
437 			}
438 		}
439 	} else {
440 		for (int yPos = 0; yPos < srcHeight; yPos++) {
441 			image.getPixels(0, yPos, srcWidth, buffer, 0);
442 			int dstRowIndex = yPos * srcWidth;
443 			for (int xPos = 0; xPos < srcWidth; xPos++) {
444 				int pixel = buffer[xPos];
445 				int dstDataIndex = dstRowIndex + xPos;
446 				RGB rgb = palette.getRGB(pixel);
447 				int r = rgb.red;
448 				int g = rgb.green;
449 				int b = rgb.blue;
450 				dataYComp[dstDataIndex] = (byte)((RYTable[r] + GYTable[g] + BYTable[b]) >> 16);
451 				dataCbComp[dstDataIndex] = (byte)((RCbTable[r] + GCbTable[g] + BCbTable[b]) >> 16);
452 				dataCrComp[dstDataIndex] = (byte)((RCrTable[r] + GCrTable[g] + BCrTable[b]) >> 16);
453 			}
454 		}
455 	}
456 	compress(image, dataYComp, dataCbComp, dataCrComp);
457 }
convertYToRGB()458 byte[] convertYToRGB() {
459 	int compWidth = frameComponents[componentIds[ID_Y]][CW];
460 	int bytesPerLine = (((imageWidth * 8 + 7) / 8) + 3) / 4 * 4;
461 	byte[] data = new byte[bytesPerLine * imageHeight];
462 	byte[] yComp = imageComponents[ID_Y];
463 	int destIndex = 0;
464 	for (int i = 0; i < imageHeight; i++) {
465 		int srcIndex = i * compWidth;
466 		for (int j = 0; j < bytesPerLine; j++) {
467 			int y = yComp[srcIndex] & 0xFF;
468 			if (y < 0) {
469 				y = 0;
470 			} else {
471 				if (y > 255) y = 255;
472 			}
473 			if (j >= imageWidth) {
474 				y = 0;
475 			}
476 			data[destIndex] = (byte)y;
477 			srcIndex++;
478 			destIndex++;
479 		}
480 	}
481 	return data;
482 }
convertYCbCrToRGB()483 byte[] convertYCbCrToRGB() {
484 	/**
485 	 * Convert existing image components into an RGB format.
486 	 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
487 	 * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
488 	 * The conversion equations to be implemented are therefore
489 	 * 	R = Y                + 1.40200 * Cr
490 	 * 	G = Y - 0.34414 * Cb - 0.71414 * Cr
491 	 * 	B = Y + 1.77200 * Cb
492 	 * where Cb and Cr represent the incoming values less MAXJSAMPLE/2.
493 	 * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
494 	 *
495 	 * To avoid floating-point arithmetic, we represent the fractional constants
496 	 * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
497 	 * the products by 2^16, with appropriate rounding, to get the correct answer.
498 	 * Notice that Y, being an integral input, does not contribute any fraction
499 	 * so it need not participate in the rounding.
500 	 *
501 	 * For even more speed, we avoid doing any multiplications in the inner loop
502 	 * by precalculating the constants times Cb and Cr for all possible values.
503 	 * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
504 	 * for 12-bit samples it is still acceptable.  It's not very reasonable for
505 	 * 16-bit samples, but if you want lossless storage you shouldn't be changing
506 	 * colorspace anyway.
507 	 * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
508 	 * values for the G calculation are left scaled up, since we must add them
509 	 * together before rounding.
510 	 */
511 	int bSize = imageWidth * imageHeight * nComponents;
512 	byte[] rgbData = new byte[bSize];
513 	int destIndex = 0;
514 	expandImageComponents();
515 	byte[] yComp = imageComponents[ID_Y];
516 	byte[] cbComp = imageComponents[ID_CB];
517 	byte[] crComp = imageComponents[ID_CR];
518 	int compWidth = frameComponents[componentIds[ID_Y]][CW];
519 	for (int v = 0; v < imageHeight; v++) {
520 		int srcIndex = v * compWidth;
521 		for (int i = 0; i < imageWidth; i++) {
522 			int y = yComp[srcIndex] & 0xFF;
523 			int cb = cbComp[srcIndex] & 0xFF;
524 			int cr = crComp[srcIndex] & 0xFF;
525 			int r = y + CrRTable[cr];
526 			int g = y + ((CbGTable[cb] + CrGTable[cr]) >> 16);
527 			int b = y + CbBTable[cb];
528 			if (r < 0) {
529 				r = 0;
530 			} else {
531 				if (r > 255) r = 255;
532 			}
533 			if (g < 0) {
534 				g = 0;
535 			} else {
536 				if (g > 255) g = 255;
537 			}
538 			if (b < 0) {
539 				b = 0;
540 			} else {
541 				if (b > 255) b = 255;
542 			}
543 			rgbData[destIndex] = (byte)b;
544 			rgbData[destIndex + 1] = (byte)g;
545 			rgbData[destIndex + 2] = (byte)r;
546 			destIndex += 3;
547 			srcIndex++;
548 		}
549 	}
550 	return rgbData;
551 }
decodeACCoefficients(int[] dataUnit, int iComp)552 void decodeACCoefficients(int[] dataUnit, int iComp) {
553 	int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
554 	JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
555 	int k = 1;
556 	while (k < 64) {
557 		int rs = decodeUsingTable(acTable);
558 		int r = rs >> 4;
559 		int s = rs & 0xF;
560 		if (s == 0) {
561 			if (r == 15) {
562 				k += 16;
563 			} else {
564 				break;
565 			}
566 		} else {
567 			k += r;
568 			int bits = receive(s);
569 			dataUnit[ZigZag8x8[k]] = extendBy(bits, s);
570 			k++;
571 		}
572 	}
573 }
decodeACFirstCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit)574 void decodeACFirstCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit) {
575 	if (eobrun > 0) {
576 		eobrun--;
577 		return;
578 	}
579 	int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
580 	JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
581 	int k = start;
582 	while (k <= end) {
583 		int rs = decodeUsingTable(acTable);
584 		int r = rs >> 4;
585 		int s = rs & 0xF;
586 		if (s == 0) {
587 			if (r == 15) {
588 				k += 16;
589 			} else {
590 				eobrun = (1 << r) + receive(r) - 1;
591 				break;
592 			}
593 		} else {
594 			k += r;
595 			int bits = receive(s);
596 			dataUnit[ZigZag8x8[k]] = extendBy(bits, s) << approxBit;
597 			k++;
598 		}
599 	}
600 }
decodeACRefineCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit)601 void decodeACRefineCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit) {
602 	int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
603 	JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
604 	int k = start;
605 	while (k <= end) {
606 		if (eobrun > 0) {
607 			while (k <= end) {
608 				int zzIndex = ZigZag8x8[k];
609 				if (dataUnit[zzIndex] != 0) {
610 					dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
611 				}
612 				k++;
613 			}
614 			eobrun--;
615 		} else {
616 			int rs = decodeUsingTable(acTable);
617 			int r = rs >> 4;
618 			int s = rs & 0xF;
619 			if (s == 0) {
620 				if (r == 15) {
621 					int zeros = 0;
622 					while (zeros < 16 && k <= end) {
623 						int zzIndex = ZigZag8x8[k];
624 						if (dataUnit[zzIndex] != 0) {
625 							dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
626 						} else {
627 							zeros++;
628 						}
629 						k++;
630 					}
631 				} else {
632 					eobrun = (1 << r) + receive(r);
633 				}
634 			} else {
635 				int bit = receive(s);
636 				int zeros = 0;
637 				int zzIndex = ZigZag8x8[k];
638 				while ((zeros < r || dataUnit[zzIndex] != 0) && k <= end) {
639 					if (dataUnit[zzIndex] != 0) {
640 						dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
641 					} else {
642 						zeros++;
643 					}
644 					k++;
645 					zzIndex = ZigZag8x8[k];
646 				}
647 				if (bit != 0) {
648 					dataUnit[zzIndex] = 1 << approxBit;
649 				} else {
650 					dataUnit[zzIndex] = -1 << approxBit;
651 				}
652 				k++;
653 			}
654 		}
655 	}
656 }
refineAC(int ac, int approxBit)657 int refineAC(int ac, int approxBit) {
658 	if (ac > 0) {
659 		int bit = nextBit();
660 		if (bit != 0) {
661 			ac += 1 << approxBit;
662 		}
663 	} else if (ac < 0) {
664 		int bit = nextBit();
665 		if (bit != 0) {
666 			ac += -1 << approxBit;
667 		}
668 	}
669 	return ac;
670 }
decodeDCCoefficient(int[] dataUnit, int iComp, boolean first, int approxBit)671 void decodeDCCoefficient(int[] dataUnit, int iComp, boolean first, int approxBit) {
672 	int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
673 	JPEGHuffmanTable dcTable = dcHuffmanTables[sParams[DC]];
674 	int lastDC = 0;
675 	if (progressive && !first) {
676 		int bit = nextBit();
677 		lastDC = dataUnit[0] + (bit << approxBit);
678 	} else {
679 		lastDC = precedingDCs[iComp];
680 		int nBits = decodeUsingTable(dcTable);
681 		if (nBits != 0) {
682 			int bits = receive(nBits);
683 			int diff = extendBy(bits, nBits);
684 			lastDC += diff;
685 			precedingDCs[iComp] = lastDC;
686 		}
687 		if (progressive) {
688 			lastDC = lastDC << approxBit;
689 		}
690 	}
691 	dataUnit[0] = lastDC;
692 }
dequantize(int[] dataUnit, int iComp)693 void dequantize(int[] dataUnit, int iComp) {
694 	int[] qTable = quantizationTables[frameComponents[componentIds[iComp]][TQI]];
695 	for (int i = 0; i < dataUnit.length; i++) {
696 		int zzIndex = ZigZag8x8[i];
697 		dataUnit[zzIndex] = dataUnit[zzIndex] * qTable[i];
698 	}
699 }
decodeImageComponents()700 byte[] decodeImageComponents() {
701 	if (nComponents == 3) { // compIds 1, 2, 3
702 		return convertYCbCrToRGB();
703 	}
704 //	if (nComponents == 3) { // compIds 1, 4, 5
705 //		Unsupported CMYK format.
706 //		return convertYIQToRGB();
707 //	}
708 	if (nComponents == 4) {
709 		return convertCMYKToRGB();
710 	}
711 	return convertYToRGB();
712 }
decodeMCUAtXAndY(int xmcu, int ymcu, int nComponentsInScan, boolean first, int start, int end, int approxBit)713 void decodeMCUAtXAndY(int xmcu, int ymcu, int nComponentsInScan, boolean first, int start, int end, int approxBit) {
714 	for (int iComp = 0; iComp < nComponentsInScan; iComp++) {
715 		int scanComponent = iComp;
716 		while (scanHeader.componentParameters[componentIds[scanComponent]] == null) {
717 			scanComponent++;
718 		}
719 		int[] frameComponent = frameComponents[componentIds[scanComponent]];
720 		int hi = frameComponent[HI];
721 		int vi = frameComponent[VI];
722 		if (nComponentsInScan == 1) {
723 			hi = 1;
724 			vi = 1;
725 		}
726 		int compWidth = frameComponent[CW];
727 		for (int ivi = 0; ivi < vi; ivi++) {
728 			for (int ihi = 0; ihi < hi; ihi++) {
729 				if (progressive) {
730 					// Progressive: First scan - create a new data unit.
731 					// Subsequent scans - refine the existing data unit.
732 					int index = (ymcu * vi + ivi) * compWidth + xmcu * hi + ihi;
733 					dataUnit = dataUnits[scanComponent][index];
734 					if (dataUnit == null) {
735 						dataUnit = new int[64];
736 						dataUnits[scanComponent][index] = dataUnit;
737 					}
738 				} else {
739 					// Sequential: Clear and reuse the data unit buffer.
740 					for (int i = 0; i < dataUnit.length; i++) {
741 						dataUnit[i] = 0;
742 					}
743 				}
744 				if (!progressive || scanHeader.isDCProgressiveScan()) {
745 					decodeDCCoefficient(dataUnit, scanComponent, first, approxBit);
746 				}
747 				if (!progressive) {
748 					decodeACCoefficients(dataUnit, scanComponent);
749 				} else {
750 					if (scanHeader.isACProgressiveScan()) {
751 						if (first) {
752 							decodeACFirstCoefficients(dataUnit, scanComponent, start, end, approxBit);
753 						} else {
754 							decodeACRefineCoefficients(dataUnit, scanComponent, start, end, approxBit);
755 						}
756 					}
757 					if (loader.hasListeners()) {
758 						// Dequantization, IDCT, up-sampling and color conversion
759 						// are done on a copy of the coefficient data in order to
760 						// display the image incrementally.
761 						int[] temp = dataUnit;
762 						dataUnit = new int[64];
763 						System.arraycopy(temp, 0, dataUnit, 0, 64);
764 					}
765 				}
766 				if (!progressive || (progressive && loader.hasListeners())) {
767 					dequantize(dataUnit, scanComponent);
768 					inverseDCT(dataUnit);
769 					storeData(dataUnit, scanComponent, xmcu, ymcu, hi, ihi, vi, ivi);
770 				}
771 			}
772 		}
773 	}
774 }
decodeScan()775 void decodeScan() {
776 	if (progressive && !scanHeader.verifyProgressiveScan()) {
777 		SWT.error(SWT.ERROR_INVALID_IMAGE);
778 	}
779 	int nComponentsInScan = scanHeader.getNumberOfImageComponents();
780 	int mcuRowsInScan = interleavedMcuRows;
781 	int mcusPerRow = interleavedMcuCols;
782 	if (nComponentsInScan == 1) {
783 		// Non-interleaved.
784 		int scanComponent = 0;
785 		while (scanHeader.componentParameters[componentIds[scanComponent]] == null) {
786 			scanComponent++;
787 		}
788 		int[] frameComponent = frameComponents[componentIds[scanComponent]];
789 		int hi = frameComponent[HI];
790 		int vi = frameComponent[VI];
791 		int mcuWidth = DCTSIZE * maxH / hi;
792 		int mcuHeight = DCTSIZE * maxV / vi;
793 		mcusPerRow = (imageWidth + mcuWidth - 1) / mcuWidth;
794 		mcuRowsInScan = (imageHeight + mcuHeight - 1) / mcuHeight;
795 	}
796 	boolean first = scanHeader.isFirstScan();
797 	int start = scanHeader.getStartOfSpectralSelection();
798 	int end = scanHeader.getEndOfSpectralSelection();
799 	int approxBit = scanHeader.getApproxBitPositionLow();
800 	restartsToGo = restartInterval;
801 	nextRestartNumber = 0;
802 	for (int ymcu = 0; ymcu < mcuRowsInScan; ymcu++) {
803 		for (int xmcu = 0; xmcu < mcusPerRow; xmcu++) {
804 			if (restartInterval != 0) {
805 				if (restartsToGo == 0) processRestartInterval();
806 				restartsToGo--;
807 			}
808 			decodeMCUAtXAndY(xmcu, ymcu, nComponentsInScan, first, start, end, approxBit);
809 		}
810 	}
811 }
decodeUsingTable(JPEGHuffmanTable huffmanTable)812 int decodeUsingTable(JPEGHuffmanTable huffmanTable) {
813 	int i = 0;
814 	int[] maxCodes = huffmanTable.getDhMaxCodes();
815 	int[] minCodes = huffmanTable.getDhMinCodes();
816 	int[] valPtrs = huffmanTable.getDhValPtrs();
817 	int[] huffVals = huffmanTable.getDhValues();
818 	int code = nextBit();
819 	while (code > maxCodes[i]) {
820 		code = code * 2 + nextBit();
821 		i++;
822 	}
823 	int j = valPtrs[i] + code - minCodes[i];
824 	return huffVals[j];
825 }
emit(int huffCode, int nBits)826 void emit(int huffCode, int nBits) {
827 	if (nBits == 0) {
828 		SWT.error(SWT.ERROR_INVALID_IMAGE);
829 	}
830 	int[] power2m1 = new int[] {
831 		1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191,
832 		16383, 32767, 65535, 131125
833 	};
834 	int code = (huffCode & power2m1[nBits - 1]) << (24 - nBits - currentBitCount);
835 	byte[] codeBuffer = new byte[4];
836 	codeBuffer[0] = (byte)(code & 0xFF);
837 	codeBuffer[1] = (byte)((code >> 8) & 0xFF);
838 	codeBuffer[2] = (byte)((code >> 16) & 0xFF);
839 	codeBuffer[3] = (byte)((code >> 24) & 0xFF);
840 	int abs = nBits - (8 - currentBitCount);
841 	if (abs < 0) abs = -abs;
842 	if ((abs >> 3) > 0) {
843 		currentByte += codeBuffer[2];
844 		emitByte((byte)currentByte);
845 		emitByte(codeBuffer[1]);
846 		currentByte = codeBuffer[0];
847 		currentBitCount += nBits - 16;
848 	} else {
849 		currentBitCount += nBits;
850 		if (currentBitCount >= 8) {
851 			currentByte += codeBuffer[2];
852 			emitByte((byte)currentByte);
853 			currentByte = codeBuffer[1];
854 			currentBitCount -= 8;
855 		} else {
856 			currentByte += codeBuffer[2];
857 		}
858 	}
859 }
emitByte(byte byteValue)860 void emitByte(byte byteValue) {
861 	if (bufferCurrentPosition >= 512) {
862 		resetOutputBuffer();
863 	}
864 	dataBuffer[bufferCurrentPosition] = byteValue;
865 	bufferCurrentPosition++;
866 	if (byteValue == -1) {
867 		emitByte((byte)0);
868 	}
869 }
encodeACCoefficients(int[] dataUnit, int iComp)870 void encodeACCoefficients(int[] dataUnit, int iComp) {
871 	int[] sParams = scanHeader.componentParameters[iComp];
872 	JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
873 	int[] ehCodes = acTable.ehCodes;
874 	byte[] ehSizes = acTable.ehCodeLengths;
875 	int r = 0;
876 	int k = 1;
877 	while (k < 64) {
878 		k++;
879 		int acValue = dataUnit[ZigZag8x8[k - 1]];
880 		if (acValue == 0) {
881 			if (k == 64) {
882 				emit(ehCodes[0], ehSizes[0] & 0xFF);
883 			} else {
884 				r++;
885 			}
886 		} else {
887 			while (r > 15) {
888 				emit(ehCodes[0xF0], ehSizes[0xF0] & 0xFF);
889 				r -= 16;
890 			}
891 			if (acValue < 0) {
892 				int absACValue = acValue;
893 				if (absACValue < 0) absACValue = -absACValue;
894 				int nBits = NBitsTable[absACValue];
895 				int rs = r * 16 + nBits;
896 				emit(ehCodes[rs], ehSizes[rs] & 0xFF);
897 				emit(0xFFFFFF - absACValue, nBits);
898 			} else {
899 				int nBits = NBitsTable[acValue];
900 				int rs = r * 16 + nBits;
901 				emit(ehCodes[rs], ehSizes[rs] & 0xFF);
902 				emit(acValue, nBits);
903 			}
904 			r = 0;
905 		}
906 	}
907 }
encodeDCCoefficients(int[] dataUnit, int iComp)908 void encodeDCCoefficients(int[] dataUnit, int iComp) {
909 	int[] sParams = scanHeader.componentParameters[iComp];
910 	JPEGHuffmanTable dcTable = dcHuffmanTables[sParams[DC]];
911 	int lastDC = precedingDCs[iComp];
912 	int dcValue = dataUnit[0];
913 	int diff = dcValue - lastDC;
914 	precedingDCs[iComp] = dcValue;
915 	if (diff < 0) {
916 		int absDiff = 0 - diff;
917 		int nBits = NBitsTable[absDiff];
918 		emit(dcTable.ehCodes[nBits], dcTable.ehCodeLengths[nBits]);
919 		emit(0xFFFFFF - absDiff, nBits);
920 	} else {
921 		int nBits = NBitsTable[diff];
922 		emit(dcTable.ehCodes[nBits], dcTable.ehCodeLengths[nBits]);
923 		if (nBits != 0) {
924 			emit(diff, nBits);
925 		}
926 	}
927 }
encodeMCUAtXAndY(int xmcu, int ymcu)928 void encodeMCUAtXAndY(int xmcu, int ymcu) {
929 	int nComponentsInScan = scanHeader.getNumberOfImageComponents();
930 	dataUnit = new int[64];
931 	for (int iComp = 0; iComp < nComponentsInScan; iComp++) {
932 		int[] frameComponent = frameComponents[componentIds[iComp]];
933 		int hi = frameComponent[HI];
934 		int vi = frameComponent[VI];
935 		for (int ivi = 0; ivi < vi; ivi++) {
936 			for (int ihi = 0; ihi < hi; ihi++) {
937 				extractData(dataUnit, iComp, xmcu, ymcu, ihi, ivi);
938 				forwardDCT(dataUnit);
939 				quantizeData(dataUnit, iComp);
940 				encodeDCCoefficients(dataUnit, iComp);
941 				encodeACCoefficients(dataUnit, iComp);
942 			}
943 		}
944 	}
945 }
encodeScan()946 void encodeScan() {
947 	for (int ymcu = 0; ymcu < interleavedMcuRows; ymcu++) {
948 		for (int xmcu = 0; xmcu < interleavedMcuCols; xmcu++) {
949 			encodeMCUAtXAndY(xmcu, ymcu);
950 		}
951 	}
952 	if (currentBitCount != 0) {
953 		emitByte((byte)currentByte);
954 	}
955 	resetOutputBuffer();
956 }
expandImageComponents()957 void expandImageComponents() {
958 	for (int iComp = 0; iComp < nComponents; iComp++) {
959 		int[] frameComponent = frameComponents[componentIds[iComp]];
960 		int hi = frameComponent[HI];
961 		int vi = frameComponent[VI];
962 		int upH = maxH / hi;
963 		int upV = maxV / vi;
964 		if ((upH * upV) > 1) {
965 			byte[] component = imageComponents[iComp];
966 			int compWidth = frameComponent[CW];
967 			int compHeight = frameComponent[CH];
968 			int upCompWidth = compWidth * upH;
969 			int upCompHeight = compHeight * upV;
970 			ImageData src = new ImageData(compWidth, compHeight, 8, new PaletteData(RGB16), 4, component);
971 			ImageData dest = src.scaledTo(upCompWidth, upCompHeight);
972 			imageComponents[iComp] = dest.data;
973 		}
974 	}
975 }
extendBy(int diff, int t)976 int extendBy(int diff, int t) {
977 	if (diff < ExtendTest[t]) {
978 		return diff + ExtendOffset[t];
979 	} else {
980 		return diff;
981 	}
982 }
extractData(int[] dataUnit, int iComp, int xmcu, int ymcu, int ihi, int ivi)983 void extractData(int[] dataUnit, int iComp, int xmcu, int ymcu, int ihi, int ivi) {
984 	byte[] compImage = imageComponents[iComp];
985 	int[] frameComponent = frameComponents[componentIds[iComp]];
986 	int hi = frameComponent[HI];
987 	int vi = frameComponent[VI];
988 	int compWidth = frameComponent[CW];
989 	int srcIndex = ((ymcu * vi + ivi) * compWidth * DCTSIZE) + ((xmcu * hi + ihi) * DCTSIZE);
990 	int destIndex = 0;
991 	for (int i = 0; i < DCTSIZE; i++) {
992 		for (int col = 0; col < DCTSIZE; col++) {
993 			dataUnit[destIndex] = (compImage[srcIndex + col] & 0xFF) - 128;
994 			destIndex++;
995 		}
996 		srcIndex += compWidth;
997 	}
998 }
forwardDCT(int[] dataUnit)999 void forwardDCT(int[] dataUnit) {
1000 	for (int row = 0; row < 8; row++) {
1001 		int rIndex = row * DCTSIZE;
1002 		int tmp0 = dataUnit[rIndex] + dataUnit[rIndex + 7];
1003 		int tmp7 = dataUnit[rIndex] - dataUnit[rIndex + 7];
1004 		int tmp1 = dataUnit[rIndex + 1] + dataUnit[rIndex + 6];
1005 		int tmp6 = dataUnit[rIndex + 1] - dataUnit[rIndex + 6];
1006 		int tmp2 = dataUnit[rIndex + 2] + dataUnit[rIndex + 5];
1007 		int tmp5 = dataUnit[rIndex + 2] - dataUnit[rIndex + 5];
1008 		int tmp3 = dataUnit[rIndex + 3] + dataUnit[rIndex + 4];
1009 		int tmp4 = dataUnit[rIndex + 3] - dataUnit[rIndex + 4];
1010 
1011 		/**
1012 		 * Even part per LL&M figure 1 --- note that published figure
1013 		 * is faulty; rotator 'sqrt(2)*c1' should be 'sqrt(2)*c6'.
1014 		 */
1015 		int tmp10 = tmp0 + tmp3;
1016 		int tmp13 = tmp0 - tmp3;
1017 		int tmp11 = tmp1 + tmp2;
1018 		int tmp12 = tmp1 - tmp2;
1019 
1020 		dataUnit[rIndex] = (tmp10 + tmp11) * 4;
1021 		dataUnit[rIndex + 4]  = (tmp10 - tmp11) * 4;
1022 
1023 		int z1 = (tmp12 + tmp13) * FIX_0_541196100;
1024 		int n = z1 + (tmp13 * FIX_0_765366865) + 1024;
1025 		dataUnit[rIndex + 2] = n >> 11;
1026 		if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 2]--;
1027 		n = z1 + (tmp12 * (0 - FIX_1_847759065)) + 1024;
1028 		dataUnit[rIndex + 6] = n >> 11;
1029 		if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 6]--;
1030 
1031 		/**
1032 		 * Odd part per figure 8 --- note paper omits factor of sqrt(2).
1033 		 * cK represents cos(K*pi/16).
1034 		 * i0..i3 in the paper are tmp4..tmp7 here.
1035 		 */
1036 		z1 = tmp4 + tmp7;
1037 		int z2 = tmp5 + tmp6;
1038 		int z3 = tmp4 + tmp6;
1039 		int z4 = tmp5 + tmp7;
1040 		int z5 = (z3 + z4) * FIX_1_175875602;	// sqrt(2) * c3
1041 
1042 		tmp4 *= FIX_0_298631336;	// sqrt(2) * (-c1+c3+c5-c7)
1043 		tmp5 *= FIX_2_053119869;	// sqrt(2) * ( c1+c3-c5+c7)
1044 		tmp6 *= FIX_3_072711026;	// sqrt(2) * ( c1+c3+c5-c7)
1045 		tmp7 *= FIX_1_501321110;	// sqrt(2) * ( c1+c3-c5-c7)
1046 		z1 *= 0 - FIX_0_899976223;	// sqrt(2) * (c7-c3)
1047 		z2 *= 0 - FIX_2_562915447;	// sqrt(2) * (-c1-c3)
1048 		z3 *= 0 - FIX_1_961570560;	// sqrt(2) * (-c3-c5)
1049 		z4 *= 0 - FIX_0_390180644;	// sqrt(2) * (c5-c3)
1050 
1051 		z3 += z5;
1052 		z4 += z5;
1053 
1054 		n = tmp4 + z1 + z3 + 1024;
1055 		dataUnit[rIndex + 7] = n >> 11;
1056 		if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 7]--;
1057 		n = tmp5 + z2 + z4 + 1024;
1058 		dataUnit[rIndex + 5] = n >> 11;
1059 		if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 5]--;
1060 		n = tmp6 + z2 + z3 + 1024;
1061 		dataUnit[rIndex + 3] = n >> 11;
1062 		if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 3]--;
1063 		n = tmp7 + z1 + z4 + 1024;
1064 		dataUnit[rIndex + 1] = n >> 11;
1065 		if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 1]--;
1066 	}
1067 
1068 	/**
1069 	 * Pass 2: process columns.
1070 	 * Note that we must descale the results by a factor of 8 == 2**3,
1071 	 * and also undo the PASS1_BITS scaling.
1072 	 */
1073 	for (int col = 0; col < 8; col++) {
1074 		int c0 = col;
1075 		int c1 = col + 8;
1076 		int c2 = col + 16;
1077 		int c3 = col + 24;
1078 		int c4 = col + 32;
1079 		int c5 = col + 40;
1080 		int c6 = col + 48;
1081 		int c7 = col + 56;
1082 		int tmp0 = dataUnit[c0] + dataUnit[c7];
1083 		int tmp7 = dataUnit[c0] - dataUnit[c7];
1084 		int tmp1 = dataUnit[c1] + dataUnit[c6];
1085 		int tmp6 = dataUnit[c1] - dataUnit[c6];
1086 		int tmp2 = dataUnit[c2] + dataUnit[c5];
1087 		int tmp5 = dataUnit[c2] - dataUnit[c5];
1088 		int tmp3 = dataUnit[c3] + dataUnit[c4];
1089 		int tmp4 = dataUnit[c3] - dataUnit[c4];
1090 
1091 		/**
1092 		 * Even part per LL&M figure 1 --- note that published figure
1093 		 * is faulty; rotator 'sqrt(2)*c1' should be 'sqrt(2)*c6'.
1094 		 */
1095 		int tmp10 = tmp0 + tmp3;
1096 		int tmp13 = tmp0 - tmp3;
1097 		int tmp11 = tmp1 + tmp2;
1098 		int tmp12 = tmp1 - tmp2;
1099 
1100 		int n = tmp10 + tmp11 + 16;
1101 		dataUnit[c0] = n >> 5;
1102 		if ((n < 0) && ((n & 0x1F) != 0)) dataUnit[c0]--;
1103 		n = tmp10 - tmp11 + 16;
1104 		dataUnit[c4] = n >> 5;
1105 		if ((n < 0) && ((n & 0x1F) != 0)) dataUnit[c4]--;
1106 
1107 		int z1 = (tmp12 + tmp13) * FIX_0_541196100;
1108 		n = z1 + (tmp13 * FIX_0_765366865) + 131072;
1109 		dataUnit[c2] = n >> 18;
1110 		if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c2]--;
1111 		n = z1 + (tmp12 * (0 - FIX_1_847759065)) + 131072;
1112 		dataUnit[c6] = n >> 18;
1113 		if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c6]--;
1114 
1115 		/**
1116 		 * Odd part per figure 8 --- note paper omits factor of sqrt(2).
1117 		 * cK represents cos(K*pi/16).
1118 		 * i0..i3 in the paper are tmp4..tmp7 here.
1119 		 */
1120 		z1 = tmp4 + tmp7;
1121 		int z2 = tmp5 + tmp6;
1122 		int z3 = tmp4 + tmp6;
1123 		int z4 = tmp5 + tmp7;
1124 		int z5 = (z3 + z4) * FIX_1_175875602;	// sqrt(2) * c3
1125 
1126 		tmp4 *= FIX_0_298631336;	// sqrt(2) * (-c1+c3+c5-c7)
1127 		tmp5 *= FIX_2_053119869;	// sqrt(2) * ( c1+c3-c5+c7)
1128 		tmp6 *= FIX_3_072711026;	// sqrt(2) * ( c1+c3+c5-c7)
1129 		tmp7 *= FIX_1_501321110;	// sqrt(2) * ( c1+c3-c5-c7)
1130 		z1 *= 0 - FIX_0_899976223;	// sqrt(2) * (c7-c3)
1131 		z2 *= 0 - FIX_2_562915447;	// sqrt(2) * (-c1-c3)
1132 		z3 *= 0 - FIX_1_961570560;	// sqrt(2) * (-c3-c5)
1133 		z4 *= 0 - FIX_0_390180644;	// sqrt(2) * (c5-c3)
1134 
1135 		z3 += z5;
1136 		z4 += z5;
1137 
1138 		n = tmp4 + z1 + z3 + 131072;
1139 		dataUnit[c7] = n >> 18;
1140 		if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c7]--;
1141 		n = tmp5 + z2 + z4 + 131072;
1142 		dataUnit[c5] = n >> 18;
1143 		if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c5]--;
1144 		n = tmp6 + z2 + z3 + 131072;
1145 		dataUnit[c3] = n >> 18;
1146 		if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c3]--;
1147 		n = tmp7 + z1 + z4 + 131072;
1148 		dataUnit[c1] = n >> 18;
1149 		if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c1]--;
1150 	}
1151 }
getAPP0()1152 void getAPP0() {
1153 	JPEGAppn appn = new JPEGAppn(inputStream);
1154 	if (!appn.verify()) {
1155 		SWT.error(SWT.ERROR_INVALID_IMAGE);
1156 	}
1157 }
getCOM()1158 void getCOM() {
1159 	new JPEGComment(inputStream);
1160 }
getDAC()1161 void getDAC() {
1162 	new JPEGArithmeticConditioningTable(inputStream);
1163 }
getDHT()1164 void getDHT() {
1165 	JPEGHuffmanTable dht = new JPEGHuffmanTable(inputStream);
1166 	if (!dht.verify()) {
1167 		SWT.error(SWT.ERROR_INVALID_IMAGE);
1168 	}
1169 	if (acHuffmanTables == null) {
1170 		acHuffmanTables = new JPEGHuffmanTable[4];
1171 	}
1172 	if (dcHuffmanTables == null) {
1173 		dcHuffmanTables = new JPEGHuffmanTable[4];
1174 	}
1175 	for (JPEGHuffmanTable dhtTable : dht.getAllTables()) {
1176 		if (dhtTable.getTableClass() == 0) {
1177 			dcHuffmanTables[dhtTable.getTableIdentifier()] = dhtTable;
1178 		} else {
1179 			acHuffmanTables[dhtTable.getTableIdentifier()] = dhtTable;
1180 		}
1181 	}
1182 }
getDNL()1183 void getDNL() {
1184 	new JPEGRestartInterval(inputStream);
1185 }
getDQT()1186 void getDQT() {
1187 	JPEGQuantizationTable dqt = new JPEGQuantizationTable(inputStream);
1188 	int[][] currentTables = quantizationTables;
1189 	if (currentTables == null) {
1190 		currentTables = new int[4][];
1191 	}
1192 	int[] dqtTablesKeys = dqt.getQuantizationTablesKeys();
1193 	int[][] dqtTablesValues = dqt.getQuantizationTablesValues();
1194 	for (int i = 0; i < dqtTablesKeys.length; i++) {
1195 		int index = dqtTablesKeys[i];
1196 		currentTables[index] = dqtTablesValues[i];
1197 	}
1198 	quantizationTables = currentTables;
1199 }
getDRI()1200 void getDRI() {
1201 	JPEGRestartInterval dri = new JPEGRestartInterval(inputStream);
1202 	if (!dri.verify()) {
1203 		SWT.error(SWT.ERROR_INVALID_IMAGE);
1204 	}
1205 	restartInterval = dri.getRestartInterval();
1206 }
inverseDCT(int[] dataUnit)1207 void inverseDCT(int[] dataUnit) {
1208 	for (int row = 0; row < 8; row++) {
1209 		int rIndex = row * DCTSIZE;
1210 		/**
1211 		 * Due to quantization, we will usually find that many of the input
1212 		 * coefficients are zero, especially the AC terms.  We can exploit this
1213 		 * by short-circuiting the IDCT calculation for any row in which all
1214 		 * the AC terms are zero.  In that case each output is equal to the
1215 		 * DC coefficient (with scale factor as needed).
1216 		 * With typical images and quantization tables, half or more of the
1217 		 * row DCT calculations can be simplified this way.
1218 		 */
1219 		if (isZeroInRow(dataUnit, rIndex)) {
1220 			int dcVal = dataUnit[rIndex] << 2;
1221 			for (int i = rIndex + 7; i >= rIndex; i--) {
1222 				dataUnit[i] = dcVal;
1223 			}
1224 		} else {
1225 			/**
1226 			 * Even part: reverse the even part of the forward DCT.
1227 			 * The rotator is sqrt(2)*c(-6).
1228 			 */
1229 			int z2 = dataUnit[rIndex + 2];
1230 			int z3 = dataUnit[rIndex + 6];
1231 			int z1 = (z2 + z3) * FIX_0_541196100;
1232 			int tmp2 = z1 + (z3 * (0 - FIX_1_847759065));
1233 			int tmp3 = z1 + (z2 * FIX_0_765366865);
1234 			int tmp0 = (dataUnit[rIndex] + dataUnit[rIndex + 4]) << 13;
1235 			int tmp1 = (dataUnit[rIndex] - dataUnit[rIndex + 4]) << 13;
1236 			int tmp10 = tmp0 + tmp3;
1237 			int tmp13 = tmp0 - tmp3;
1238 			int tmp11 = tmp1 + tmp2;
1239 			int tmp12 = tmp1 - tmp2;
1240 			/**
1241 			 * Odd part per figure 8; the matrix is unitary and hence its
1242 			 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
1243 			 */
1244 			tmp0 = dataUnit[rIndex + 7];
1245 			tmp1 = dataUnit[rIndex + 5];
1246 			tmp2 = dataUnit[rIndex + 3];
1247 			tmp3 = dataUnit[rIndex + 1];
1248 			z1 = tmp0 + tmp3;
1249 			z2 = tmp1 + tmp2;
1250 			z3 = tmp0 + tmp2;
1251 			int z4 = tmp1 + tmp3;
1252 			int z5 = (z3 + z4) * FIX_1_175875602; /* sqrt(2) * c3 */
1253 
1254 			tmp0 *= FIX_0_298631336;		/* sqrt(2) * (-c1+c3+c5-c7) */
1255 			tmp1 *= FIX_2_053119869;		/* sqrt(2) * ( c1+c3-c5+c7) */
1256 			tmp2 *= FIX_3_072711026;		/* sqrt(2) * ( c1+c3+c5-c7) */
1257 			tmp3 *= FIX_1_501321110;		/* sqrt(2) * ( c1+c3-c5-c7) */
1258 			z1 *= 0 - FIX_0_899976223;	/* sqrt(2) * (c7-c3) */
1259 			z2 *= 0 - FIX_2_562915447;	/* sqrt(2) * (-c1-c3) */
1260 			z3 *= 0 - FIX_1_961570560;	/* sqrt(2) * (-c3-c5) */
1261 			z4 *= 0 - FIX_0_390180644;	/* sqrt(2) * (c5-c3) */
1262 
1263 			z3 += z5;
1264 			z4 += z5;
1265 			tmp0 += z1 + z3;
1266 			tmp1 += z2 + z4;
1267 			tmp2 += z2 + z3;
1268 			tmp3 += z1 + z4;
1269 
1270 			dataUnit[rIndex] = (tmp10 + tmp3 + 1024) >> 11;
1271 			dataUnit[rIndex + 7] = (tmp10 - tmp3 + 1024) >> 11;
1272 			dataUnit[rIndex + 1] = (tmp11 + tmp2 + 1024) >> 11;
1273 			dataUnit[rIndex + 6] = (tmp11 - tmp2 + 1024) >> 11;
1274 			dataUnit[rIndex + 2] = (tmp12 + tmp1 + 1024) >> 11;
1275 			dataUnit[rIndex + 5] = (tmp12 - tmp1 + 1024) >> 11;
1276 			dataUnit[rIndex + 3] = (tmp13 + tmp0 + 1024) >> 11;
1277 			dataUnit[rIndex + 4] = (tmp13 - tmp0 + 1024) >> 11;
1278 		}
1279 	}
1280 	/**
1281 	 * Pass 2: process columns.
1282 	 * Note that we must descale the results by a factor of 8 == 2**3,
1283 	 * and also undo the PASS1_BITS scaling.
1284 	 */
1285 	for (int col = 0; col < 8; col++) {
1286 		int c0 = col;
1287 		int c1 = col + 8;
1288 		int c2 = col + 16;
1289 		int c3 = col + 24;
1290 		int c4 = col + 32;
1291 		int c5 = col + 40;
1292 		int c6 = col + 48;
1293 		int c7 = col + 56;
1294 		if (isZeroInColumn(dataUnit, col)) {
1295 			int dcVal = (dataUnit[c0] + 16) >> 5;
1296 			dataUnit[c0] = dcVal;
1297 			dataUnit[c1] = dcVal;
1298 			dataUnit[c2] = dcVal;
1299 			dataUnit[c3] = dcVal;
1300 			dataUnit[c4] = dcVal;
1301 			dataUnit[c5] = dcVal;
1302 			dataUnit[c6] = dcVal;
1303 			dataUnit[c7] = dcVal;
1304 		} else {
1305 			/**
1306 			 * Even part: reverse the even part of the forward DCT.
1307 			 * The rotator is sqrt(2)*c(-6).
1308 			 */
1309 			int z0 = dataUnit[c0];
1310 			int z2 = dataUnit[c2];
1311 			int z3 = dataUnit[c6];
1312 			int z4 = dataUnit[c4];
1313 			int z1 = (z2 + z3) * FIX_0_541196100;
1314 			int tmp2 = z1 + (z3 * (0 - FIX_1_847759065));
1315 			int tmp3 = z1 + (z2 * FIX_0_765366865);
1316 			int tmp0 = (z0 + z4) << 13;
1317 			int tmp1 = (z0 - z4) << 13;
1318 			int tmp10 = tmp0 + tmp3;
1319 			int tmp13 = tmp0 - tmp3;
1320 			int tmp11 = tmp1 + tmp2;
1321 			int tmp12 = tmp1 - tmp2;
1322 			/**
1323 			 * Odd part per figure 8; the matrix is unitary and hence its
1324 			 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
1325 			 */
1326 			tmp0 = dataUnit[c7];
1327 			tmp1 = dataUnit[c5];
1328 			tmp2 = dataUnit[c3];
1329 			tmp3 = dataUnit[c1];
1330 			z1 = tmp0 + tmp3;
1331 			z2 = tmp1 + tmp2;
1332 			z3 = tmp0 + tmp2;
1333 			z4 = tmp1 + tmp3;
1334 			z0 = (z3 + z4) * FIX_1_175875602;	/* sqrt(2) * c3 */
1335 
1336 			tmp0 *= FIX_0_298631336;		/* sqrt(2) * (-c1+c3+c5-c7) */
1337 			tmp1 *= FIX_2_053119869;		/* sqrt(2) * ( c1+c3-c5+c7) */
1338 			tmp2 *= FIX_3_072711026;		/* sqrt(2) * ( c1+c3+c5-c7) */
1339 			tmp3 *= FIX_1_501321110;		/* sqrt(2) * ( c1+c3-c5-c7) */
1340 			z1 *= 0 - FIX_0_899976223;	/* sqrt(2) * (c7-c3) */
1341 			z2 *= 0 - FIX_2_562915447;	/* sqrt(2) * (-c1-c3) */
1342 			z3 *= 0 - FIX_1_961570560;	/* sqrt(2) * (-c3-c5) */
1343 			z4 *= 0 - FIX_0_390180644;	/* sqrt(2) * (c5-c3) */
1344 
1345 			z3 += z0;
1346 			z4 += z0;
1347 
1348 			tmp0 += z1 + z3;
1349 			tmp1 += z2 + z4;
1350 			tmp2 += z2 + z3;
1351 			tmp3 += z1 + z4;
1352 
1353 			/* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
1354 			dataUnit[c0] = (tmp10 + tmp3 + 131072) >> 18;
1355 			dataUnit[c7] = (tmp10 - tmp3 + 131072) >> 18;
1356 			dataUnit[c1] = (tmp11 + tmp2 + 131072) >> 18;
1357 			dataUnit[c6] = (tmp11 - tmp2 + 131072) >> 18;
1358 			dataUnit[c2] = (tmp12 + tmp1 + 131072) >> 18;
1359 			dataUnit[c5] = (tmp12 - tmp1 + 131072) >> 18;
1360 			dataUnit[c3] = (tmp13 + tmp0 + 131072) >> 18;
1361 			dataUnit[c4] = (tmp13 - tmp0 + 131072) >> 18;
1362 		}
1363 	}
1364 }
1365 @Override
isFileFormat(LEDataInputStream stream)1366 boolean isFileFormat(LEDataInputStream stream) {
1367 	try {
1368 		JPEGStartOfImage soi = new JPEGStartOfImage(stream);
1369 		stream.unread(soi.reference);
1370 		return soi.verify();  // we no longer check for appN
1371 	} catch (Exception e) {
1372 		return false;
1373 	}
1374 }
isZeroInColumn(int[] dataUnit, int col)1375 boolean isZeroInColumn(int[] dataUnit, int col) {
1376 	return dataUnit[col + 8] == 0 && dataUnit[col + 16] == 0
1377 			&& dataUnit[col + 24] == 0 && dataUnit[col + 32] == 0
1378 			&& dataUnit[col + 40] == 0 && dataUnit[col + 48] == 0
1379 			&& dataUnit[col + 56] == 0;
1380 }
isZeroInRow(int[] dataUnit, int rIndex)1381 boolean isZeroInRow(int[] dataUnit, int rIndex) {
1382 	return dataUnit[rIndex + 1] == 0 && dataUnit[rIndex + 2] == 0
1383 			&& dataUnit[rIndex + 3] == 0 && dataUnit[rIndex + 4] == 0
1384 			&& dataUnit[rIndex + 5] == 0 && dataUnit[rIndex + 6] == 0
1385 			&& dataUnit[rIndex + 7] == 0;
1386 }
1387 @Override
loadFromByteStream()1388 ImageData[] loadFromByteStream() {
1389 	//TEMPORARY CODE
1390 	if (System.getProperty("org.eclipse.swt.internal.image.JPEGFileFormat_3.2") == null) {
1391 		return JPEGDecoder.loadFromByteStream(inputStream, loader);
1392 	}
1393 	JPEGStartOfImage soi = new JPEGStartOfImage(inputStream);
1394 	if (!soi.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
1395 	restartInterval = 0;
1396 
1397 	/* Process the tables preceding the frame header. */
1398 	processTables();
1399 
1400 	/* Start of Frame. */
1401 	frameHeader = new JPEGFrameHeader(inputStream);
1402 	if (!frameHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
1403 	imageWidth = frameHeader.getSamplesPerLine();
1404 	imageHeight = frameHeader.getNumberOfLines();
1405 	maxH = frameHeader.getMaxHFactor();
1406 	maxV = frameHeader.getMaxVFactor();
1407 	int mcuWidth = maxH * DCTSIZE;
1408 	int mcuHeight = maxV * DCTSIZE;
1409 	interleavedMcuCols = (imageWidth + mcuWidth - 1) / mcuWidth;
1410 	interleavedMcuRows = (imageHeight + mcuHeight - 1) / mcuHeight;
1411 	progressive = frameHeader.isProgressive();
1412 	samplePrecision = frameHeader.getSamplePrecision();
1413 	nComponents = frameHeader.getNumberOfImageComponents();
1414 	frameComponents = frameHeader.componentParameters;
1415 	componentIds = frameHeader.componentIdentifiers;
1416 	imageComponents = new byte[nComponents][];
1417 	if (progressive) {
1418 		// Progressive jpeg: need to keep all of the data units.
1419 		dataUnits = new int[nComponents][][];
1420 	} else {
1421 		// Sequential jpeg: only need one data unit.
1422 		dataUnit = new int[8 * 8];
1423 	}
1424 	for (int i = 0; i < nComponents; i++) {
1425 		int[] frameComponent = frameComponents[componentIds[i]];
1426 		int bufferSize = frameComponent[CW] * frameComponent[CH];
1427 		imageComponents[i] = new byte[bufferSize];
1428 		if (progressive) {
1429 			dataUnits[i] = new int[bufferSize][];
1430 		}
1431 	}
1432 
1433 	/* Process the tables preceding the scan header. */
1434 	processTables();
1435 
1436 	/* Start of Scan. */
1437 	scanHeader = new JPEGScanHeader(inputStream);
1438 	if (!scanHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
1439 
1440 	/* Process scan(s) and further tables until EOI. */
1441 	int progressiveScanCount = 0;
1442 	boolean done = false;
1443 	while(!done) {
1444 		resetInputBuffer();
1445 		precedingDCs = new int[4];
1446 		decodeScan();
1447 		if (progressive && loader.hasListeners()) {
1448 			ImageData imageData = createImageData();
1449 			loader.notifyListeners(new ImageLoaderEvent(loader, imageData, progressiveScanCount, false));
1450 			progressiveScanCount++;
1451 		}
1452 
1453 		/* Unread any buffered data before looking for tables again. */
1454 		int delta = 512 - bufferCurrentPosition - 1;
1455 		if (delta > 0) {
1456 			byte[] unreadBuffer = new byte[delta];
1457 			System.arraycopy(dataBuffer, bufferCurrentPosition + 1, unreadBuffer, 0, delta);
1458 			try {
1459 				inputStream.unread(unreadBuffer);
1460 			} catch (IOException e) {
1461 				SWT.error(SWT.ERROR_IO, e);
1462 			}
1463 		}
1464 
1465 		/* Process the tables preceding the next scan header. */
1466 		JPEGSegment jpegSegment = processTables();
1467 		if (jpegSegment == null || jpegSegment.getSegmentMarker() == EOI) {
1468 			done = true;
1469 		} else {
1470 			scanHeader = new JPEGScanHeader(inputStream);
1471 			if (!scanHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
1472 		}
1473 	}
1474 
1475 	if (progressive) {
1476 		for (int ymcu = 0; ymcu < interleavedMcuRows; ymcu++) {
1477 			for (int xmcu = 0; xmcu < interleavedMcuCols; xmcu++) {
1478 				for (int iComp = 0; iComp < nComponents; iComp++) {
1479 					int[] frameComponent = frameComponents[componentIds[iComp]];
1480 					int hi = frameComponent[HI];
1481 					int vi = frameComponent[VI];
1482 					int compWidth = frameComponent[CW];
1483 					for (int ivi = 0; ivi < vi; ivi++) {
1484 						for (int ihi = 0; ihi < hi; ihi++) {
1485 							int index = (ymcu * vi + ivi) * compWidth + xmcu * hi + ihi;
1486 							dataUnit = dataUnits[iComp][index];
1487 							dequantize(dataUnit, iComp);
1488 							inverseDCT(dataUnit);
1489 							storeData(dataUnit, iComp, xmcu, ymcu, hi, ihi, vi, ivi);
1490 						}
1491 					}
1492 				}
1493 			}
1494 		}
1495 		dataUnits = null; // release memory
1496 	}
1497 	ImageData imageData = createImageData();
1498 	if (progressive && loader.hasListeners()) {
1499 		loader.notifyListeners(new ImageLoaderEvent(loader, imageData, progressiveScanCount, true));
1500 	}
1501 	return new ImageData[] {imageData};
1502 }
createImageData()1503 ImageData createImageData() {
1504 	return ImageData.internal_new(
1505 		imageWidth,
1506 		imageHeight,
1507 		nComponents * samplePrecision,
1508 		setUpPalette(),
1509 		nComponents == 1 ? 4 : 1,
1510 		decodeImageComponents(),
1511 		0,
1512 		null,
1513 		null,
1514 		-1,
1515 		-1,
1516 		SWT.IMAGE_JPEG,
1517 		0,
1518 		0,
1519 		0,
1520 		0);
1521 }
nextBit()1522 int nextBit() {
1523 	if (currentBitCount != 0) {
1524 		currentBitCount--;
1525 		currentByte *= 2;
1526 		if (currentByte > 255) {
1527 			currentByte -= 256;
1528 			return 1;
1529 		} else {
1530 			return 0;
1531 		}
1532 	}
1533 	bufferCurrentPosition++;
1534 	if (bufferCurrentPosition >= 512) {
1535 		resetInputBuffer();
1536 		bufferCurrentPosition = 0;
1537 	}
1538 	currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
1539 	currentBitCount = 8;
1540 	byte nextByte;
1541 	if (bufferCurrentPosition == 511) {
1542 		resetInputBuffer();
1543 		currentBitCount = 8;
1544 		nextByte = dataBuffer[0];
1545 	} else {
1546 		nextByte = dataBuffer[bufferCurrentPosition + 1];
1547 	}
1548 	if (currentByte == 0xFF) {
1549 		if (nextByte == 0) {
1550 			bufferCurrentPosition ++;
1551 			currentBitCount--;
1552 			currentByte *= 2;
1553 			if (currentByte > 255) {
1554 				currentByte -= 256;
1555 				return 1;
1556 			} else {
1557 				return 0;
1558 			}
1559 		} else {
1560 			if ((nextByte & 0xFF) + 0xFF00 == DNL) {
1561 				getDNL();
1562 				return 0;
1563 			} else {
1564 				SWT.error(SWT.ERROR_INVALID_IMAGE);
1565 				return 0;
1566 			}
1567 		}
1568 	} else {
1569 		currentBitCount--;
1570 		currentByte *= 2;
1571 		if (currentByte > 255) {
1572 			currentByte -= 256;
1573 			return 1;
1574 		} else {
1575 			return 0;
1576 		}
1577 	}
1578 }
processRestartInterval()1579 void processRestartInterval() {
1580 	do {
1581 		bufferCurrentPosition++;
1582 		if (bufferCurrentPosition > 511) {
1583 			resetInputBuffer();
1584 			bufferCurrentPosition = 0;
1585 		}
1586 		currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
1587 	} while (currentByte != 0xFF);
1588 	while (currentByte == 0xFF) {
1589 		bufferCurrentPosition++;
1590 		if (bufferCurrentPosition > 511) {
1591 			resetInputBuffer();
1592 			bufferCurrentPosition = 0;
1593 		}
1594 		currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
1595 	}
1596 	if (currentByte != ((RST0 + nextRestartNumber) & 0xFF)) {
1597 		SWT.error(SWT.ERROR_INVALID_IMAGE);
1598 	}
1599 	bufferCurrentPosition++;
1600 	if (bufferCurrentPosition > 511) {
1601 		resetInputBuffer();
1602 		bufferCurrentPosition = 0;
1603 	}
1604 	currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
1605 	currentBitCount = 8;
1606 	restartsToGo = restartInterval;
1607 	nextRestartNumber = (nextRestartNumber + 1) & 0x7;
1608 	precedingDCs = new int[4];
1609 	eobrun = 0;
1610 }
1611 /* Process all markers until a frame header, scan header, or EOI is found. */
processTables()1612 JPEGSegment processTables() {
1613 	while (true) {
1614 		JPEGSegment jpegSegment = seekUnspecifiedMarker(inputStream);
1615 		if (jpegSegment == null) return null;
1616 		JPEGFrameHeader sof = new JPEGFrameHeader(jpegSegment.reference);
1617 		if (sof.verify()) {
1618 			return jpegSegment;
1619 		}
1620 		int marker = jpegSegment.getSegmentMarker();
1621 		switch (marker) {
1622 			case SOI: // there should only be one SOI per file
1623 				SWT.error(SWT.ERROR_INVALID_IMAGE);
1624 			case EOI:
1625 			case SOS:
1626 				return jpegSegment;
1627 			case DQT:
1628 				getDQT();
1629 				break;
1630 			case DHT:
1631 				getDHT();
1632 				break;
1633 			case DAC:
1634 				getDAC();
1635 				break;
1636 			case DRI:
1637 				getDRI();
1638 				break;
1639 			case APP0:
1640 				getAPP0();
1641 				break;
1642 			case COM:
1643 				getCOM();
1644 				break;
1645 			default:
1646 				skipSegmentFrom(inputStream);
1647 
1648 		}
1649 	}
1650 }
quantizeData(int[] dataUnit, int iComp)1651 void quantizeData(int[] dataUnit, int iComp) {
1652 	int[] qTable = quantizationTables[frameComponents[componentIds[iComp]][TQI]];
1653 	for (int i = 0; i < dataUnit.length; i++) {
1654 		int zzIndex = ZigZag8x8[i];
1655 		int data = dataUnit[zzIndex];
1656 		int absData = data < 0 ? 0 - data : data;
1657 		int qValue = qTable[i];
1658 		int q2 = qValue >> 1;
1659 		absData += q2;
1660 		if (absData < qValue) {
1661 			dataUnit[zzIndex] = 0;
1662 		} else {
1663 			absData /= qValue;
1664 			if (data >= 0) {
1665 				dataUnit[zzIndex] = absData;
1666 			} else {
1667 				dataUnit[zzIndex] = 0 - absData;
1668 			}
1669 		}
1670 	}
1671 }
receive(int nBits)1672 int receive(int nBits) {
1673 	int v = 0;
1674 	for (int i = 0; i < nBits; i++) {
1675 		v = v * 2 + nextBit();
1676 	}
1677 	return v;
1678 }
resetInputBuffer()1679 void resetInputBuffer() {
1680 	if (dataBuffer == null) {
1681 		dataBuffer = new byte[512];
1682 	}
1683 	try {
1684 		inputStream.read(dataBuffer);
1685 	} catch (IOException e) {
1686 		SWT.error(SWT.ERROR_IO, e);
1687 	}
1688 	currentBitCount = 0;
1689 	bufferCurrentPosition = -1;
1690 }
resetOutputBuffer()1691 void resetOutputBuffer() {
1692 	if (dataBuffer == null) {
1693 		dataBuffer = new byte[512];
1694 	} else {
1695 		try {
1696 			outputStream.write(dataBuffer, 0, bufferCurrentPosition);
1697 		} catch (IOException e) {
1698 			SWT.error(SWT.ERROR_IO, e);
1699 		}
1700 	}
1701 	bufferCurrentPosition = 0;
1702 }
seekUnspecifiedMarker(LEDataInputStream byteStream)1703 static JPEGSegment seekUnspecifiedMarker(LEDataInputStream byteStream) {
1704 	byte[] byteArray = new byte[2];
1705 	try {
1706 		while (true) {
1707 			if (byteStream.read(byteArray, 0, 1) != 1) return null;
1708 			if (byteArray[0] == (byte) 0xFF) {
1709 				if (byteStream.read(byteArray, 1, 1) != 1) return null;
1710 				if (byteArray[1] != (byte) 0xFF && byteArray[1] != 0) {
1711 					byteStream.unread(byteArray);
1712 					return new JPEGSegment(byteArray);
1713 				}
1714 			}
1715 		}
1716 	} catch (IOException e) {
1717 		SWT.error(SWT.ERROR_IO, e);
1718 	}
1719 	return null;
1720 }
setUpPalette()1721 PaletteData setUpPalette() {
1722 	if (nComponents == 1) {
1723 		RGB[] entries = new RGB[256];
1724 		for (int i = 0; i < 256; i++) {
1725 			entries[i] = new RGB(i, i, i);
1726 		}
1727 		return new PaletteData(entries);
1728 	}
1729 	return new PaletteData(0xFF, 0xFF00, 0xFF0000);
1730 }
skipSegmentFrom(LEDataInputStream byteStream)1731 static void skipSegmentFrom(LEDataInputStream byteStream) {
1732 	try {
1733 		byte[] byteArray = new byte[4];
1734 		JPEGSegment jpegSegment = new JPEGSegment(byteArray);
1735 
1736 		if (byteStream.read(byteArray) != byteArray.length) {
1737 			SWT.error(SWT.ERROR_INVALID_IMAGE);
1738 		}
1739 		if (!(byteArray[0] == -1 && byteArray[1] != 0 && byteArray[1] != -1)) {
1740 			SWT.error(SWT.ERROR_INVALID_IMAGE);
1741 		}
1742 		int delta = jpegSegment.getSegmentLength() - 2;
1743 		byteStream.skip(delta);
1744 	} catch (Exception e) {
1745 		SWT.error(SWT.ERROR_IO, e);
1746 	}
1747 }
storeData(int[] dataUnit, int iComp, int xmcu, int ymcu, int hi, int ihi, int vi, int ivi)1748 void storeData(int[] dataUnit, int iComp, int xmcu, int ymcu, int hi, int ihi, int vi, int ivi) {
1749 	byte[] compImage = imageComponents[iComp];
1750 	int[] frameComponent = frameComponents[componentIds[iComp]];
1751 	int compWidth = frameComponent[CW];
1752 	int destIndex = ((ymcu * vi + ivi) * compWidth * DCTSIZE) + ((xmcu * hi + ihi) * DCTSIZE);
1753 	int srcIndex = 0;
1754 	for (int i = 0; i < DCTSIZE; i++) {
1755 		for (int col = 0; col < DCTSIZE; col++) {
1756 			int x = dataUnit[srcIndex] + 128;
1757 			if (x < 0) {
1758 				x = 0;
1759 			} else {
1760 				if (x > 255) x = 255;
1761 			}
1762 			compImage[destIndex + col] = (byte)x;
1763 			srcIndex++;
1764 		}
1765 		destIndex += compWidth;
1766 	}
1767 }
1768 @Override
unloadIntoByteStream(ImageLoader loader)1769 void unloadIntoByteStream(ImageLoader loader) {
1770 	ImageData image = loader.data[0];
1771 	if (!new JPEGStartOfImage().writeToStream(outputStream)) {
1772 		SWT.error(SWT.ERROR_IO);
1773 	}
1774 	JPEGAppn appn = new JPEGAppn(new byte[] {(byte)0xFF, (byte)0xE0, 0, 0x10, 0x4A, 0x46, 0x49, 0x46, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0});
1775 	if (!appn.writeToStream(outputStream)) {
1776 		SWT.error(SWT.ERROR_IO);
1777 	}
1778 	quantizationTables = new int[4][];
1779 	JPEGQuantizationTable chromDQT = JPEGQuantizationTable.defaultChrominanceTable();
1780 	int encoderQFactor = loader.compression >= 1 && loader.compression <= 100 ? loader.compression : 75;
1781 	chromDQT.scaleBy(encoderQFactor);
1782 	int[] jpegDQTKeys = chromDQT.getQuantizationTablesKeys();
1783 	int[][] jpegDQTValues = chromDQT.getQuantizationTablesValues();
1784 	for (int i = 0; i < jpegDQTKeys.length; i++) {
1785 		quantizationTables[jpegDQTKeys[i]] = jpegDQTValues[i];
1786 	}
1787 	JPEGQuantizationTable lumDQT = JPEGQuantizationTable.defaultLuminanceTable();
1788 	lumDQT.scaleBy(encoderQFactor);
1789 	jpegDQTKeys = lumDQT.getQuantizationTablesKeys();
1790 	jpegDQTValues = lumDQT.getQuantizationTablesValues();
1791 	for (int i = 0; i < jpegDQTKeys.length; i++) {
1792 		quantizationTables[jpegDQTKeys[i]] = jpegDQTValues[i];
1793 	}
1794 	if (!lumDQT.writeToStream(outputStream)) {
1795 		SWT.error(SWT.ERROR_IO);
1796 	}
1797 	if (!chromDQT.writeToStream(outputStream)) {
1798 		SWT.error(SWT.ERROR_IO);
1799 	}
1800 	int frameLength, scanLength, precision;
1801 	int[][] frameParams, scanParams;
1802 	if (image.depth == 1) {
1803 		frameLength = 11;
1804 		frameParams = new int[1][];
1805 		frameParams[0] = new int[] {1, 1, 1, 0, 0};
1806 		scanParams = new int[1][];
1807 		scanParams[0] = new int[] {0, 0};
1808 		scanLength = 8;
1809 		nComponents = 1;
1810 		precision = 1;
1811 	} else {
1812 		frameLength = 17;
1813 		frameParams = new int[3][];
1814 		frameParams[0] = new int[] {0, 2, 2, 0, 0};
1815 		frameParams[1] = new int[] {1, 1, 1, 0, 0};
1816 		frameParams[2] = new int[] {1, 1, 1, 0, 0};
1817 		scanParams = new int[3][];
1818 		scanParams[0] = new int[] {0, 0};
1819 		scanParams[1] = new int[] {1, 1};
1820 		scanParams[2] = new int[] {1, 1};
1821 		scanLength = 12;
1822 		nComponents = 3;
1823 		precision = 8;
1824 	}
1825 	imageWidth = image.width;
1826 	imageHeight = image.height;
1827 	frameHeader = new JPEGFrameHeader(new byte[19]);
1828 	frameHeader.setSegmentMarker(SOF0);
1829 	frameHeader.setSegmentLength(frameLength);
1830 	frameHeader.setSamplePrecision(precision);
1831 	frameHeader.setSamplesPerLine(imageWidth);
1832 	frameHeader.setNumberOfLines(imageHeight);
1833 	frameHeader.setNumberOfImageComponents(nComponents);
1834 	frameHeader.componentParameters = frameParams;
1835 	frameHeader.componentIdentifiers = new int[] {0, 1, 2};
1836 	frameHeader.initializeContents();
1837 	if (!frameHeader.writeToStream(outputStream)) {
1838 		SWT.error(SWT.ERROR_IO);
1839 	}
1840 	frameComponents = frameParams;
1841 	componentIds = frameHeader.componentIdentifiers;
1842 	maxH = frameHeader.getMaxHFactor();
1843 	maxV = frameHeader.getMaxVFactor();
1844 	int mcuWidth = maxH * DCTSIZE;
1845 	int mcuHeight = maxV * DCTSIZE;
1846 	interleavedMcuCols = (imageWidth + mcuWidth - 1) / mcuWidth;
1847 	interleavedMcuRows = (imageHeight + mcuHeight - 1) / mcuHeight;
1848 	acHuffmanTables = new JPEGHuffmanTable[4];
1849 	dcHuffmanTables = new JPEGHuffmanTable[4];
1850 	JPEGHuffmanTable[] dhtTables = new JPEGHuffmanTable[] {
1851 		JPEGHuffmanTable.getDefaultDCLuminanceTable(),
1852 		JPEGHuffmanTable.getDefaultDCChrominanceTable(),
1853 		JPEGHuffmanTable.getDefaultACLuminanceTable(),
1854 		JPEGHuffmanTable.getDefaultACChrominanceTable()
1855 	};
1856 	for (JPEGHuffmanTable dhtTable : dhtTables) {
1857 		if (!dhtTable.writeToStream(outputStream)) {
1858 			SWT.error(SWT.ERROR_IO);
1859 		}
1860 		for (JPEGHuffmanTable huffmanTable : dhtTable.getAllTables()) {
1861 			if (huffmanTable.getTableClass() == 0) {
1862 				dcHuffmanTables[huffmanTable.getTableIdentifier()] = huffmanTable;
1863 			} else {
1864 				acHuffmanTables[huffmanTable.getTableIdentifier()] = huffmanTable;
1865 			}
1866 		}
1867 	}
1868 	precedingDCs = new int[4];
1869 	scanHeader = new JPEGScanHeader(new byte[14]);
1870 	scanHeader.setSegmentMarker(SOS);
1871 	scanHeader.setSegmentLength(scanLength);
1872 	scanHeader.setNumberOfImageComponents(nComponents);
1873 	scanHeader.setStartOfSpectralSelection(0);
1874 	scanHeader.setEndOfSpectralSelection(63);
1875 	scanHeader.componentParameters = scanParams;
1876 	scanHeader.initializeContents();
1877 	if (!scanHeader.writeToStream(outputStream)) {
1878 		SWT.error(SWT.ERROR_IO);
1879 	}
1880 	convertImageToYCbCr(image);
1881 	resetOutputBuffer();
1882 	currentByte = 0;
1883 	currentBitCount = 0;
1884 	encodeScan();
1885 	if (!new JPEGEndOfImage().writeToStream(outputStream)) {
1886 		SWT.error(SWT.ERROR_IO);
1887 	}
1888 }
1889 }
1890