KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > internal > image > JPEGFileFormat


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This source file is made available under the terms contained in the README file
4  * accompanying this program. The README file should be located in the about_files directory of the
5  * plug-in that contains this source file.
6  *
7  * Contributors:
8  * IBM Corporation - initial API and implementation
9  *******************************************************************************/

10 package org.eclipse.swt.internal.image;
11
12
13 import org.eclipse.swt.*;
14 import org.eclipse.swt.graphics.*;
15 import java.io.*;
16
17 final class JPEGFileFormat extends FileFormat {
18     int restartInterval;
19     JPEGFrameHeader frameHeader;
20     int imageWidth, imageHeight;
21     int interleavedMcuCols, interleavedMcuRows;
22     int maxV, maxH;
23     boolean progressive;
24     int samplePrecision;
25     int nComponents;
26     int[][] frameComponents;
27     int[] componentIds;
28     byte[][] imageComponents;
29     int[] dataUnit;
30     int[][][] dataUnits;
31     int[] precedingDCs;
32     JPEGScanHeader scanHeader;
33     byte[] dataBuffer;
34     int currentBitCount;
35     int bufferCurrentPosition;
36     int restartsToGo;
37     int nextRestartNumber;
38     JPEGHuffmanTable[] acHuffmanTables;
39     JPEGHuffmanTable[] dcHuffmanTables;
40     int[][] quantizationTables;
41     int currentByte;
42     int encoderQFactor = 75;
43     int eobrun = 0;
44     /* JPEGConstants */
45     public static final int DCTSIZE = 8;
46     public static final int DCTSIZESQR = 64;
47     /* JPEGFixedPointConstants */
48     public static final int FIX_0_899976223 = 7373;
49     public static final int FIX_1_961570560 = 16069;
50     public static final int FIX_2_053119869 = 16819;
51     public static final int FIX_0_298631336 = 2446;
52     public static final int FIX_1_847759065 = 15137;
53     public static final int FIX_1_175875602 = 9633;
54     public static final int FIX_3_072711026 = 25172;
55     public static final int FIX_0_765366865 = 6270;
56     public static final int FIX_2_562915447 = 20995;
57     public static final int FIX_0_541196100 = 4433;
58     public static final int FIX_0_390180644 = 3196;
59     public static final int FIX_1_501321110 = 12299;
60     /* JPEGMarkerCodes */
61     public static final int APP0 = 0xFFE0;
62     public static final int APP15 = 0xFFEF;
63     public static final int COM = 0xFFFE;
64     public static final int DAC = 0xFFCC;
65     public static final int DHP = 0xFFDE;
66     public static final int DHT = 0xFFC4;
67     public static final int DNL = 0xFFDC;
68     public static final int DRI = 0xFFDD;
69     public static final int DQT = 0xFFDB;
70     public static final int EOI = 0xFFD9;
71     public static final int EXP = 0xFFDF;
72     public static final int JPG = 0xFFC8;
73     public static final int JPG0 = 0xFFF0;
74     public static final int JPG13 = 0xFFFD;
75     public static final int RST0 = 0xFFD0;
76     public static final int RST1 = 0xFFD1;
77     public static final int RST2 = 0xFFD2;
78     public static final int RST3 = 0xFFD3;
79     public static final int RST4 = 0xFFD4;
80     public static final int RST5 = 0xFFD5;
81     public static final int RST6 = 0xFFD6;
82     public static final int RST7 = 0xFFD7;
83     public static final int SOF0 = 0xFFC0;
84     public static final int SOF1 = 0xFFC1;
85     public static final int SOF2 = 0xFFC2;
86     public static final int SOF3 = 0xFFC3;
87     public static final int SOF5 = 0xFFC5;
88     public static final int SOF6 = 0xFFC6;
89     public static final int SOF7 = 0xFFC7;
90     public static final int SOF9 = 0xFFC9;
91     public static final int SOF10 = 0xFFCA;
92     public static final int SOF11 = 0xFFCB;
93     public static final int SOF13 = 0xFFCD;
94     public static final int SOF14 = 0xFFCE;
95     public static final int SOF15 = 0xFFCF;
96     public static final int SOI = 0xFFD8;
97     public static final int SOS = 0xFFDA;
98     public static final int TEM = 0xFF01;
99     /* JPEGFrameComponentParameterConstants */
100     public static final int TQI = 0;
101     public static final int HI = 1;
102     public static final int VI = 2;
103     public static final int CW = 3;
104     public static final int CH = 4;
105     /* JPEGScanComponentParameterConstants */
106     public static final int DC = 0;
107     public static final int AC = 1;
108     /* JFIF Component Constants */
109     public static final int ID_Y = 1 - 1;
110     public static final int ID_CB = 2 - 1;
111     public static final int ID_CR = 3 - 1;
112     public static final RGB[] RGB16 = new RGB[] {
113         new RGB(0,0,0),
114         new RGB(0x80,0,0),
115         new RGB(0,0x80,0),
116         new RGB(0x80,0x80,0),
117         new RGB(0,0,0x80),
118         new RGB(0x80,0,0x80),
119         new RGB(0,0x80,0x80),
120         new RGB(0xC0,0xC0,0xC0),
121         new RGB(0x80,0x80,0x80),
122         new RGB(0xFF,0,0),
123         new RGB(0,0xFF,0),
124         new RGB(0xFF,0xFF,0),
125         new RGB(0,0,0xFF),
126         new RGB(0xFF,0,0xFF),
127         new RGB(0,0xFF,0xFF),
128         new RGB(0xFF,0xFF,0xFF),
129     };
130     public static final int[] ExtendTest = {
131         0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
132         4096, 8192, 16384, 32768, 65536, 131072, 262144
133     };
134     public static final int[] ExtendOffset = new int[] {
135         0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047,
136         -4095, -8191, -16383, -32767, -65535, -131071, -262143
137     };
138     public static final int[] ZigZag8x8 = {
139         0, 1, 8, 16, 9, 2, 3, 10,
140         17, 24, 32, 25, 18, 11, 4, 5,
141         12, 19, 26, 33, 40, 48, 41, 34,
142         27, 20, 13, 6, 7, 14, 21, 28,
143         35, 42, 49, 56, 57, 50, 43, 36,
144         29, 22, 15, 23, 30, 37, 44, 51,
145         58, 59, 52, 45, 38, 31, 39, 46,
146         53, 60, 61, 54, 47, 55, 62, 63
147     };
148
149     public static int[] CrRTable, CbBTable, CrGTable, CbGTable;
150     public static int[] RYTable, GYTable, BYTable,
151         RCbTable, GCbTable, BCbTable, RCrTable, GCrTable, BCrTable, NBitsTable;
152     static {
153         initialize();
154     }
155 void compress(ImageData image, byte[] dataYComp, byte[] dataCbComp, byte[] dataCrComp) {
156     int srcWidth = image.width;
157     int srcHeight = image.height;
158     int vhFactor = maxV * maxH;
159     int[] frameComponent;
160     imageComponents = new byte[nComponents][];
161     for (int i = 0; i < nComponents; i++) {
162         frameComponent = frameComponents[componentIds[i]];
163         imageComponents[i] = new byte[frameComponent[CW] * frameComponent[CH]];
164     }
165     frameComponent = frameComponents[componentIds[ID_Y]];
166     for (int yPos = 0; yPos < srcHeight; yPos++) {
167         int srcOfs = yPos * srcWidth;
168         int dstOfs = yPos * frameComponent[CW];
169         System.arraycopy(dataYComp, srcOfs, imageComponents[ID_Y], dstOfs, srcWidth);
170     }
171     frameComponent = frameComponents[componentIds[ID_CB]];
172     for (int yPos = 0; yPos < srcHeight / maxV; yPos++) {
173         int destRowIndex = yPos * frameComponent[CW];
174         for (int xPos = 0; xPos < srcWidth / maxH; xPos++) {
175             int sum = 0;
176             for (int iv = 0; iv < maxV; iv++) {
177                 int srcIndex = (yPos * maxV + iv) * srcWidth + (xPos * maxH);
178                 for (int ih = 0; ih < maxH; ih++) {
179                     sum += dataCbComp[srcIndex + ih] & 0xFF;
180                 }
181             }
182             imageComponents[ID_CB][destRowIndex + xPos] = (byte)(sum / vhFactor);
183         }
184     }
185     frameComponent = frameComponents[componentIds[ID_CR]];
186     for (int yPos = 0; yPos < srcHeight / maxV; yPos++) {
187         int destRowIndex = yPos * frameComponent[CW];
188         for (int xPos = 0; xPos < srcWidth / maxH; xPos++) {
189             int sum = 0;
190             for (int iv = 0; iv < maxV; iv++) {
191                 int srcIndex = (yPos * maxV + iv) * srcWidth + (xPos * maxH);
192                 for (int ih = 0; ih < maxH; ih++) {
193                     sum += dataCrComp[srcIndex + ih] & 0xFF;
194                 }
195             }
196             imageComponents[ID_CR][destRowIndex + xPos] = (byte)(sum / vhFactor);
197         }
198     }
199     for (int iComp = 0; iComp < nComponents; iComp++) {
200         byte[] imageComponent = imageComponents[iComp];
201         frameComponent = frameComponents[componentIds[iComp]];
202         int hFactor = frameComponent[HI];
203         int vFactor = frameComponent[VI];
204         int componentWidth = frameComponent[CW];
205         int componentHeight = frameComponent[CH];
206         int compressedWidth = srcWidth / (maxH / hFactor);
207         int compressedHeight = srcHeight / (maxV / vFactor);
208         if (compressedWidth < componentWidth) {
209             int delta = componentWidth - compressedWidth;
210             for (int yPos = 0; yPos < compressedHeight; yPos++) {
211                 int dstOfs = ((yPos + 1) * componentWidth - delta);
212                 int dataValue = imageComponent[dstOfs - 1] & 0xFF;
213                 for (int i = 0; i < delta; i++) {
214                     imageComponent[dstOfs + i] = (byte)dataValue;
215                 }
216             }
217         }
218         if (compressedHeight < componentHeight) {
219             int srcOfs = (compressedHeight - 1) * componentWidth;
220             for (int yPos = compressedHeight; yPos <= componentHeight; yPos++) {
221                 int dstOfs = (yPos - 1) * componentWidth;
222                 System.arraycopy(imageComponent, srcOfs, imageComponent, dstOfs, componentWidth);
223             }
224         }
225     }
226 }
227 void convert4BitRGBToYCbCr(ImageData image) {
228     RGB[] rgbs = image.getRGBs();
229     int paletteSize = rgbs.length;
230     byte[] yComp = new byte[paletteSize];
231     byte[] cbComp = new byte[paletteSize];
232     byte[] crComp = new byte[paletteSize];
233     int srcWidth = image.width;
234     int srcHeight = image.height;
235     for (int i = 0; i < paletteSize; i++) {
236         RGB color = rgbs[i];
237         int r = color.red;
238         int g = color.green;
239         int b = color.blue;
240         int n = RYTable[r] + GYTable[g] + BYTable[b];
241         yComp[i] = (byte)(n >> 16);
242         if ((n < 0) && ((n & 0xFFFF) != 0)) yComp[i]--;
243         n = RCbTable[r] + GCbTable[g] + BCbTable[b];
244         cbComp[i] = (byte)(n >> 16);
245         if ((n < 0) && ((n & 0xFFFF) != 0)) cbComp[i]--;
246         n = RCrTable[r] + GCrTable[g] + BCrTable[b];
247         crComp[i] = (byte)(n >> 16);
248         if ((n < 0) && ((n & 0xFFFF) != 0)) crComp[i]--;
249     }
250     int bSize = srcWidth * srcHeight;
251     byte[] dataYComp = new byte[bSize];
252     byte[] dataCbComp = new byte[bSize];
253     byte[] dataCrComp = new byte[bSize];
254     byte[] origData = image.data;
255     int bytesPerLine = image.bytesPerLine;
256     int maxScanlineByte = srcWidth >> 1;
257     for (int yPos = 0; yPos < srcHeight; yPos++) {
258         for (int xPos = 0; xPos < maxScanlineByte; xPos++) {
259             int srcIndex = yPos * bytesPerLine + xPos;
260             int dstIndex = yPos * srcWidth + (xPos * 2);
261             int value2 = origData[srcIndex] & 0xFF;
262             int value1 = value2 >> 4;
263             value2 &= 0x0F;
264             dataYComp[dstIndex] = yComp[value1];
265             dataCbComp[dstIndex] = cbComp[value1];
266             dataCrComp[dstIndex] = crComp[value1];
267             dataYComp[dstIndex + 1] = yComp[value2];
268             dataCbComp[dstIndex + 1] = cbComp[value2];
269             dataCrComp[dstIndex + 1] = crComp[value2];
270         }
271     }
272     compress(image, dataYComp, dataCbComp, dataCrComp);
273 }
274 void convert8BitRGBToYCbCr(ImageData image) {
275     RGB[] rgbs = image.getRGBs();
276     int paletteSize = rgbs.length;
277     byte[] yComp = new byte[paletteSize];
278     byte[] cbComp = new byte[paletteSize];
279     byte[] crComp = new byte[paletteSize];
280     int srcWidth = image.width;
281     int srcHeight = image.height;
282     for (int i = 0; i < paletteSize; i++) {
283         RGB color = rgbs[i];
284         int r = color.red;
285         int g = color.green;
286         int b = color.blue;
287         int n = RYTable[r] + GYTable[g] + BYTable[b];
288         yComp[i] = (byte)(n >> 16);
289         if ((n < 0) && ((n & 0xFFFF) != 0)) yComp[i]--;
290         n = RCbTable[r] + GCbTable[g] + BCbTable[b];
291         cbComp[i] = (byte)(n >> 16);
292         if ((n < 0) && ((n & 0xFFFF) != 0)) cbComp[i]--;
293         n = RCrTable[r] + GCrTable[g] + BCrTable[b];
294         crComp[i] = (byte)(n >> 16);
295         if ((n < 0) && ((n & 0xFFFF) != 0)) crComp[i]--;
296     }
297     int dstWidth = image.width;
298     int dstHeight = srcHeight;
299     int stride = ((srcWidth + 3) >> 2) << 2;
300     int bSize = dstWidth * dstHeight;
301     byte[] dataYComp = new byte[bSize];
302     byte[] dataCbComp = new byte[bSize];
303     byte[] dataCrComp = new byte[bSize];
304     byte[] origData = image.data;
305     for (int yPos = 0; yPos < srcHeight; yPos++) {
306         int srcRowIndex = yPos * stride;
307         int dstRowIndex = yPos * dstWidth;
308         for (int xPos = 0; xPos < srcWidth; xPos++) {
309             int value = origData[srcRowIndex + xPos] & 0xFF;
310             int dstIndex = dstRowIndex + xPos;
311             dataYComp[dstIndex] = yComp[value];
312             dataCbComp[dstIndex] = cbComp[value];
313             dataCrComp[dstIndex] = crComp[value];
314         }
315     }
316     compress(image, dataYComp, dataCbComp, dataCrComp);
317 }
318 byte[] convertCMYKToRGB() {
319     /* Unsupported CMYK format. Answer an empty byte array. */
320     return new byte[0];
321 }
322 void convertImageToYCbCr(ImageData image) {
323     switch (image.depth) {
324         case 4:
325             convert4BitRGBToYCbCr(image);
326             return;
327         case 8:
328             convert8BitRGBToYCbCr(image);
329             return;
330         case 16:
331         case 24:
332         case 32:
333             convertMultiRGBToYCbCr(image);
334             return;
335         default:
336             SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
337     }
338     return;
339 }
340 void convertMultiRGBToYCbCr(ImageData image) {
341     int srcWidth = image.width;
342     int srcHeight = image.height;
343     int bSize = srcWidth * srcHeight;
344     byte[] dataYComp = new byte[bSize];
345     byte[] dataCbComp = new byte[bSize];
346     byte[] dataCrComp = new byte[bSize];
347     PaletteData palette = image.palette;
348     int[] buffer = new int[srcWidth];
349     if (palette.isDirect) {
350         int redMask = palette.redMask;
351         int greenMask = palette.greenMask;
352         int blueMask = palette.blueMask;
353         int redShift = palette.redShift;
354         int greenShift = palette.greenShift;
355         int blueShift = palette.blueShift;
356         for (int yPos = 0; yPos < srcHeight; yPos++) {
357             image.getPixels(0, yPos, srcWidth, buffer, 0);
358             int dstRowIndex = yPos * srcWidth;
359             for (int xPos = 0; xPos < srcWidth; xPos++) {
360                 int pixel = buffer[xPos];
361                 int dstDataIndex = dstRowIndex + xPos;
362                 int r = pixel & redMask;
363                 r = (redShift < 0) ? r >>> -redShift : r << redShift;
364                 int g = pixel & greenMask;
365                 g = (greenShift < 0) ? g >>> -greenShift : g << greenShift;
366                 int b = pixel & blueMask;
367                 b = (blueShift < 0) ? b >>> -blueShift : b << blueShift;
368                 dataYComp[dstDataIndex] = (byte)((RYTable[r] + GYTable[g] + BYTable[b]) >> 16);
369                 dataCbComp[dstDataIndex] = (byte)((RCbTable[r] + GCbTable[g] + BCbTable[b]) >> 16);
370                 dataCrComp[dstDataIndex] = (byte)((RCrTable[r] + GCrTable[g] + BCrTable[b]) >> 16);
371             }
372         }
373     } else {
374         for (int yPos = 0; yPos < srcHeight; yPos++) {
375             image.getPixels(0, yPos, srcWidth, buffer, 0);
376             int dstRowIndex = yPos * srcWidth;
377             for (int xPos = 0; xPos < srcWidth; xPos++) {
378                 int pixel = buffer[xPos];
379                 int dstDataIndex = dstRowIndex + xPos;
380                 RGB rgb = palette.getRGB(pixel);
381                 int r = rgb.red;
382                 int g = rgb.green;
383                 int b = rgb.blue;
384                 dataYComp[dstDataIndex] = (byte)((RYTable[r] + GYTable[g] + BYTable[b]) >> 16);
385                 dataCbComp[dstDataIndex] = (byte)((RCbTable[r] + GCbTable[g] + BCbTable[b]) >> 16);
386                 dataCrComp[dstDataIndex] = (byte)((RCrTable[r] + GCrTable[g] + BCrTable[b]) >> 16);
387             }
388         }
389     }
390     compress(image, dataYComp, dataCbComp, dataCrComp);
391 }
392 byte[] convertYToRGB() {
393     int compWidth = frameComponents[componentIds[ID_Y]][CW];
394     int bytesPerLine = (((imageWidth * 8 + 7) / 8) + 3) / 4 * 4;
395     byte[] data = new byte[bytesPerLine * imageHeight];
396     byte[] yComp = imageComponents[ID_Y];
397     int destIndex = 0;
398     for (int i = 0; i < imageHeight; i++) {
399         int srcIndex = i * compWidth;
400         for (int j = 0; j < bytesPerLine; j++) {
401             int y = yComp[srcIndex] & 0xFF;
402             if (y < 0) {
403                 y = 0;
404             } else {
405                 if (y > 255) y = 255;
406             }
407             if (j >= imageWidth) {
408                 y = 0;
409             }
410             data[destIndex] = (byte)y;
411             srcIndex++;
412             destIndex++;
413         }
414     }
415     return data;
416 }
417 byte[] convertYCbCrToRGB() {
418     /**
419      * Convert existing image components into an RGB format.
420      * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
421      * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
422      * The conversion equations to be implemented are therefore
423      * R = Y + 1.40200 * Cr
424      * G = Y - 0.34414 * Cb - 0.71414 * Cr
425      * B = Y + 1.77200 * Cb
426      * where Cb and Cr represent the incoming values less MAXJSAMPLE/2.
427      * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
428      *
429      * To avoid floating-point arithmetic, we represent the fractional constants
430      * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
431      * the products by 2^16, with appropriate rounding, to get the correct answer.
432      * Notice that Y, being an integral input, does not contribute any fraction
433      * so it need not participate in the rounding.
434      *
435      * For even more speed, we avoid doing any multiplications in the inner loop
436      * by precalculating the constants times Cb and Cr for all possible values.
437      * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
438      * for 12-bit samples it is still acceptable. It's not very reasonable for
439      * 16-bit samples, but if you want lossless storage you shouldn't be changing
440      * colorspace anyway.
441      * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
442      * values for the G calculation are left scaled up, since we must add them
443      * together before rounding.
444      */

445     int bSize = imageWidth * imageHeight * nComponents;
446     byte[] rgbData = new byte[bSize];
447     int destIndex = 0;
448     expandImageComponents();
449     byte[] yComp = imageComponents[ID_Y];
450     byte[] cbComp = imageComponents[ID_CB];
451     byte[] crComp = imageComponents[ID_CR];
452     int compWidth = frameComponents[componentIds[ID_Y]][CW];
453     for (int v = 0; v < imageHeight; v++) {
454         int srcIndex = v * compWidth;
455         for (int i = 0; i < imageWidth; i++) {
456             int y = yComp[srcIndex] & 0xFF;
457             int cb = cbComp[srcIndex] & 0xFF;
458             int cr = crComp[srcIndex] & 0xFF;
459             int r = y + CrRTable[cr];
460             int g = y + ((CbGTable[cb] + CrGTable[cr]) >> 16);
461             int b = y + CbBTable[cb];
462             if (r < 0) {
463                 r = 0;
464             } else {
465                 if (r > 255) r = 255;
466             }
467             if (g < 0) {
468                 g = 0;
469             } else {
470                 if (g > 255) g = 255;
471             }
472             if (b < 0) {
473                 b = 0;
474             } else {
475                 if (b > 255) b = 255;
476             }
477             rgbData[destIndex] = (byte)b;
478             rgbData[destIndex + 1] = (byte)g;
479             rgbData[destIndex + 2] = (byte)r;
480             destIndex += 3;
481             srcIndex++;
482         }
483     }
484     return rgbData;
485 }
486 void decodeACCoefficients(int[] dataUnit, int iComp) {
487     int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
488     JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
489     int k = 1;
490     while (k < 64) {
491         int rs = decodeUsingTable(acTable);
492         int r = rs >> 4;
493         int s = rs & 0xF;
494         if (s == 0) {
495             if (r == 15) {
496                 k += 16;
497             } else {
498                 break;
499             }
500         } else {
501             k += r;
502             int bits = receive(s);
503             dataUnit[ZigZag8x8[k]] = extendBy(bits, s);
504             k++;
505         }
506     }
507 }
508 void decodeACFirstCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit) {
509     if (eobrun > 0) {
510         eobrun--;
511         return;
512     }
513     int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
514     JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
515     int k = start;
516     while (k <= end) {
517         int rs = decodeUsingTable(acTable);
518         int r = rs >> 4;
519         int s = rs & 0xF;
520         if (s == 0) {
521             if (r == 15) {
522                 k += 16;
523             } else {
524                 eobrun = (1 << r) + receive(r) - 1;
525                 break;
526             }
527         } else {
528             k += r;
529             int bits = receive(s);
530             dataUnit[ZigZag8x8[k]] = extendBy(bits, s) << approxBit;
531             k++;
532         }
533     }
534 }
535 void decodeACRefineCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit) {
536     int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
537     JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
538     int k = start;
539     while (k <= end) {
540         if (eobrun > 0) {
541             while (k <= end) {
542                 int zzIndex = ZigZag8x8[k];
543                 if (dataUnit[zzIndex] != 0) {
544                     dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
545                 }
546                 k++;
547             }
548             eobrun--;
549         } else {
550             int rs = decodeUsingTable(acTable);
551             int r = rs >> 4;
552             int s = rs & 0xF;
553             if (s == 0) {
554                 if (r == 15) {
555                     int zeros = 0;
556                     while (zeros < 16 && k <= end) {
557                         int zzIndex = ZigZag8x8[k];
558                         if (dataUnit[zzIndex] != 0) {
559                             dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
560                         } else {
561                             zeros++;
562                         }
563                         k++;
564                     }
565                 } else {
566                     eobrun = (1 << r) + receive(r);
567                 }
568             } else {
569                 int bit = receive(s);
570                 int zeros = 0;
571                 int zzIndex = ZigZag8x8[k];
572                 while ((zeros < r || dataUnit[zzIndex] != 0) && k <= end) {
573                     if (dataUnit[zzIndex] != 0) {
574                         dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
575                     } else {
576                         zeros++;
577                     }
578                     k++;
579                     zzIndex = ZigZag8x8[k];
580                 }
581                 if (bit != 0) {
582                     dataUnit[zzIndex] = 1 << approxBit;
583                 } else {
584                     dataUnit[zzIndex] = -1 << approxBit;
585                 }
586                 k++;
587             }
588         }
589     }
590 }
591 int refineAC(int ac, int approxBit) {
592     if (ac > 0) {
593         int bit = nextBit();
594         if (bit != 0) {
595             ac += 1 << approxBit;
596         }
597     } else if (ac < 0) {
598         int bit = nextBit();
599         if (bit != 0) {
600             ac += -1 << approxBit;
601         }
602     }
603     return ac;
604 }
605 void decodeDCCoefficient(int[] dataUnit, int iComp, boolean first, int approxBit) {
606     int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
607     JPEGHuffmanTable dcTable = dcHuffmanTables[sParams[DC]];
608     int lastDC = 0;
609     if (progressive && !first) {
610         int bit = nextBit();
611         lastDC = dataUnit[0] + (bit << approxBit);
612     } else {
613         lastDC = precedingDCs[iComp];
614         int nBits = decodeUsingTable(dcTable);
615         if (nBits != 0) {
616             int bits = receive(nBits);
617             int diff = extendBy(bits, nBits);
618             lastDC += diff;
619             precedingDCs[iComp] = lastDC;
620         }
621         if (progressive) {
622             lastDC = lastDC << approxBit;
623         }
624     }
625     dataUnit[0] = lastDC;
626 }
627 void dequantize(int[] dataUnit, int iComp) {
628     int[] qTable = quantizationTables[frameComponents[componentIds[iComp]][TQI]];
629     for (int i = 0; i < dataUnit.length; i++) {
630         int zzIndex = ZigZag8x8[i];
631         dataUnit[zzIndex] = dataUnit[zzIndex] * qTable[i];
632     }
633 }
634 byte[] decodeImageComponents() {
635     if (nComponents == 3) { // compIds 1, 2, 3
636
return convertYCbCrToRGB();
637     }
638 // if (nComponents == 3) { // compIds 1, 4, 5
639
// Unsupported CMYK format.
640
// return convertYIQToRGB();
641
// }
642
if (nComponents == 4) {
643         return convertCMYKToRGB();
644     }
645     return convertYToRGB();
646 }
647 void decodeMCUAtXAndY(int xmcu, int ymcu, int nComponentsInScan, boolean first, int start, int end, int approxBit) {
648     for (int iComp = 0; iComp < nComponentsInScan; iComp++) {
649         int scanComponent = iComp;
650         while (scanHeader.componentParameters[componentIds[scanComponent]] == null) {
651             scanComponent++;
652         }
653         int[] frameComponent = frameComponents[componentIds[scanComponent]];
654         int hi = frameComponent[HI];
655         int vi = frameComponent[VI];
656         if (nComponentsInScan == 1) {
657             hi = 1;
658             vi = 1;
659         }
660         int compWidth = frameComponent[CW];
661         for (int ivi = 0; ivi < vi; ivi++) {
662             for (int ihi = 0; ihi < hi; ihi++) {
663                 if (progressive) {
664                     // Progressive: First scan - create a new data unit.
665
// Subsequent scans - refine the existing data unit.
666
int index = (ymcu * vi + ivi) * compWidth + xmcu * hi + ihi;
667                     dataUnit = dataUnits[scanComponent][index];
668                     if (dataUnit == null) {
669                         dataUnit = new int[64];
670                         dataUnits[scanComponent][index] = dataUnit;
671                     }
672                 } else {
673                     // Sequential: Clear and reuse the data unit buffer.
674
for (int i = 0; i < dataUnit.length; i++) {
675                         dataUnit[i] = 0;
676                     }
677                 }
678                 if (!progressive || scanHeader.isDCProgressiveScan()) {
679                     decodeDCCoefficient(dataUnit, scanComponent, first, approxBit);
680                 }
681                 if (!progressive) {
682                     decodeACCoefficients(dataUnit, scanComponent);
683                 } else {
684                     if (scanHeader.isACProgressiveScan()) {
685                         if (first) {
686                             decodeACFirstCoefficients(dataUnit, scanComponent, start, end, approxBit);
687                         } else {
688                             decodeACRefineCoefficients(dataUnit, scanComponent, start, end, approxBit);
689                         }
690                     }
691                     if (loader.hasListeners()) {
692                         // Dequantization, IDCT, up-sampling and color conversion
693
// are done on a copy of the coefficient data in order to
694
// display the image incrementally.
695
int[] temp = dataUnit;
696                         dataUnit = new int[64];
697                         System.arraycopy(temp, 0, dataUnit, 0, 64);
698                     }
699                 }
700                 if (!progressive || (progressive && loader.hasListeners())) {
701                     dequantize(dataUnit, scanComponent);
702                     inverseDCT(dataUnit);
703                     storeData(dataUnit, scanComponent, xmcu, ymcu, hi, ihi, vi, ivi);
704                 }
705             }
706         }
707     }
708 }
709 void decodeScan() {
710     if (progressive && !scanHeader.verifyProgressiveScan()) {
711         SWT.error(SWT.ERROR_INVALID_IMAGE);
712     }
713     int nComponentsInScan = scanHeader.getNumberOfImageComponents();
714     int mcuRowsInScan = interleavedMcuRows;
715     int mcusPerRow = interleavedMcuCols;
716     if (nComponentsInScan == 1) {
717         // Non-interleaved.
718
int scanComponent = 0;
719         while (scanHeader.componentParameters[componentIds[scanComponent]] == null) {
720             scanComponent++;
721         }
722         int[] frameComponent = frameComponents[componentIds[scanComponent]];
723         int hi = frameComponent[HI];
724         int vi = frameComponent[VI];
725         int mcuWidth = DCTSIZE * maxH / hi;
726         int mcuHeight = DCTSIZE * maxV / vi;
727         mcusPerRow = (imageWidth + mcuWidth - 1) / mcuWidth;
728         mcuRowsInScan = (imageHeight + mcuHeight - 1) / mcuHeight;
729     }
730     boolean first = scanHeader.isFirstScan();
731     int start = scanHeader.getStartOfSpectralSelection();
732     int end = scanHeader.getEndOfSpectralSelection();
733     int approxBit = scanHeader.getApproxBitPositionLow();
734     restartsToGo = restartInterval;
735     nextRestartNumber = 0;
736     for (int ymcu = 0; ymcu < mcuRowsInScan; ymcu++) {
737         for (int xmcu = 0; xmcu < mcusPerRow; xmcu++) {
738             if (restartInterval != 0) {
739                 if (restartsToGo == 0) processRestartInterval();
740                 restartsToGo--;
741             }
742             decodeMCUAtXAndY(xmcu, ymcu, nComponentsInScan, first, start, end, approxBit);
743         }
744     }
745 }
746 int decodeUsingTable(JPEGHuffmanTable huffmanTable) {
747     int i = 0;
748     int[] maxCodes = huffmanTable.getDhMaxCodes();
749     int[] minCodes = huffmanTable.getDhMinCodes();
750     int[] valPtrs = huffmanTable.getDhValPtrs();
751     int[] huffVals = huffmanTable.getDhValues();
752     int code = nextBit();
753     while (code > maxCodes[i]) {
754         code = code * 2 + nextBit();
755         i++;
756     }
757     int j = valPtrs[i] + code - minCodes[i];
758     return huffVals[j];
759 }
760 void emit(int huffCode, int nBits) {
761     if (nBits == 0) {
762         SWT.error(SWT.ERROR_INVALID_IMAGE);
763     }
764     int[] power2m1 = new int[] {
765         1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191,
766         16383, 32767, 65535, 131125
767     };
768     int code = (huffCode & power2m1[nBits - 1]) << (24 - nBits - currentBitCount);
769     byte[] codeBuffer = new byte[4];
770     codeBuffer[0] = (byte)(code & 0xFF);
771     codeBuffer[1] = (byte)((code >> 8) & 0xFF);
772     codeBuffer[2] = (byte)((code >> 16) & 0xFF);
773     codeBuffer[3] = (byte)((code >> 24) & 0xFF);
774     int abs = nBits - (8 - currentBitCount);
775     if (abs < 0) abs = -abs;
776     if ((abs >> 3) > 0) {
777         currentByte += codeBuffer[2];
778         emitByte((byte)currentByte);
779         emitByte(codeBuffer[1]);
780         currentByte = codeBuffer[0];
781         currentBitCount += nBits - 16;
782     } else {
783         currentBitCount += nBits;
784         if (currentBitCount >= 8) {
785             currentByte += codeBuffer[2];
786             emitByte((byte)currentByte);
787             currentByte = codeBuffer[1];
788             currentBitCount -= 8;
789         } else {
790             currentByte += codeBuffer[2];
791         }
792     }
793 }
794 void emitByte(byte byteValue) {
795     if (bufferCurrentPosition >= 512) {
796         resetOutputBuffer();
797     }
798     dataBuffer[bufferCurrentPosition] = byteValue;
799     bufferCurrentPosition++;
800     if (byteValue == -1) {
801         emitByte((byte)0);
802     }
803 }
804 void encodeACCoefficients(int[] dataUnit, int iComp) {
805     int[] sParams = scanHeader.componentParameters[iComp];
806     JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
807     int[] ehCodes = acTable.ehCodes;
808     byte[] ehSizes = acTable.ehCodeLengths;
809     int r = 0;
810     int k = 1;
811     while (k < 64) {
812         k++;
813         int acValue = dataUnit[ZigZag8x8[k - 1]];
814         if (acValue == 0) {
815             if (k == 64) {
816                 emit(ehCodes[0], ehSizes[0] & 0xFF);
817             } else {
818                 r++;
819             }
820         } else {
821             while (r > 15) {
822                 emit(ehCodes[0xF0], ehSizes[0xF0] & 0xFF);
823                 r -= 16;
824             }
825             if (acValue < 0) {
826                 int absACValue = acValue;
827                 if (absACValue < 0) absACValue = -absACValue;
828                 int nBits = NBitsTable[absACValue];
829                 int rs = r * 16 + nBits;
830                 emit(ehCodes[rs], ehSizes[rs] & 0xFF);
831                 emit(0xFFFFFF - absACValue, nBits);
832             } else {
833                 int nBits = NBitsTable[acValue];
834                 int rs = r * 16 + nBits;
835                 emit(ehCodes[rs], ehSizes[rs] & 0xFF);
836                 emit(acValue, nBits);
837             }
838             r = 0;
839         }
840     }
841 }
842 void encodeDCCoefficients(int[] dataUnit, int iComp) {
843     int[] sParams = scanHeader.componentParameters[iComp];
844     JPEGHuffmanTable dcTable = dcHuffmanTables[sParams[DC]];
845     int lastDC = precedingDCs[iComp];
846     int dcValue = dataUnit[0];
847     int diff = dcValue - lastDC;
848     precedingDCs[iComp] = dcValue;
849     if (diff < 0) {
850         int absDiff = 0 - diff;
851         int nBits = NBitsTable[absDiff];
852         emit(dcTable.ehCodes[nBits], dcTable.ehCodeLengths[nBits]);
853         emit(0xFFFFFF - absDiff, nBits);
854     } else {
855         int nBits = NBitsTable[diff];
856         emit(dcTable.ehCodes[nBits], dcTable.ehCodeLengths[nBits]);
857         if (nBits != 0) {
858             emit(diff, nBits);
859         }
860     }
861 }
862 void encodeMCUAtXAndY(int xmcu, int ymcu) {
863     int nComponentsInScan = scanHeader.getNumberOfImageComponents();
864     dataUnit = new int[64];
865     for (int iComp = 0; iComp < nComponentsInScan; iComp++) {
866         int[] frameComponent = frameComponents[componentIds[iComp]];
867         int hi = frameComponent[HI];
868         int vi = frameComponent[VI];
869         for (int ivi = 0; ivi < vi; ivi++) {
870             for (int ihi = 0; ihi < hi; ihi++) {
871                 extractData(dataUnit, iComp, xmcu, ymcu, ihi, ivi);
872                 forwardDCT(dataUnit);
873                 quantizeData(dataUnit, iComp);
874                 encodeDCCoefficients(dataUnit, iComp);
875                 encodeACCoefficients(dataUnit, iComp);
876             }
877         }
878     }
879 }
880 void encodeScan() {
881     for (int ymcu = 0; ymcu < interleavedMcuRows; ymcu++) {
882         for (int xmcu = 0; xmcu < interleavedMcuCols; xmcu++) {
883             encodeMCUAtXAndY(xmcu, ymcu);
884         }
885     }
886     if (currentBitCount != 0) {
887         emitByte((byte)currentByte);
888     }
889     resetOutputBuffer();
890 }
891 void expandImageComponents() {
892     for (int iComp = 0; iComp < nComponents; iComp++) {
893         int[] frameComponent = frameComponents[componentIds[iComp]];
894         int hi = frameComponent[HI];
895         int vi = frameComponent[VI];
896         int upH = maxH / hi;
897         int upV = maxV / vi;
898         if ((upH * upV) > 1) {
899             byte[] component = imageComponents[iComp];
900             int compWidth = frameComponent[CW];
901             int compHeight = frameComponent[CH];
902             int upCompWidth = compWidth * upH;
903             int upCompHeight = compHeight * upV;
904             ImageData src = new ImageData(compWidth, compHeight, 8, new PaletteData(RGB16), 4, component);
905             ImageData dest = src.scaledTo(upCompWidth, upCompHeight);
906             imageComponents[iComp] = dest.data;
907         }
908     }
909 }
910 int extendBy(int diff, int t) {
911     if (diff < ExtendTest[t]) {
912         return diff + ExtendOffset[t];
913     } else {
914         return diff;
915     }
916 }
917 void extractData(int[] dataUnit, int iComp, int xmcu, int ymcu, int ihi, int ivi) {
918     byte[] compImage = imageComponents[iComp];
919     int[] frameComponent = frameComponents[componentIds[iComp]];
920     int hi = frameComponent[HI];
921     int vi = frameComponent[VI];
922     int compWidth = frameComponent[CW];
923     int srcIndex = ((ymcu * vi + ivi) * compWidth * DCTSIZE) + ((xmcu * hi + ihi) * DCTSIZE);
924     int destIndex = 0;
925     for (int i = 0; i < DCTSIZE; i++) {
926         for (int col = 0; col < DCTSIZE; col++) {
927             dataUnit[destIndex] = (compImage[srcIndex + col] & 0xFF) - 128;
928             destIndex++;
929         }
930         srcIndex += compWidth;
931     }
932 }
933 void forwardDCT(int[] dataUnit) {
934     for (int row = 0; row < 8; row++) {
935         int rIndex = row * DCTSIZE;
936         int tmp0 = dataUnit[rIndex] + dataUnit[rIndex + 7];
937         int tmp7 = dataUnit[rIndex] - dataUnit[rIndex + 7];
938         int tmp1 = dataUnit[rIndex + 1] + dataUnit[rIndex + 6];
939         int tmp6 = dataUnit[rIndex + 1] - dataUnit[rIndex + 6];
940         int tmp2 = dataUnit[rIndex + 2] + dataUnit[rIndex + 5];
941         int tmp5 = dataUnit[rIndex + 2] - dataUnit[rIndex + 5];
942         int tmp3 = dataUnit[rIndex + 3] + dataUnit[rIndex + 4];
943         int tmp4 = dataUnit[rIndex + 3] - dataUnit[rIndex + 4];
944
945         /**
946          * Even part per LL&M figure 1 --- note that published figure
947          * is faulty; rotator 'sqrt(2)*c1' should be 'sqrt(2)*c6'.
948          */

949         int tmp10 = tmp0 + tmp3;
950         int tmp13 = tmp0 - tmp3;
951         int tmp11 = tmp1 + tmp2;
952         int tmp12 = tmp1 - tmp2;
953
954         dataUnit[rIndex] = (tmp10 + tmp11) * 4;
955         dataUnit[rIndex + 4] = (tmp10 - tmp11) * 4;
956
957         int z1 = (tmp12 + tmp13) * FIX_0_541196100;
958         int n = z1 + (tmp13 * FIX_0_765366865) + 1024;
959         dataUnit[rIndex + 2] = n >> 11;
960         if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 2]--;
961         n = z1 + (tmp12 * (0 - FIX_1_847759065)) + 1024;
962         dataUnit[rIndex + 6] = n >> 11;
963         if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 6]--;
964
965         /**
966          * Odd part per figure 8 --- note paper omits factor of sqrt(2).
967          * cK represents cos(K*pi/16).
968          * i0..i3 in the paper are tmp4..tmp7 here.
969          */

970         z1 = tmp4 + tmp7;
971         int z2 = tmp5 + tmp6;
972         int z3 = tmp4 + tmp6;
973         int z4 = tmp5 + tmp7;
974         int z5 = (z3 + z4) * FIX_1_175875602; // sqrt(2) * c3
975

976         tmp4 *= FIX_0_298631336; // sqrt(2) * (-c1+c3+c5-c7)
977
tmp5 *= FIX_2_053119869; // sqrt(2) * ( c1+c3-c5+c7)
978
tmp6 *= FIX_3_072711026; // sqrt(2) * ( c1+c3+c5-c7)
979
tmp7 *= FIX_1_501321110; // sqrt(2) * ( c1+c3-c5-c7)
980
z1 *= 0 - FIX_0_899976223; // sqrt(2) * (c7-c3)
981
z2 *= 0 - FIX_2_562915447; // sqrt(2) * (-c1-c3)
982
z3 *= 0 - FIX_1_961570560; // sqrt(2) * (-c3-c5)
983
z4 *= 0 - FIX_0_390180644; // sqrt(2) * (c5-c3)
984

985         z3 += z5;
986         z4 += z5;
987
988         n = tmp4 + z1 + z3 + 1024;
989         dataUnit[rIndex + 7] = n >> 11;
990         if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 7]--;
991         n = tmp5 + z2 + z4 + 1024;
992         dataUnit[rIndex + 5] = n >> 11;
993         if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 5]--;
994         n = tmp6 + z2 + z3 + 1024;
995         dataUnit[rIndex + 3] = n >> 11;
996         if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 3]--;
997         n = tmp7 + z1 + z4 + 1024;
998         dataUnit[rIndex + 1] = n >> 11;
999         if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 1]--;
1000    }
1001
1002    /**
1003     * Pass 2: process columns.
1004     * Note that we must descale the results by a factor of 8 == 2**3,
1005     * and also undo the PASS1_BITS scaling.
1006     */

1007    for (int col = 0; col < 8; col++) {
1008        int c0 = col;
1009        int c1 = col + 8;
1010        int c2 = col + 16;
1011        int c3 = col + 24;
1012        int c4 = col + 32;
1013        int c5 = col + 40;
1014        int c6 = col + 48;
1015        int c7 = col + 56;
1016        int tmp0 = dataUnit[c0] + dataUnit[c7];
1017        int tmp7 = dataUnit[c0] - dataUnit[c7];
1018        int tmp1 = dataUnit[c1] + dataUnit[c6];
1019        int tmp6 = dataUnit[c1] - dataUnit[c6];
1020        int tmp2 = dataUnit[c2] + dataUnit[c5];
1021        int tmp5 = dataUnit[c2] - dataUnit[c5];
1022        int tmp3 = dataUnit[c3] + dataUnit[c4];
1023        int tmp4 = dataUnit[c3] - dataUnit[c4];
1024
1025        /**
1026         * Even part per LL&M figure 1 --- note that published figure
1027         * is faulty; rotator 'sqrt(2)*c1' should be 'sqrt(2)*c6'.
1028         */

1029        int tmp10 = tmp0 + tmp3;
1030        int tmp13 = tmp0 - tmp3;
1031        int tmp11 = tmp1 + tmp2;
1032        int tmp12 = tmp1 - tmp2;
1033
1034        int n = tmp10 + tmp11 + 16;
1035        dataUnit[c0] = n >> 5;
1036        if ((n < 0) && ((n & 0x1F) != 0)) dataUnit[c0]--;
1037        n = tmp10 - tmp11 + 16;
1038        dataUnit[c4] = n >> 5;
1039        if ((n < 0) && ((n & 0x1F) != 0)) dataUnit[c4]--;
1040
1041        int z1 = (tmp12 + tmp13) * FIX_0_541196100;
1042        n = z1 + (tmp13 * FIX_0_765366865) + 131072;
1043        dataUnit[c2] = n >> 18;
1044        if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c2]--;
1045        n = z1 + (tmp12 * (0 - FIX_1_847759065)) + 131072;
1046        dataUnit[c6] = n >> 18;
1047        if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c6]--;
1048
1049        /**
1050         * Odd part per figure 8 --- note paper omits factor of sqrt(2).
1051         * cK represents cos(K*pi/16).
1052         * i0..i3 in the paper are tmp4..tmp7 here.
1053         */

1054        z1 = tmp4 + tmp7;
1055        int z2 = tmp5 + tmp6;
1056        int z3 = tmp4 + tmp6;
1057        int z4 = tmp5 + tmp7;
1058        int z5 = (z3 + z4) * FIX_1_175875602; // sqrt(2) * c3
1059

1060        tmp4 *= FIX_0_298631336; // sqrt(2) * (-c1+c3+c5-c7)
1061
tmp5 *= FIX_2_053119869; // sqrt(2) * ( c1+c3-c5+c7)
1062
tmp6 *= FIX_3_072711026; // sqrt(2) * ( c1+c3+c5-c7)
1063
tmp7 *= FIX_1_501321110; // sqrt(2) * ( c1+c3-c5-c7)
1064
z1 *= 0 - FIX_0_899976223; // sqrt(2) * (c7-c3)
1065
z2 *= 0 - FIX_2_562915447; // sqrt(2) * (-c1-c3)
1066
z3 *= 0 - FIX_1_961570560; // sqrt(2) * (-c3-c5)
1067
z4 *= 0 - FIX_0_390180644; // sqrt(2) * (c5-c3)
1068

1069        z3 += z5;
1070        z4 += z5;
1071
1072        n = tmp4 + z1 + z3 + 131072;
1073        dataUnit[c7] = n >> 18;
1074        if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c7]--;
1075        n = tmp5 + z2 + z4 + 131072;
1076        dataUnit[c5] = n >> 18;
1077        if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c5]--;
1078        n = tmp6 + z2 + z3 + 131072;
1079        dataUnit[c3] = n >> 18;
1080        if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c3]--;
1081        n = tmp7 + z1 + z4 + 131072;
1082        dataUnit[c1] = n >> 18;
1083        if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c1]--;
1084    }
1085}
1086void getAPP0() {
1087    JPEGAppn appn = new JPEGAppn(inputStream);
1088    if (!appn.verify()) {
1089        SWT.error(SWT.ERROR_INVALID_IMAGE);
1090    }
1091}
1092void getCOM() {
1093    new JPEGComment(inputStream);
1094}
1095void getDAC() {
1096    new JPEGArithmeticConditioningTable(inputStream);
1097}
1098void getDHT() {
1099    JPEGHuffmanTable dht = new JPEGHuffmanTable(inputStream);
1100    if (!dht.verify()) {
1101        SWT.error(SWT.ERROR_INVALID_IMAGE);
1102    }
1103    if (acHuffmanTables == null) {
1104        acHuffmanTables = new JPEGHuffmanTable[4];
1105    }
1106    if (dcHuffmanTables == null) {
1107        dcHuffmanTables = new JPEGHuffmanTable[4];
1108    }
1109    JPEGHuffmanTable[] dhtTables = dht.getAllTables();
1110    for (int i = 0; i < dhtTables.length; i++) {
1111        JPEGHuffmanTable dhtTable = dhtTables[i];
1112        if (dhtTable.getTableClass() == 0) {
1113            dcHuffmanTables[dhtTable.getTableIdentifier()] = dhtTable;
1114        } else {
1115            acHuffmanTables[dhtTable.getTableIdentifier()] = dhtTable;
1116        }
1117    }
1118}
1119void getDNL() {
1120    new JPEGRestartInterval(inputStream);
1121}
1122void getDQT() {
1123    JPEGQuantizationTable dqt = new JPEGQuantizationTable(inputStream);
1124    int[][] currentTables = quantizationTables;
1125    if (currentTables == null) {
1126        currentTables = new int[4][];
1127    }
1128    int[] dqtTablesKeys = dqt.getQuantizationTablesKeys();
1129    int[][] dqtTablesValues = dqt.getQuantizationTablesValues();
1130    for (int i = 0; i < dqtTablesKeys.length; i++) {
1131        int index = dqtTablesKeys[i];
1132        currentTables[index] = dqtTablesValues[i];
1133    }
1134    quantizationTables = currentTables;
1135}
1136void getDRI() {
1137    JPEGRestartInterval dri = new JPEGRestartInterval(inputStream);
1138    if (!dri.verify()) {
1139        SWT.error(SWT.ERROR_INVALID_IMAGE);
1140    }
1141    restartInterval = dri.getRestartInterval();
1142}
1143static void initialize() {
1144    initializeRGBYCbCrTables();
1145    initializeYCbCrRGBTables();
1146    initializeBitCountTable();
1147}
1148static void initializeBitCountTable() {
1149    int nBits = 1;
1150    int power2 = 2;
1151    NBitsTable = new int[2048];
1152    NBitsTable[0] = 0;
1153    for (int i = 1; i < NBitsTable.length; i++) {
1154        if (!(i < power2)) {
1155            nBits++;
1156            power2 *= 2;
1157        }
1158        NBitsTable[i] = nBits;
1159    }
1160}
1161static void initializeRGBYCbCrTables() {
1162    RYTable = new int[256];
1163    GYTable = new int[256];
1164    BYTable = new int[256];
1165    RCbTable = new int[256];
1166    GCbTable = new int[256];
1167    BCbTable = new int[256];
1168    RCrTable = BCbTable;
1169    GCrTable = new int[256];
1170    BCrTable = new int[256];
1171    for (int i = 0; i < 256; i++) {
1172        RYTable[i] = i * 19595;
1173        GYTable[i] = i * 38470;
1174        BYTable[i] = i * 7471 + 32768;
1175        RCbTable[i] = i * -11059;
1176        GCbTable[i] = i * -21709;
1177        BCbTable[i] = i * 32768 + 8388608;
1178        GCrTable[i] = i * -27439;
1179        BCrTable[i] = i * -5329;
1180    }
1181}
1182static void initializeYCbCrRGBTables() {
1183    CrRTable = new int[256];
1184    CbBTable = new int[256];
1185    CrGTable = new int[256];
1186    CbGTable = new int[256];
1187    for (int i = 0; i < 256; i++) {
1188        int x2 = 2 * i - 255;
1189        CrRTable[i] = (45941 * x2 + 32768) >> 16;
1190        CbBTable[i] = (58065 * x2 + 32768) >> 16;
1191        CrGTable[i] = -23401 * x2;
1192        CbGTable[i] = -11277 * x2 + 32768;
1193    }
1194}
1195void inverseDCT(int[] dataUnit) {
1196    for (int row = 0; row < 8; row++) {
1197        int rIndex = row * DCTSIZE;
1198        /**
1199         * Due to quantization, we will usually find that many of the input
1200         * coefficients are zero, especially the AC terms. We can exploit this
1201         * by short-circuiting the IDCT calculation for any row in which all
1202         * the AC terms are zero. In that case each output is equal to the
1203         * DC coefficient (with scale factor as needed).
1204         * With typical images and quantization tables, half or more of the
1205         * row DCT calculations can be simplified this way.
1206         */

1207        if (isZeroInRow(dataUnit, rIndex)) {
1208            int dcVal = dataUnit[rIndex] << 2;
1209            for (int i = rIndex + 7; i >= rIndex; i--) {
1210                dataUnit[i] = dcVal;
1211            }
1212        } else {
1213            /**
1214             * Even part: reverse the even part of the forward DCT.
1215             * The rotator is sqrt(2)*c(-6).
1216             */

1217            int z2 = dataUnit[rIndex + 2];
1218            int z3 = dataUnit[rIndex + 6];
1219            int z1 = (z2 + z3) * FIX_0_541196100;
1220            int tmp2 = z1 + (z3 * (0 - FIX_1_847759065));
1221            int tmp3 = z1 + (z2 * FIX_0_765366865);
1222            int tmp0 = (dataUnit[rIndex] + dataUnit[rIndex + 4]) << 13;
1223            int tmp1 = (dataUnit[rIndex] - dataUnit[rIndex + 4]) << 13;
1224            int tmp10 = tmp0 + tmp3;
1225            int tmp13 = tmp0 - tmp3;
1226            int tmp11 = tmp1 + tmp2;
1227            int tmp12 = tmp1 - tmp2;
1228            /**
1229             * Odd part per figure 8; the matrix is unitary and hence its
1230             * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
1231             */

1232            tmp0 = dataUnit[rIndex + 7];
1233            tmp1 = dataUnit[rIndex + 5];
1234            tmp2 = dataUnit[rIndex + 3];
1235            tmp3 = dataUnit[rIndex + 1];
1236            z1 = tmp0 + tmp3;
1237            z2 = tmp1 + tmp2;
1238            z3 = tmp0 + tmp2;
1239            int z4 = tmp1 + tmp3;
1240            int z5 = (z3 + z4) * FIX_1_175875602; /* sqrt(2) * c3 */
1241              
1242            tmp0 *= FIX_0_298631336; /* sqrt(2) * (-c1+c3+c5-c7) */
1243            tmp1 *= FIX_2_053119869; /* sqrt(2) * ( c1+c3-c5+c7) */
1244            tmp2 *= FIX_3_072711026; /* sqrt(2) * ( c1+c3+c5-c7) */
1245            tmp3 *= FIX_1_501321110; /* sqrt(2) * ( c1+c3-c5-c7) */
1246            z1 *= 0 - FIX_0_899976223; /* sqrt(2) * (c7-c3) */
1247            z2 *= 0 - FIX_2_562915447; /* sqrt(2) * (-c1-c3) */
1248            z3 *= 0 - FIX_1_961570560; /* sqrt(2) * (-c3-c5) */
1249            z4 *= 0 - FIX_0_390180644; /* sqrt(2) * (c5-c3) */
1250
1251            z3 += z5;
1252            z4 += z5;
1253            tmp0 += z1 + z3;
1254            tmp1 += z2 + z4;
1255            tmp2 += z2 + z3;
1256            tmp3 += z1 + z4;
1257
1258            dataUnit[rIndex] = (tmp10 + tmp3 + 1024) >> 11;
1259            dataUnit[rIndex + 7] = (tmp10 - tmp3 + 1024) >> 11;
1260            dataUnit[rIndex + 1] = (tmp11 + tmp2 + 1024) >> 11;
1261            dataUnit[rIndex + 6] = (tmp11 - tmp2 + 1024) >> 11;
1262            dataUnit[rIndex + 2] = (tmp12 + tmp1 + 1024) >> 11;
1263            dataUnit[rIndex + 5] = (tmp12 - tmp1 + 1024) >> 11;
1264            dataUnit[rIndex + 3] = (tmp13 + tmp0 + 1024) >> 11;
1265            dataUnit[rIndex + 4] = (tmp13 - tmp0 + 1024) >> 11;
1266         }
1267    }
1268    /**
1269     * Pass 2: process columns.
1270     * Note that we must descale the results by a factor of 8 == 2**3,
1271     * and also undo the PASS1_BITS scaling.
1272     */

1273    for (int col = 0; col < 8; col++) {
1274        int c0 = col;
1275        int c1 = col + 8;
1276        int c2 = col + 16;
1277        int c3 = col + 24;
1278        int c4 = col + 32;
1279        int c5 = col + 40;
1280        int c6 = col + 48;
1281        int c7 = col + 56;
1282        if (isZeroInColumn(dataUnit, col)) {
1283            int dcVal = (dataUnit[c0] + 16) >> 5;
1284            dataUnit[c0] = dcVal;
1285            dataUnit[c1] = dcVal;
1286            dataUnit[c2] = dcVal;
1287            dataUnit[c3] = dcVal;
1288            dataUnit[c4] = dcVal;
1289            dataUnit[c5] = dcVal;
1290            dataUnit[c6] = dcVal;
1291            dataUnit[c7] = dcVal;
1292        } else {
1293            /**
1294             * Even part: reverse the even part of the forward DCT.
1295             * The rotator is sqrt(2)*c(-6).
1296             */

1297            int z0 = dataUnit[c0];
1298            int z2 = dataUnit[c2];
1299            int z3 = dataUnit[c6];
1300            int z4 = dataUnit[c4];
1301            int z1 = (z2 + z3) * FIX_0_541196100;
1302            int tmp2 = z1 + (z3 * (0 - FIX_1_847759065));
1303            int tmp3 = z1 + (z2 * FIX_0_765366865);
1304            int tmp0 = (z0 + z4) << 13;
1305            int tmp1 = (z0 - z4) << 13;
1306            int tmp10 = tmp0 + tmp3;
1307            int tmp13 = tmp0 - tmp3;
1308            int tmp11 = tmp1 + tmp2;
1309            int tmp12 = tmp1 - tmp2;
1310            /**
1311             * Odd part per figure 8; the matrix is unitary and hence its
1312             * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
1313             */

1314            tmp0 = dataUnit[c7];
1315            tmp1 = dataUnit[c5];
1316            tmp2 = dataUnit[c3];
1317            tmp3 = dataUnit[c1];
1318            z1 = tmp0 + tmp3;
1319            z2 = tmp1 + tmp2;
1320            z3 = tmp0 + tmp2;
1321            z4 = tmp1 + tmp3;
1322            z0 = (z3 + z4) * FIX_1_175875602; /* sqrt(2) * c3 */
1323            
1324            tmp0 *= FIX_0_298631336; /* sqrt(2) * (-c1+c3+c5-c7) */
1325            tmp1 *= FIX_2_053119869; /* sqrt(2) * ( c1+c3-c5+c7) */
1326            tmp2 *= FIX_3_072711026; /* sqrt(2) * ( c1+c3+c5-c7) */
1327            tmp3 *= FIX_1_501321110; /* sqrt(2) * ( c1+c3-c5-c7) */
1328            z1 *= 0 - FIX_0_899976223; /* sqrt(2) * (c7-c3) */
1329            z2 *= 0 - FIX_2_562915447; /* sqrt(2) * (-c1-c3) */
1330            z3 *= 0 - FIX_1_961570560; /* sqrt(2) * (-c3-c5) */
1331            z4 *= 0 - FIX_0_390180644; /* sqrt(2) * (c5-c3) */
1332            
1333            z3 += z0;
1334            z4 += z0;
1335            
1336            tmp0 += z1 + z3;
1337            tmp1 += z2 + z4;
1338            tmp2 += z2 + z3;
1339            tmp3 += z1 + z4;
1340
1341            /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
1342            dataUnit[c0] = (tmp10 + tmp3 + 131072) >> 18;
1343            dataUnit[c7] = (tmp10 - tmp3 + 131072) >> 18;
1344            dataUnit[c1] = (tmp11 + tmp2 + 131072) >> 18;
1345            dataUnit[c6] = (tmp11 - tmp2 + 131072) >> 18;
1346            dataUnit[c2] = (tmp12 + tmp1 + 131072) >> 18;
1347            dataUnit[c5] = (tmp12 - tmp1 + 131072) >> 18;
1348            dataUnit[c3] = (tmp13 + tmp0 + 131072) >> 18;
1349            dataUnit[c4] = (tmp13 - tmp0 + 131072) >> 18;
1350        }
1351    }
1352}
1353boolean isFileFormat(LEDataInputStream stream) {
1354    try {
1355        JPEGStartOfImage soi = new JPEGStartOfImage(stream);
1356        stream.unread(soi.reference);
1357        return soi.verify(); // we no longer check for appN
1358
} catch (Exception JavaDoc e) {
1359        return false;
1360    }
1361}
1362boolean isZeroInColumn(int[] dataUnit, int col) {
1363    return dataUnit[col + 8] == 0 && dataUnit[col + 16] == 0
1364            && dataUnit[col + 24] == 0 && dataUnit[col + 32] == 0
1365            && dataUnit[col + 40] == 0 && dataUnit[col + 48] == 0
1366            && dataUnit[col + 56] == 0;
1367}
1368boolean isZeroInRow(int[] dataUnit, int rIndex) {
1369    return dataUnit[rIndex + 1] == 0 && dataUnit[rIndex + 2] == 0
1370            && dataUnit[rIndex + 3] == 0 && dataUnit[rIndex + 4] == 0
1371            && dataUnit[rIndex + 5] == 0 && dataUnit[rIndex + 6] == 0
1372            && dataUnit[rIndex + 7] == 0;
1373}
1374ImageData[] loadFromByteStream() {
1375    //TEMPORARY CODE
1376
if (System.getProperty("org.eclipse.swt.internal.image.JPEGFileFormat_3.2") == null) {
1377        return JPEGDecoder.loadFromByteStream(inputStream, loader);
1378    }
1379    JPEGStartOfImage soi = new JPEGStartOfImage(inputStream);
1380    if (!soi.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
1381    restartInterval = 0;
1382
1383    /* Process the tables preceding the frame header. */
1384    processTables();
1385    
1386    /* Start of Frame. */
1387    frameHeader = new JPEGFrameHeader(inputStream);
1388    if (!frameHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
1389    imageWidth = frameHeader.getSamplesPerLine();
1390    imageHeight = frameHeader.getNumberOfLines();
1391    maxH = frameHeader.getMaxHFactor();
1392    maxV = frameHeader.getMaxVFactor();
1393    int mcuWidth = maxH * DCTSIZE;
1394    int mcuHeight = maxV * DCTSIZE;
1395    interleavedMcuCols = (imageWidth + mcuWidth - 1) / mcuWidth;
1396    interleavedMcuRows = (imageHeight + mcuHeight - 1) / mcuHeight;
1397    progressive = frameHeader.isProgressive();
1398    samplePrecision = frameHeader.getSamplePrecision();
1399    nComponents = frameHeader.getNumberOfImageComponents();
1400    frameComponents = frameHeader.componentParameters;
1401    componentIds = frameHeader.componentIdentifiers;
1402    imageComponents = new byte[nComponents][];
1403    if (progressive) {
1404        // Progressive jpeg: need to keep all of the data units.
1405
dataUnits = new int[nComponents][][];
1406    } else {
1407        // Sequential jpeg: only need one data unit.
1408
dataUnit = new int[8 * 8];
1409    }
1410    for (int i = 0; i < nComponents; i++) {
1411        int[] frameComponent = frameComponents[componentIds[i]];
1412        int bufferSize = frameComponent[CW] * frameComponent[CH];
1413        imageComponents[i] = new byte[bufferSize];
1414        if (progressive) {
1415            dataUnits[i] = new int[bufferSize][];
1416        }
1417    }
1418
1419    /* Process the tables preceding the scan header. */
1420    processTables();
1421    
1422    /* Start of Scan. */
1423    scanHeader = new JPEGScanHeader(inputStream);
1424    if (!scanHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
1425    
1426    /* Process scan(s) and further tables until EOI. */
1427    int progressiveScanCount = 0;
1428    boolean done = false;
1429    while(!done) {
1430        resetInputBuffer();
1431        precedingDCs = new int[4];
1432        decodeScan();
1433        if (progressive && loader.hasListeners()) {
1434            ImageData imageData = createImageData();
1435            loader.notifyListeners(new ImageLoaderEvent(loader, imageData, progressiveScanCount, false));
1436            progressiveScanCount++;
1437        }
1438
1439        /* Unread any buffered data before looking for tables again. */
1440        int delta = 512 - bufferCurrentPosition - 1;
1441        if (delta > 0) {
1442            byte[] unreadBuffer = new byte[delta];
1443            System.arraycopy(dataBuffer, bufferCurrentPosition + 1, unreadBuffer, 0, delta);
1444            try {
1445                inputStream.unread(unreadBuffer);
1446            } catch (IOException e) {
1447                SWT.error(SWT.ERROR_IO, e);
1448            }
1449        }
1450        
1451        /* Process the tables preceding the next scan header. */
1452        JPEGSegment jpegSegment = processTables();
1453        if (jpegSegment == null || jpegSegment.getSegmentMarker() == EOI) {
1454            done = true;
1455        } else {
1456            scanHeader = new JPEGScanHeader(inputStream);
1457            if (!scanHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
1458        }
1459    }
1460    
1461    if (progressive) {
1462        for (int ymcu = 0; ymcu < interleavedMcuRows; ymcu++) {
1463            for (int xmcu = 0; xmcu < interleavedMcuCols; xmcu++) {
1464                for (int iComp = 0; iComp < nComponents; iComp++) {
1465                    int[] frameComponent = frameComponents[componentIds[iComp]];
1466                    int hi = frameComponent[HI];
1467                    int vi = frameComponent[VI];
1468                    int compWidth = frameComponent[CW];
1469                    for (int ivi = 0; ivi < vi; ivi++) {
1470                        for (int ihi = 0; ihi < hi; ihi++) {
1471                            int index = (ymcu * vi + ivi) * compWidth + xmcu * hi + ihi;
1472                            dataUnit = dataUnits[iComp][index];
1473                            dequantize(dataUnit, iComp);
1474                            inverseDCT(dataUnit);
1475                            storeData(dataUnit, iComp, xmcu, ymcu, hi, ihi, vi, ivi);
1476                        }
1477                    }
1478                }
1479            }
1480        }
1481        dataUnits = null; // release memory
1482
}
1483    ImageData imageData = createImageData();
1484    if (progressive && loader.hasListeners()) {
1485        loader.notifyListeners(new ImageLoaderEvent(loader, imageData, progressiveScanCount, true));
1486    }
1487    return new ImageData[] {imageData};
1488}
1489ImageData createImageData() {
1490    return ImageData.internal_new(
1491        imageWidth,
1492        imageHeight,
1493        nComponents * samplePrecision,
1494        setUpPalette(),
1495        nComponents == 1 ? 4 : 1,
1496        decodeImageComponents(),
1497        0,
1498        null,
1499        null,
1500        -1,
1501        -1,
1502        SWT.IMAGE_JPEG,
1503        0,
1504        0,
1505        0,
1506        0);
1507}
1508int nextBit() {
1509    if (currentBitCount != 0) {
1510        currentBitCount--;
1511        currentByte *= 2;
1512        if (currentByte > 255) {
1513            currentByte -= 256;
1514            return 1;
1515        } else {
1516            return 0;
1517        }
1518    }
1519    bufferCurrentPosition++;
1520    if (bufferCurrentPosition >= 512) {
1521        resetInputBuffer();
1522        bufferCurrentPosition = 0;
1523    }
1524    currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
1525    currentBitCount = 8;
1526    byte nextByte;
1527    if (bufferCurrentPosition == 511) {
1528        resetInputBuffer();
1529        currentBitCount = 8;
1530        nextByte = dataBuffer[0];
1531    } else {
1532        nextByte = dataBuffer[bufferCurrentPosition + 1];
1533    }
1534    if (currentByte == 0xFF) {
1535        if (nextByte == 0) {
1536            bufferCurrentPosition ++;
1537            currentBitCount--;
1538            currentByte *= 2;
1539            if (currentByte > 255) {
1540                currentByte -= 256;
1541                return 1;
1542            } else {
1543                return 0;
1544            }
1545        } else {
1546            if ((nextByte & 0xFF) + 0xFF00 == DNL) {
1547                getDNL();
1548                return 0;
1549            } else {
1550                SWT.error(SWT.ERROR_INVALID_IMAGE);
1551                return 0;
1552            }
1553        }
1554    } else {
1555        currentBitCount--;
1556        currentByte *= 2;
1557        if (currentByte > 255) {
1558            currentByte -= 256;
1559            return 1;
1560        } else {
1561            return 0;
1562        }
1563    }
1564}
1565void processRestartInterval() {
1566    do {
1567        bufferCurrentPosition++;
1568        if (bufferCurrentPosition > 511) {
1569            resetInputBuffer();
1570            bufferCurrentPosition = 0;
1571        }
1572        currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
1573    } while (currentByte != 0xFF);
1574    while (currentByte == 0xFF) {
1575        bufferCurrentPosition++;
1576        if (bufferCurrentPosition > 511) {
1577            resetInputBuffer();
1578            bufferCurrentPosition = 0;
1579        }
1580        currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
1581    }
1582    if (currentByte != ((RST0 + nextRestartNumber) & 0xFF)) {
1583        SWT.error(SWT.ERROR_INVALID_IMAGE);
1584    }
1585    bufferCurrentPosition++;
1586    if (bufferCurrentPosition > 511) {
1587        resetInputBuffer();
1588        bufferCurrentPosition = 0;
1589    }
1590    currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
1591    currentBitCount = 8;
1592    restartsToGo = restartInterval;
1593    nextRestartNumber = (nextRestartNumber + 1) & 0x7;
1594    precedingDCs = new int[4];
1595    eobrun = 0;
1596}
1597/* Process all markers until a frame header, scan header, or EOI is found. */
1598JPEGSegment processTables() {
1599    while (true) {
1600        JPEGSegment jpegSegment = seekUnspecifiedMarker(inputStream);
1601        if (jpegSegment == null) return null;
1602        JPEGFrameHeader sof = new JPEGFrameHeader(jpegSegment.reference);
1603        if (sof.verify()) {
1604            return jpegSegment;
1605        }
1606        int marker = jpegSegment.getSegmentMarker();
1607        switch (marker) {
1608            case SOI: // there should only be one SOI per file
1609
SWT.error(SWT.ERROR_INVALID_IMAGE);
1610            case EOI:
1611            case SOS:
1612                return jpegSegment;
1613            case DQT:
1614                getDQT();
1615                break;
1616            case DHT:
1617                getDHT();
1618                break;
1619            case DAC:
1620                getDAC();
1621                break;
1622            case DRI:
1623                getDRI();
1624                break;
1625            case APP0:
1626                getAPP0();
1627                break;
1628            case COM:
1629                getCOM();
1630                break;
1631            default:
1632                skipSegmentFrom(inputStream);
1633            
1634        }
1635    }
1636}
1637void quantizeData(int[] dataUnit, int iComp) {
1638    int[] qTable = quantizationTables[frameComponents[componentIds[iComp]][TQI]];
1639    for (int i = 0; i < dataUnit.length; i++) {
1640        int zzIndex = ZigZag8x8[i];
1641        int data = dataUnit[zzIndex];
1642        int absData = data < 0 ? 0 - data : data;
1643        int qValue = qTable[i];
1644        int q2 = qValue >> 1;
1645        absData += q2;
1646        if (absData < qValue) {
1647            dataUnit[zzIndex] = 0;
1648        } else {
1649            absData /= qValue;
1650            if (data >= 0) {
1651                dataUnit[zzIndex] = absData;
1652            } else {
1653                dataUnit[zzIndex] = 0 - absData;
1654            }
1655        }
1656    }
1657}
1658int receive(int nBits) {
1659    int v = 0;
1660    for (int i = 0; i < nBits; i++) {
1661        v = v * 2 + nextBit();
1662    }
1663    return v;
1664}
1665void resetInputBuffer() {
1666    if (dataBuffer == null) {
1667        dataBuffer = new byte[512];
1668    }
1669    try {
1670        inputStream.read(dataBuffer);
1671    } catch (IOException e) {
1672        SWT.error(SWT.ERROR_IO, e);
1673    }
1674    currentBitCount = 0;
1675    bufferCurrentPosition = -1;
1676}
1677void resetOutputBuffer() {
1678    if (dataBuffer == null) {
1679        dataBuffer = new byte[512];
1680    } else {
1681        try {
1682            outputStream.write(dataBuffer, 0, bufferCurrentPosition);
1683        } catch (IOException e) {
1684            SWT.error(SWT.ERROR_IO, e);
1685        }
1686    }
1687    bufferCurrentPosition = 0;
1688}
1689static JPEGSegment seekUnspecifiedMarker(LEDataInputStream byteStream) {
1690    byte[] byteArray = new byte[2];
1691    try {
1692        while (true) {
1693            if (byteStream.read(byteArray, 0, 1) != 1) return null;
1694            if (byteArray[0] == (byte) 0xFF) {
1695                if (byteStream.read(byteArray, 1, 1) != 1) return null;
1696                if (byteArray[1] != (byte) 0xFF && byteArray[1] != 0) {
1697                    byteStream.unread(byteArray);
1698                    return new JPEGSegment(byteArray);
1699                }
1700            }
1701        }
1702    } catch (IOException e) {
1703        SWT.error(SWT.ERROR_IO, e);
1704    }
1705    return null;
1706}
1707PaletteData setUpPalette() {
1708    if (nComponents == 1) {
1709        RGB[] entries = new RGB[256];
1710        for (int i = 0; i < 256; i++) {
1711            entries[i] = new RGB(i, i, i);
1712        }
1713        return new PaletteData(entries);
1714    }
1715    return new PaletteData(0xFF, 0xFF00, 0xFF0000);
1716}
1717static void skipSegmentFrom(LEDataInputStream byteStream) {
1718    try {
1719        byte[] byteArray = new byte[4];
1720        JPEGSegment jpegSegment = new JPEGSegment(byteArray);
1721    
1722        if (byteStream.read(byteArray) != byteArray.length) {
1723            SWT.error(SWT.ERROR_INVALID_IMAGE);
1724        }
1725        if (!(byteArray[0] == -1 && byteArray[1] != 0 && byteArray[1] != -1)) {
1726            SWT.error(SWT.ERROR_INVALID_IMAGE);
1727        }
1728        int delta = jpegSegment.getSegmentLength() - 2;
1729        byteStream.skip(delta);
1730    } catch (Exception JavaDoc e) {
1731        SWT.error(SWT.ERROR_IO, e);
1732    }
1733}
1734void storeData(int[] dataUnit, int iComp, int xmcu, int ymcu, int hi, int ihi, int vi, int ivi) {
1735    byte[] compImage = imageComponents[iComp];
1736    int[] frameComponent = frameComponents[componentIds[iComp]];
1737    int compWidth = frameComponent[CW];
1738    int destIndex = ((ymcu * vi + ivi) * compWidth * DCTSIZE) + ((xmcu * hi + ihi) * DCTSIZE);
1739    int srcIndex = 0;
1740    for (int i = 0; i < DCTSIZE; i++) {
1741        for (int col = 0; col < DCTSIZE; col++) {
1742            int x = dataUnit[srcIndex] + 128;
1743            if (x < 0) {
1744                x = 0;
1745            } else {
1746                if (x > 255) x = 255;
1747            }
1748            compImage[destIndex + col] = (byte)x;
1749            srcIndex++;
1750        }
1751        destIndex += compWidth;
1752    }
1753}
1754void unloadIntoByteStream(ImageLoader loader) {
1755    ImageData image = loader.data[0];
1756    if (!new JPEGStartOfImage().writeToStream(outputStream)) {
1757        SWT.error(SWT.ERROR_IO);
1758    }
1759    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});
1760    if (!appn.writeToStream(outputStream)) {
1761        SWT.error(SWT.ERROR_IO);
1762    }
1763    quantizationTables = new int[4][];
1764    JPEGQuantizationTable chromDQT = JPEGQuantizationTable.defaultChrominanceTable();
1765    chromDQT.scaleBy(encoderQFactor);
1766    int[] jpegDQTKeys = chromDQT.getQuantizationTablesKeys();
1767    int[][] jpegDQTValues = chromDQT.getQuantizationTablesValues();
1768    for (int i = 0; i < jpegDQTKeys.length; i++) {
1769        quantizationTables[jpegDQTKeys[i]] = jpegDQTValues[i];
1770    }
1771    JPEGQuantizationTable lumDQT = JPEGQuantizationTable.defaultLuminanceTable();
1772    lumDQT.scaleBy(encoderQFactor);
1773    jpegDQTKeys = lumDQT.getQuantizationTablesKeys();
1774    jpegDQTValues = lumDQT.getQuantizationTablesValues();
1775    for (int i = 0; i < jpegDQTKeys.length; i++) {
1776        quantizationTables[jpegDQTKeys[i]] = jpegDQTValues[i];
1777    }
1778    if (!lumDQT.writeToStream(outputStream)) {
1779        SWT.error(SWT.ERROR_IO);
1780    }
1781    if (!chromDQT.writeToStream(outputStream)) {
1782        SWT.error(SWT.ERROR_IO);
1783    }
1784    int frameLength, scanLength, precision;
1785    int[][] frameParams, scanParams;
1786    if (image.depth == 1) {
1787        frameLength = 11;
1788        frameParams = new int[1][];
1789        frameParams[0] = new int[] {1, 1, 1, 0, 0};
1790        scanParams = new int[1][];
1791        scanParams[0] = new int[] {0, 0};
1792        scanLength = 8;
1793        nComponents = 1;
1794        precision = 1;
1795    } else {
1796        frameLength = 17;
1797        frameParams = new int[3][];
1798        frameParams[0] = new int[] {0, 2, 2, 0, 0};
1799        frameParams[1] = new int[] {1, 1, 1, 0, 0};
1800        frameParams[2] = new int[] {1, 1, 1, 0, 0};
1801        scanParams = new int[3][];
1802        scanParams[0] = new int[] {0, 0};
1803        scanParams[1] = new int[] {1, 1};
1804        scanParams[2] = new int[] {1, 1};
1805        scanLength = 12;
1806        nComponents = 3;
1807        precision = 8;
1808    }
1809    imageWidth = image.width;
1810    imageHeight = image.height;
1811    frameHeader = new JPEGFrameHeader(new byte[19]);
1812    frameHeader.setSegmentMarker(SOF0);
1813    frameHeader.setSegmentLength(frameLength);
1814    frameHeader.setSamplePrecision(precision);
1815    frameHeader.setSamplesPerLine(imageWidth);
1816    frameHeader.setNumberOfLines(imageHeight);
1817    frameHeader.setNumberOfImageComponents(nComponents);
1818    frameHeader.componentParameters = frameParams;
1819    frameHeader.componentIdentifiers = new int[] {0, 1, 2};
1820    frameHeader.initializeContents();
1821    if (!frameHeader.writeToStream(outputStream)) {
1822        SWT.error(SWT.ERROR_IO);
1823    }
1824    frameComponents = frameParams;
1825    componentIds = frameHeader.componentIdentifiers;
1826    maxH = frameHeader.getMaxHFactor();
1827    maxV = frameHeader.getMaxVFactor();
1828    int mcuWidth = maxH * DCTSIZE;
1829    int mcuHeight = maxV * DCTSIZE;
1830    interleavedMcuCols = (imageWidth + mcuWidth - 1) / mcuWidth;
1831    interleavedMcuRows = (imageHeight + mcuHeight - 1) / mcuHeight;
1832    acHuffmanTables = new JPEGHuffmanTable[4];
1833    dcHuffmanTables = new JPEGHuffmanTable[4];
1834    JPEGHuffmanTable[] dhtTables = new JPEGHuffmanTable[] {
1835        JPEGHuffmanTable.getDefaultDCLuminanceTable(),
1836        JPEGHuffmanTable.getDefaultDCChrominanceTable(),
1837        JPEGHuffmanTable.getDefaultACLuminanceTable(),
1838        JPEGHuffmanTable.getDefaultACChrominanceTable()
1839    };
1840    for (int i = 0; i < dhtTables.length; i++) {
1841        JPEGHuffmanTable dhtTable = dhtTables[i];
1842        if (!dhtTable.writeToStream(outputStream)) {
1843            SWT.error(SWT.ERROR_IO);
1844        }
1845        JPEGHuffmanTable[] allTables = dhtTable.getAllTables();
1846        for (int j = 0; j < allTables.length; j++) {
1847            JPEGHuffmanTable huffmanTable = allTables[j];
1848            if (huffmanTable.getTableClass() == 0) {
1849                dcHuffmanTables[huffmanTable.getTableIdentifier()] = huffmanTable;
1850            } else {
1851                acHuffmanTables[huffmanTable.getTableIdentifier()] = huffmanTable;
1852            }
1853        }
1854    }
1855    precedingDCs = new int[4];
1856    scanHeader = new JPEGScanHeader(new byte[14]);
1857    scanHeader.setSegmentMarker(SOS);
1858    scanHeader.setSegmentLength(scanLength);
1859    scanHeader.setNumberOfImageComponents(nComponents);
1860    scanHeader.setStartOfSpectralSelection(0);
1861    scanHeader.setEndOfSpectralSelection(63);
1862    scanHeader.componentParameters = scanParams;
1863    scanHeader.initializeContents();
1864    if (!scanHeader.writeToStream(outputStream)) {
1865        SWT.error(SWT.ERROR_IO);
1866    }
1867    convertImageToYCbCr(image);
1868    resetOutputBuffer();
1869    currentByte = 0;
1870    currentBitCount = 0;
1871    encodeScan();
1872    if (!new JPEGEndOfImage().writeToStream(outputStream)) {
1873        SWT.error(SWT.ERROR_IO);
1874    }
1875}
1876}
1877
Popular Tags