1 /*******************************************************************************
2 * Copyright (c) 2000, 2014 IBM Corporation and others.
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/
9 * SPDX-License-Identifier: EPL-2.0
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.
16 * IBM Corporation - initial API and implementation
17 *******************************************************************************/
18 package org.eclipse.swt.internal.image;
21 import org.eclipse.swt.*;
22 import org.eclipse.swt.graphics.*;
25 public final class JPEGFileFormat extends FileFormat {
27 JPEGFrameHeader frameHeader;
28 int imageWidth, imageHeight;
29 int interleavedMcuCols, interleavedMcuRows;
34 int[][] frameComponents;
36 byte[][] imageComponents;
40 JPEGScanHeader scanHeader;
43 int bufferCurrentPosition;
45 int nextRestartNumber;
46 JPEGHuffmanTable[] acHuffmanTables;
47 JPEGHuffmanTable[] dcHuffmanTables;
48 int[][] quantizationTables;
50 int encoderQFactor = 75;
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;
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[] {
124 new RGB(0x80,0x80,0),
126 new RGB(0x80,0,0x80),
127 new RGB(0,0x80,0x80),
128 new RGB(0xC0,0xC0,0xC0),
129 new RGB(0x80,0x80,0x80),
132 new RGB(0xFF,0xFF,0),
134 new RGB(0xFF,0,0xFF),
135 new RGB(0,0xFF,0xFF),
136 new RGB(0xFF,0xFF,0xFF),
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
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
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
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;
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;
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;
207 /* Initialize BitCount Table */
210 int [] nBitsTable = new int[2048];
212 for (int i = 1; i < nBitsTable.length; i++) {
217 nBitsTable[i] = nBits;
219 NBitsTable = nBitsTable;
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]];
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);
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++) {
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;
248 imageComponents[ID_CB][destRowIndex + xPos] = (byte)(sum / vhFactor);
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++) {
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;
262 imageComponents[ID_CR][destRowIndex + xPos] = (byte)(sum / vhFactor);
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;
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);
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++) {
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]--;
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;
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];
338 compress(image, dataYComp, dataCbComp, dataCrComp);
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++) {
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]--;
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];
382 compress(image, dataYComp, dataCbComp, dataCrComp);
384 byte[] convertCMYKToRGB() {
385 /* Unsupported CMYK format. Answer an empty byte array. */
388 void convertImageToYCbCr(ImageData image) {
389 switch (image.depth) {
391 convert4BitRGBToYCbCr(image);
394 convert8BitRGBToYCbCr(image);
399 convertMultiRGBToYCbCr(image);
402 SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
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);
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);
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);
456 compress(image, dataYComp, dataCbComp, dataCrComp);
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];
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;
471 if (y > 255) y = 255;
473 if (j >= imageWidth) {
476 data[destIndex] = (byte)y;
483 byte[] convertYCbCrToRGB() {
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.)
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.
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
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.
511 int bSize = imageWidth * imageHeight * nComponents;
512 byte[] rgbData = new byte[bSize];
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];
531 if (r > 255) r = 255;
536 if (g > 255) g = 255;
541 if (b > 255) b = 255;
543 rgbData[destIndex] = (byte)b;
544 rgbData[destIndex + 1] = (byte)g;
545 rgbData[destIndex + 2] = (byte)r;
552 void decodeACCoefficients(int[] dataUnit, int iComp) {
553 int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
554 JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
557 int rs = decodeUsingTable(acTable);
568 int bits = receive(s);
569 dataUnit[ZigZag8x8[k]] = extendBy(bits, s);
574 void decodeACFirstCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit) {
579 int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
580 JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
583 int rs = decodeUsingTable(acTable);
590 eobrun = (1 << r) + receive(r) - 1;
595 int bits = receive(s);
596 dataUnit[ZigZag8x8[k]] = extendBy(bits, s) << 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]];
608 int zzIndex = ZigZag8x8[k];
609 if (dataUnit[zzIndex] != 0) {
610 dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
616 int rs = decodeUsingTable(acTable);
622 while (zeros < 16 && k <= end) {
623 int zzIndex = ZigZag8x8[k];
624 if (dataUnit[zzIndex] != 0) {
625 dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
632 eobrun = (1 << r) + receive(r);
635 int bit = receive(s);
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);
645 zzIndex = ZigZag8x8[k];
648 dataUnit[zzIndex] = 1 << approxBit;
650 dataUnit[zzIndex] = -1 << approxBit;
657 int refineAC(int ac, int approxBit) {
661 ac += 1 << approxBit;
666 ac += -1 << 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]];
675 if (progressive && !first) {
677 lastDC = dataUnit[0] + (bit << approxBit);
679 lastDC = precedingDCs[iComp];
680 int nBits = decodeUsingTable(dcTable);
682 int bits = receive(nBits);
683 int diff = extendBy(bits, nBits);
685 precedingDCs[iComp] = lastDC;
688 lastDC = lastDC << approxBit;
691 dataUnit[0] = lastDC;
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];
700 byte[] decodeImageComponents() {
701 if (nComponents == 3) { // compIds 1, 2, 3
702 return convertYCbCrToRGB();
704 // if (nComponents == 3) { // compIds 1, 4, 5
705 // Unsupported CMYK format.
706 // return convertYIQToRGB();
708 if (nComponents == 4) {
709 return convertCMYKToRGB();
711 return convertYToRGB();
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) {
719 int[] frameComponent = frameComponents[componentIds[scanComponent]];
720 int hi = frameComponent[HI];
721 int vi = frameComponent[VI];
722 if (nComponentsInScan == 1) {
726 int compWidth = frameComponent[CW];
727 for (int ivi = 0; ivi < vi; ivi++) {
728 for (int ihi = 0; ihi < hi; ihi++) {
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;
739 // Sequential: Clear and reuse the data unit buffer.
740 for (int i = 0; i < dataUnit.length; i++) {
744 if (!progressive || scanHeader.isDCProgressiveScan()) {
745 decodeDCCoefficient(dataUnit, scanComponent, first, approxBit);
748 decodeACCoefficients(dataUnit, scanComponent);
750 if (scanHeader.isACProgressiveScan()) {
752 decodeACFirstCoefficients(dataUnit, scanComponent, start, end, approxBit);
754 decodeACRefineCoefficients(dataUnit, scanComponent, start, end, approxBit);
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);
766 if (!progressive || (progressive && loader.hasListeners())) {
767 dequantize(dataUnit, scanComponent);
768 inverseDCT(dataUnit);
769 storeData(dataUnit, scanComponent, xmcu, ymcu, hi, ihi, vi, ivi);
776 if (progressive && !scanHeader.verifyProgressiveScan()) {
777 SWT.error(SWT.ERROR_INVALID_IMAGE);
779 int nComponentsInScan = scanHeader.getNumberOfImageComponents();
780 int mcuRowsInScan = interleavedMcuRows;
781 int mcusPerRow = interleavedMcuCols;
782 if (nComponentsInScan == 1) {
784 int scanComponent = 0;
785 while (scanHeader.componentParameters[componentIds[scanComponent]] == null) {
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;
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();
808 decodeMCUAtXAndY(xmcu, ymcu, nComponentsInScan, first, start, end, approxBit);
812 int decodeUsingTable(JPEGHuffmanTable huffmanTable) {
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();
823 int j = valPtrs[i] + code - minCodes[i];
826 void emit(int huffCode, int nBits) {
828 SWT.error(SWT.ERROR_INVALID_IMAGE);
830 int[] power2m1 = new int[] {
831 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191,
832 16383, 32767, 65535, 131125
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;
849 currentBitCount += nBits;
850 if (currentBitCount >= 8) {
851 currentByte += codeBuffer[2];
852 emitByte((byte)currentByte);
853 currentByte = codeBuffer[1];
854 currentBitCount -= 8;
856 currentByte += codeBuffer[2];
860 void emitByte(byte byteValue) {
861 if (bufferCurrentPosition >= 512) {
864 dataBuffer[bufferCurrentPosition] = byteValue;
865 bufferCurrentPosition++;
866 if (byteValue == -1) {
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;
879 int acValue = dataUnit[ZigZag8x8[k - 1]];
882 emit(ehCodes[0], ehSizes[0] & 0xFF);
888 emit(ehCodes[0xF0], ehSizes[0xF0] & 0xFF);
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);
899 int nBits = NBitsTable[acValue];
900 int rs = r * 16 + nBits;
901 emit(ehCodes[rs], ehSizes[rs] & 0xFF);
902 emit(acValue, nBits);
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;
916 int absDiff = 0 - diff;
917 int nBits = NBitsTable[absDiff];
918 emit(dcTable.ehCodes[nBits], dcTable.ehCodeLengths[nBits]);
919 emit(0xFFFFFF - absDiff, nBits);
921 int nBits = NBitsTable[diff];
922 emit(dcTable.ehCodes[nBits], dcTable.ehCodeLengths[nBits]);
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);
947 for (int ymcu = 0; ymcu < interleavedMcuRows; ymcu++) {
948 for (int xmcu = 0; xmcu < interleavedMcuCols; xmcu++) {
949 encodeMCUAtXAndY(xmcu, ymcu);
952 if (currentBitCount != 0) {
953 emitByte((byte)currentByte);
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];
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;
976 int extendBy(int diff, int t) {
977 if (diff < ExtendTest[t]) {
978 return diff + ExtendOffset[t];
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);
991 for (int i = 0; i < DCTSIZE; i++) {
992 for (int col = 0; col < DCTSIZE; col++) {
993 dataUnit[destIndex] = (compImage[srcIndex + col] & 0xFF) - 128;
996 srcIndex += compWidth;
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];
1012 * Even part per LL&M figure 1 --- note that published figure
1013 * is faulty; rotator 'sqrt(2)*c1' should be 'sqrt(2)*c6'.
1015 int tmp10 = tmp0 + tmp3;
1016 int tmp13 = tmp0 - tmp3;
1017 int tmp11 = tmp1 + tmp2;
1018 int tmp12 = tmp1 - tmp2;
1020 dataUnit[rIndex] = (tmp10 + tmp11) * 4;
1021 dataUnit[rIndex + 4] = (tmp10 - tmp11) * 4;
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]--;
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.
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
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)
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]--;
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.
1073 for (int col = 0; col < 8; col++) {
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];
1092 * Even part per LL&M figure 1 --- note that published figure
1093 * is faulty; rotator 'sqrt(2)*c1' should be 'sqrt(2)*c6'.
1095 int tmp10 = tmp0 + tmp3;
1096 int tmp13 = tmp0 - tmp3;
1097 int tmp11 = tmp1 + tmp2;
1098 int tmp12 = tmp1 - tmp2;
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]--;
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]--;
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.
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
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)
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]--;
1153 JPEGAppn appn = new JPEGAppn(inputStream);
1154 if (!appn.verify()) {
1155 SWT.error(SWT.ERROR_INVALID_IMAGE);
1159 new JPEGComment(inputStream);
1162 new JPEGArithmeticConditioningTable(inputStream);
1165 JPEGHuffmanTable dht = new JPEGHuffmanTable(inputStream);
1166 if (!dht.verify()) {
1167 SWT.error(SWT.ERROR_INVALID_IMAGE);
1169 if (acHuffmanTables == null) {
1170 acHuffmanTables = new JPEGHuffmanTable[4];
1172 if (dcHuffmanTables == null) {
1173 dcHuffmanTables = new JPEGHuffmanTable[4];
1175 JPEGHuffmanTable[] dhtTables = dht.getAllTables();
1176 for (int i = 0; i < dhtTables.length; i++) {
1177 JPEGHuffmanTable dhtTable = dhtTables[i];
1178 if (dhtTable.getTableClass() == 0) {
1179 dcHuffmanTables[dhtTable.getTableIdentifier()] = dhtTable;
1181 acHuffmanTables[dhtTable.getTableIdentifier()] = dhtTable;
1186 new JPEGRestartInterval(inputStream);
1189 JPEGQuantizationTable dqt = new JPEGQuantizationTable(inputStream);
1190 int[][] currentTables = quantizationTables;
1191 if (currentTables == null) {
1192 currentTables = new int[4][];
1194 int[] dqtTablesKeys = dqt.getQuantizationTablesKeys();
1195 int[][] dqtTablesValues = dqt.getQuantizationTablesValues();
1196 for (int i = 0; i < dqtTablesKeys.length; i++) {
1197 int index = dqtTablesKeys[i];
1198 currentTables[index] = dqtTablesValues[i];
1200 quantizationTables = currentTables;
1203 JPEGRestartInterval dri = new JPEGRestartInterval(inputStream);
1204 if (!dri.verify()) {
1205 SWT.error(SWT.ERROR_INVALID_IMAGE);
1207 restartInterval = dri.getRestartInterval();
1209 void inverseDCT(int[] dataUnit) {
1210 for (int row = 0; row < 8; row++) {
1211 int rIndex = row * DCTSIZE;
1213 * Due to quantization, we will usually find that many of the input
1214 * coefficients are zero, especially the AC terms. We can exploit this
1215 * by short-circuiting the IDCT calculation for any row in which all
1216 * the AC terms are zero. In that case each output is equal to the
1217 * DC coefficient (with scale factor as needed).
1218 * With typical images and quantization tables, half or more of the
1219 * row DCT calculations can be simplified this way.
1221 if (isZeroInRow(dataUnit, rIndex)) {
1222 int dcVal = dataUnit[rIndex] << 2;
1223 for (int i = rIndex + 7; i >= rIndex; i--) {
1224 dataUnit[i] = dcVal;
1228 * Even part: reverse the even part of the forward DCT.
1229 * The rotator is sqrt(2)*c(-6).
1231 int z2 = dataUnit[rIndex + 2];
1232 int z3 = dataUnit[rIndex + 6];
1233 int z1 = (z2 + z3) * FIX_0_541196100;
1234 int tmp2 = z1 + (z3 * (0 - FIX_1_847759065));
1235 int tmp3 = z1 + (z2 * FIX_0_765366865);
1236 int tmp0 = (dataUnit[rIndex] + dataUnit[rIndex + 4]) << 13;
1237 int tmp1 = (dataUnit[rIndex] - dataUnit[rIndex + 4]) << 13;
1238 int tmp10 = tmp0 + tmp3;
1239 int tmp13 = tmp0 - tmp3;
1240 int tmp11 = tmp1 + tmp2;
1241 int tmp12 = tmp1 - tmp2;
1243 * Odd part per figure 8; the matrix is unitary and hence its
1244 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
1246 tmp0 = dataUnit[rIndex + 7];
1247 tmp1 = dataUnit[rIndex + 5];
1248 tmp2 = dataUnit[rIndex + 3];
1249 tmp3 = dataUnit[rIndex + 1];
1253 int z4 = tmp1 + tmp3;
1254 int z5 = (z3 + z4) * FIX_1_175875602; /* sqrt(2) * c3 */
1256 tmp0 *= FIX_0_298631336; /* sqrt(2) * (-c1+c3+c5-c7) */
1257 tmp1 *= FIX_2_053119869; /* sqrt(2) * ( c1+c3-c5+c7) */
1258 tmp2 *= FIX_3_072711026; /* sqrt(2) * ( c1+c3+c5-c7) */
1259 tmp3 *= FIX_1_501321110; /* sqrt(2) * ( c1+c3-c5-c7) */
1260 z1 *= 0 - FIX_0_899976223; /* sqrt(2) * (c7-c3) */
1261 z2 *= 0 - FIX_2_562915447; /* sqrt(2) * (-c1-c3) */
1262 z3 *= 0 - FIX_1_961570560; /* sqrt(2) * (-c3-c5) */
1263 z4 *= 0 - FIX_0_390180644; /* sqrt(2) * (c5-c3) */
1272 dataUnit[rIndex] = (tmp10 + tmp3 + 1024) >> 11;
1273 dataUnit[rIndex + 7] = (tmp10 - tmp3 + 1024) >> 11;
1274 dataUnit[rIndex + 1] = (tmp11 + tmp2 + 1024) >> 11;
1275 dataUnit[rIndex + 6] = (tmp11 - tmp2 + 1024) >> 11;
1276 dataUnit[rIndex + 2] = (tmp12 + tmp1 + 1024) >> 11;
1277 dataUnit[rIndex + 5] = (tmp12 - tmp1 + 1024) >> 11;
1278 dataUnit[rIndex + 3] = (tmp13 + tmp0 + 1024) >> 11;
1279 dataUnit[rIndex + 4] = (tmp13 - tmp0 + 1024) >> 11;
1283 * Pass 2: process columns.
1284 * Note that we must descale the results by a factor of 8 == 2**3,
1285 * and also undo the PASS1_BITS scaling.
1287 for (int col = 0; col < 8; col++) {
1296 if (isZeroInColumn(dataUnit, col)) {
1297 int dcVal = (dataUnit[c0] + 16) >> 5;
1298 dataUnit[c0] = dcVal;
1299 dataUnit[c1] = dcVal;
1300 dataUnit[c2] = dcVal;
1301 dataUnit[c3] = dcVal;
1302 dataUnit[c4] = dcVal;
1303 dataUnit[c5] = dcVal;
1304 dataUnit[c6] = dcVal;
1305 dataUnit[c7] = dcVal;
1308 * Even part: reverse the even part of the forward DCT.
1309 * The rotator is sqrt(2)*c(-6).
1311 int z0 = dataUnit[c0];
1312 int z2 = dataUnit[c2];
1313 int z3 = dataUnit[c6];
1314 int z4 = dataUnit[c4];
1315 int z1 = (z2 + z3) * FIX_0_541196100;
1316 int tmp2 = z1 + (z3 * (0 - FIX_1_847759065));
1317 int tmp3 = z1 + (z2 * FIX_0_765366865);
1318 int tmp0 = (z0 + z4) << 13;
1319 int tmp1 = (z0 - z4) << 13;
1320 int tmp10 = tmp0 + tmp3;
1321 int tmp13 = tmp0 - tmp3;
1322 int tmp11 = tmp1 + tmp2;
1323 int tmp12 = tmp1 - tmp2;
1325 * Odd part per figure 8; the matrix is unitary and hence its
1326 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
1328 tmp0 = dataUnit[c7];
1329 tmp1 = dataUnit[c5];
1330 tmp2 = dataUnit[c3];
1331 tmp3 = dataUnit[c1];
1336 z0 = (z3 + z4) * FIX_1_175875602; /* sqrt(2) * c3 */
1338 tmp0 *= FIX_0_298631336; /* sqrt(2) * (-c1+c3+c5-c7) */
1339 tmp1 *= FIX_2_053119869; /* sqrt(2) * ( c1+c3-c5+c7) */
1340 tmp2 *= FIX_3_072711026; /* sqrt(2) * ( c1+c3+c5-c7) */
1341 tmp3 *= FIX_1_501321110; /* sqrt(2) * ( c1+c3-c5-c7) */
1342 z1 *= 0 - FIX_0_899976223; /* sqrt(2) * (c7-c3) */
1343 z2 *= 0 - FIX_2_562915447; /* sqrt(2) * (-c1-c3) */
1344 z3 *= 0 - FIX_1_961570560; /* sqrt(2) * (-c3-c5) */
1345 z4 *= 0 - FIX_0_390180644; /* sqrt(2) * (c5-c3) */
1355 /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
1356 dataUnit[c0] = (tmp10 + tmp3 + 131072) >> 18;
1357 dataUnit[c7] = (tmp10 - tmp3 + 131072) >> 18;
1358 dataUnit[c1] = (tmp11 + tmp2 + 131072) >> 18;
1359 dataUnit[c6] = (tmp11 - tmp2 + 131072) >> 18;
1360 dataUnit[c2] = (tmp12 + tmp1 + 131072) >> 18;
1361 dataUnit[c5] = (tmp12 - tmp1 + 131072) >> 18;
1362 dataUnit[c3] = (tmp13 + tmp0 + 131072) >> 18;
1363 dataUnit[c4] = (tmp13 - tmp0 + 131072) >> 18;
1368 boolean isFileFormat(LEDataInputStream stream) {
1370 JPEGStartOfImage soi = new JPEGStartOfImage(stream);
1371 stream.unread(soi.reference);
1372 return soi.verify(); // we no longer check for appN
1373 } catch (Exception e) {
1377 boolean isZeroInColumn(int[] dataUnit, int col) {
1378 return dataUnit[col + 8] == 0 && dataUnit[col + 16] == 0
1379 && dataUnit[col + 24] == 0 && dataUnit[col + 32] == 0
1380 && dataUnit[col + 40] == 0 && dataUnit[col + 48] == 0
1381 && dataUnit[col + 56] == 0;
1383 boolean isZeroInRow(int[] dataUnit, int rIndex) {
1384 return dataUnit[rIndex + 1] == 0 && dataUnit[rIndex + 2] == 0
1385 && dataUnit[rIndex + 3] == 0 && dataUnit[rIndex + 4] == 0
1386 && dataUnit[rIndex + 5] == 0 && dataUnit[rIndex + 6] == 0
1387 && dataUnit[rIndex + 7] == 0;
1390 ImageData[] loadFromByteStream() {
1392 if (System.getProperty("org.eclipse.swt.internal.image.JPEGFileFormat_3.2") == null) {
1393 return JPEGDecoder.loadFromByteStream(inputStream, loader);
1395 JPEGStartOfImage soi = new JPEGStartOfImage(inputStream);
1396 if (!soi.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
1397 restartInterval = 0;
1399 /* Process the tables preceding the frame header. */
1402 /* Start of Frame. */
1403 frameHeader = new JPEGFrameHeader(inputStream);
1404 if (!frameHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
1405 imageWidth = frameHeader.getSamplesPerLine();
1406 imageHeight = frameHeader.getNumberOfLines();
1407 maxH = frameHeader.getMaxHFactor();
1408 maxV = frameHeader.getMaxVFactor();
1409 int mcuWidth = maxH * DCTSIZE;
1410 int mcuHeight = maxV * DCTSIZE;
1411 interleavedMcuCols = (imageWidth + mcuWidth - 1) / mcuWidth;
1412 interleavedMcuRows = (imageHeight + mcuHeight - 1) / mcuHeight;
1413 progressive = frameHeader.isProgressive();
1414 samplePrecision = frameHeader.getSamplePrecision();
1415 nComponents = frameHeader.getNumberOfImageComponents();
1416 frameComponents = frameHeader.componentParameters;
1417 componentIds = frameHeader.componentIdentifiers;
1418 imageComponents = new byte[nComponents][];
1420 // Progressive jpeg: need to keep all of the data units.
1421 dataUnits = new int[nComponents][][];
1423 // Sequential jpeg: only need one data unit.
1424 dataUnit = new int[8 * 8];
1426 for (int i = 0; i < nComponents; i++) {
1427 int[] frameComponent = frameComponents[componentIds[i]];
1428 int bufferSize = frameComponent[CW] * frameComponent[CH];
1429 imageComponents[i] = new byte[bufferSize];
1431 dataUnits[i] = new int[bufferSize][];
1435 /* Process the tables preceding the scan header. */
1438 /* Start of Scan. */
1439 scanHeader = new JPEGScanHeader(inputStream);
1440 if (!scanHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
1442 /* Process scan(s) and further tables until EOI. */
1443 int progressiveScanCount = 0;
1444 boolean done = false;
1447 precedingDCs = new int[4];
1449 if (progressive && loader.hasListeners()) {
1450 ImageData imageData = createImageData();
1451 loader.notifyListeners(new ImageLoaderEvent(loader, imageData, progressiveScanCount, false));
1452 progressiveScanCount++;
1455 /* Unread any buffered data before looking for tables again. */
1456 int delta = 512 - bufferCurrentPosition - 1;
1458 byte[] unreadBuffer = new byte[delta];
1459 System.arraycopy(dataBuffer, bufferCurrentPosition + 1, unreadBuffer, 0, delta);
1461 inputStream.unread(unreadBuffer);
1462 } catch (IOException e) {
1463 SWT.error(SWT.ERROR_IO, e);
1467 /* Process the tables preceding the next scan header. */
1468 JPEGSegment jpegSegment = processTables();
1469 if (jpegSegment == null || jpegSegment.getSegmentMarker() == EOI) {
1472 scanHeader = new JPEGScanHeader(inputStream);
1473 if (!scanHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
1478 for (int ymcu = 0; ymcu < interleavedMcuRows; ymcu++) {
1479 for (int xmcu = 0; xmcu < interleavedMcuCols; xmcu++) {
1480 for (int iComp = 0; iComp < nComponents; iComp++) {
1481 int[] frameComponent = frameComponents[componentIds[iComp]];
1482 int hi = frameComponent[HI];
1483 int vi = frameComponent[VI];
1484 int compWidth = frameComponent[CW];
1485 for (int ivi = 0; ivi < vi; ivi++) {
1486 for (int ihi = 0; ihi < hi; ihi++) {
1487 int index = (ymcu * vi + ivi) * compWidth + xmcu * hi + ihi;
1488 dataUnit = dataUnits[iComp][index];
1489 dequantize(dataUnit, iComp);
1490 inverseDCT(dataUnit);
1491 storeData(dataUnit, iComp, xmcu, ymcu, hi, ihi, vi, ivi);
1497 dataUnits = null; // release memory
1499 ImageData imageData = createImageData();
1500 if (progressive && loader.hasListeners()) {
1501 loader.notifyListeners(new ImageLoaderEvent(loader, imageData, progressiveScanCount, true));
1503 return new ImageData[] {imageData};
1505 ImageData createImageData() {
1506 return ImageData.internal_new(
1509 nComponents * samplePrecision,
1511 nComponents == 1 ? 4 : 1,
1512 decodeImageComponents(),
1525 if (currentBitCount != 0) {
1528 if (currentByte > 255) {
1535 bufferCurrentPosition++;
1536 if (bufferCurrentPosition >= 512) {
1538 bufferCurrentPosition = 0;
1540 currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
1541 currentBitCount = 8;
1543 if (bufferCurrentPosition == 511) {
1545 currentBitCount = 8;
1546 nextByte = dataBuffer[0];
1548 nextByte = dataBuffer[bufferCurrentPosition + 1];
1550 if (currentByte == 0xFF) {
1551 if (nextByte == 0) {
1552 bufferCurrentPosition ++;
1555 if (currentByte > 255) {
1562 if ((nextByte & 0xFF) + 0xFF00 == DNL) {
1566 SWT.error(SWT.ERROR_INVALID_IMAGE);
1573 if (currentByte > 255) {
1581 void processRestartInterval() {
1583 bufferCurrentPosition++;
1584 if (bufferCurrentPosition > 511) {
1586 bufferCurrentPosition = 0;
1588 currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
1589 } while (currentByte != 0xFF);
1590 while (currentByte == 0xFF) {
1591 bufferCurrentPosition++;
1592 if (bufferCurrentPosition > 511) {
1594 bufferCurrentPosition = 0;
1596 currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
1598 if (currentByte != ((RST0 + nextRestartNumber) & 0xFF)) {
1599 SWT.error(SWT.ERROR_INVALID_IMAGE);
1601 bufferCurrentPosition++;
1602 if (bufferCurrentPosition > 511) {
1604 bufferCurrentPosition = 0;
1606 currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
1607 currentBitCount = 8;
1608 restartsToGo = restartInterval;
1609 nextRestartNumber = (nextRestartNumber + 1) & 0x7;
1610 precedingDCs = new int[4];
1613 /* Process all markers until a frame header, scan header, or EOI is found. */
1614 JPEGSegment processTables() {
1616 JPEGSegment jpegSegment = seekUnspecifiedMarker(inputStream);
1617 if (jpegSegment == null) return null;
1618 JPEGFrameHeader sof = new JPEGFrameHeader(jpegSegment.reference);
1622 int marker = jpegSegment.getSegmentMarker();
1624 case SOI: // there should only be one SOI per file
1625 SWT.error(SWT.ERROR_INVALID_IMAGE);
1648 skipSegmentFrom(inputStream);
1653 void quantizeData(int[] dataUnit, int iComp) {
1654 int[] qTable = quantizationTables[frameComponents[componentIds[iComp]][TQI]];
1655 for (int i = 0; i < dataUnit.length; i++) {
1656 int zzIndex = ZigZag8x8[i];
1657 int data = dataUnit[zzIndex];
1658 int absData = data < 0 ? 0 - data : data;
1659 int qValue = qTable[i];
1660 int q2 = qValue >> 1;
1662 if (absData < qValue) {
1663 dataUnit[zzIndex] = 0;
1667 dataUnit[zzIndex] = absData;
1669 dataUnit[zzIndex] = 0 - absData;
1674 int receive(int nBits) {
1676 for (int i = 0; i < nBits; i++) {
1677 v = v * 2 + nextBit();
1681 void resetInputBuffer() {
1682 if (dataBuffer == null) {
1683 dataBuffer = new byte[512];
1686 inputStream.read(dataBuffer);
1687 } catch (IOException e) {
1688 SWT.error(SWT.ERROR_IO, e);
1690 currentBitCount = 0;
1691 bufferCurrentPosition = -1;
1693 void resetOutputBuffer() {
1694 if (dataBuffer == null) {
1695 dataBuffer = new byte[512];
1698 outputStream.write(dataBuffer, 0, bufferCurrentPosition);
1699 } catch (IOException e) {
1700 SWT.error(SWT.ERROR_IO, e);
1703 bufferCurrentPosition = 0;
1705 static JPEGSegment seekUnspecifiedMarker(LEDataInputStream byteStream) {
1706 byte[] byteArray = new byte[2];
1709 if (byteStream.read(byteArray, 0, 1) != 1) return null;
1710 if (byteArray[0] == (byte) 0xFF) {
1711 if (byteStream.read(byteArray, 1, 1) != 1) return null;
1712 if (byteArray[1] != (byte) 0xFF && byteArray[1] != 0) {
1713 byteStream.unread(byteArray);
1714 return new JPEGSegment(byteArray);
1718 } catch (IOException e) {
1719 SWT.error(SWT.ERROR_IO, e);
1723 PaletteData setUpPalette() {
1724 if (nComponents == 1) {
1725 RGB[] entries = new RGB[256];
1726 for (int i = 0; i < 256; i++) {
1727 entries[i] = new RGB(i, i, i);
1729 return new PaletteData(entries);
1731 return new PaletteData(0xFF, 0xFF00, 0xFF0000);
1733 static void skipSegmentFrom(LEDataInputStream byteStream) {
1735 byte[] byteArray = new byte[4];
1736 JPEGSegment jpegSegment = new JPEGSegment(byteArray);
1738 if (byteStream.read(byteArray) != byteArray.length) {
1739 SWT.error(SWT.ERROR_INVALID_IMAGE);
1741 if (!(byteArray[0] == -1 && byteArray[1] != 0 && byteArray[1] != -1)) {
1742 SWT.error(SWT.ERROR_INVALID_IMAGE);
1744 int delta = jpegSegment.getSegmentLength() - 2;
1745 byteStream.skip(delta);
1746 } catch (Exception e) {
1747 SWT.error(SWT.ERROR_IO, e);
1750 void storeData(int[] dataUnit, int iComp, int xmcu, int ymcu, int hi, int ihi, int vi, int ivi) {
1751 byte[] compImage = imageComponents[iComp];
1752 int[] frameComponent = frameComponents[componentIds[iComp]];
1753 int compWidth = frameComponent[CW];
1754 int destIndex = ((ymcu * vi + ivi) * compWidth * DCTSIZE) + ((xmcu * hi + ihi) * DCTSIZE);
1756 for (int i = 0; i < DCTSIZE; i++) {
1757 for (int col = 0; col < DCTSIZE; col++) {
1758 int x = dataUnit[srcIndex] + 128;
1762 if (x > 255) x = 255;
1764 compImage[destIndex + col] = (byte)x;
1767 destIndex += compWidth;
1771 void unloadIntoByteStream(ImageLoader loader) {
1772 ImageData image = loader.data[0];
1773 if (!new JPEGStartOfImage().writeToStream(outputStream)) {
1774 SWT.error(SWT.ERROR_IO);
1776 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});
1777 if (!appn.writeToStream(outputStream)) {
1778 SWT.error(SWT.ERROR_IO);
1780 quantizationTables = new int[4][];
1781 JPEGQuantizationTable chromDQT = JPEGQuantizationTable.defaultChrominanceTable();
1782 int encoderQFactor = loader.compression >= 1 && loader.compression <= 100 ? loader.compression : 75;
1783 chromDQT.scaleBy(encoderQFactor);
1784 int[] jpegDQTKeys = chromDQT.getQuantizationTablesKeys();
1785 int[][] jpegDQTValues = chromDQT.getQuantizationTablesValues();
1786 for (int i = 0; i < jpegDQTKeys.length; i++) {
1787 quantizationTables[jpegDQTKeys[i]] = jpegDQTValues[i];
1789 JPEGQuantizationTable lumDQT = JPEGQuantizationTable.defaultLuminanceTable();
1790 lumDQT.scaleBy(encoderQFactor);
1791 jpegDQTKeys = lumDQT.getQuantizationTablesKeys();
1792 jpegDQTValues = lumDQT.getQuantizationTablesValues();
1793 for (int i = 0; i < jpegDQTKeys.length; i++) {
1794 quantizationTables[jpegDQTKeys[i]] = jpegDQTValues[i];
1796 if (!lumDQT.writeToStream(outputStream)) {
1797 SWT.error(SWT.ERROR_IO);
1799 if (!chromDQT.writeToStream(outputStream)) {
1800 SWT.error(SWT.ERROR_IO);
1802 int frameLength, scanLength, precision;
1803 int[][] frameParams, scanParams;
1804 if (image.depth == 1) {
1806 frameParams = new int[1][];
1807 frameParams[0] = new int[] {1, 1, 1, 0, 0};
1808 scanParams = new int[1][];
1809 scanParams[0] = new int[] {0, 0};
1815 frameParams = new int[3][];
1816 frameParams[0] = new int[] {0, 2, 2, 0, 0};
1817 frameParams[1] = new int[] {1, 1, 1, 0, 0};
1818 frameParams[2] = new int[] {1, 1, 1, 0, 0};
1819 scanParams = new int[3][];
1820 scanParams[0] = new int[] {0, 0};
1821 scanParams[1] = new int[] {1, 1};
1822 scanParams[2] = new int[] {1, 1};
1827 imageWidth = image.width;
1828 imageHeight = image.height;
1829 frameHeader = new JPEGFrameHeader(new byte[19]);
1830 frameHeader.setSegmentMarker(SOF0);
1831 frameHeader.setSegmentLength(frameLength);
1832 frameHeader.setSamplePrecision(precision);
1833 frameHeader.setSamplesPerLine(imageWidth);
1834 frameHeader.setNumberOfLines(imageHeight);
1835 frameHeader.setNumberOfImageComponents(nComponents);
1836 frameHeader.componentParameters = frameParams;
1837 frameHeader.componentIdentifiers = new int[] {0, 1, 2};
1838 frameHeader.initializeContents();
1839 if (!frameHeader.writeToStream(outputStream)) {
1840 SWT.error(SWT.ERROR_IO);
1842 frameComponents = frameParams;
1843 componentIds = frameHeader.componentIdentifiers;
1844 maxH = frameHeader.getMaxHFactor();
1845 maxV = frameHeader.getMaxVFactor();
1846 int mcuWidth = maxH * DCTSIZE;
1847 int mcuHeight = maxV * DCTSIZE;
1848 interleavedMcuCols = (imageWidth + mcuWidth - 1) / mcuWidth;
1849 interleavedMcuRows = (imageHeight + mcuHeight - 1) / mcuHeight;
1850 acHuffmanTables = new JPEGHuffmanTable[4];
1851 dcHuffmanTables = new JPEGHuffmanTable[4];
1852 JPEGHuffmanTable[] dhtTables = new JPEGHuffmanTable[] {
1853 JPEGHuffmanTable.getDefaultDCLuminanceTable(),
1854 JPEGHuffmanTable.getDefaultDCChrominanceTable(),
1855 JPEGHuffmanTable.getDefaultACLuminanceTable(),
1856 JPEGHuffmanTable.getDefaultACChrominanceTable()
1858 for (int i = 0; i < dhtTables.length; i++) {
1859 JPEGHuffmanTable dhtTable = dhtTables[i];
1860 if (!dhtTable.writeToStream(outputStream)) {
1861 SWT.error(SWT.ERROR_IO);
1863 JPEGHuffmanTable[] allTables = dhtTable.getAllTables();
1864 for (int j = 0; j < allTables.length; j++) {
1865 JPEGHuffmanTable huffmanTable = allTables[j];
1866 if (huffmanTable.getTableClass() == 0) {
1867 dcHuffmanTables[huffmanTable.getTableIdentifier()] = huffmanTable;
1869 acHuffmanTables[huffmanTable.getTableIdentifier()] = huffmanTable;
1873 precedingDCs = new int[4];
1874 scanHeader = new JPEGScanHeader(new byte[14]);
1875 scanHeader.setSegmentMarker(SOS);
1876 scanHeader.setSegmentLength(scanLength);
1877 scanHeader.setNumberOfImageComponents(nComponents);
1878 scanHeader.setStartOfSpectralSelection(0);
1879 scanHeader.setEndOfSpectralSelection(63);
1880 scanHeader.componentParameters = scanParams;
1881 scanHeader.initializeContents();
1882 if (!scanHeader.writeToStream(outputStream)) {
1883 SWT.error(SWT.ERROR_IO);
1885 convertImageToYCbCr(image);
1886 resetOutputBuffer();
1888 currentBitCount = 0;
1890 if (!new JPEGEndOfImage().writeToStream(outputStream)) {
1891 SWT.error(SWT.ERROR_IO);