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