/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.internal.image;


import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import java.io.*;

final class JPEGFileFormat extends FileFormat {
	int restartInterval;
	JPEGFrameHeader frameHeader;
	int imageWidth, imageHeight;
	int interleavedMcuCols, interleavedMcuRows;
	int maxV, maxH;
	boolean progressive;
	int samplePrecision;
	int nComponents;
	int[][] frameComponents;
	int[] componentIds;
	byte[][] imageComponents;
	int[] dataUnit;
	int[][][] dataUnits;
	int[] precedingDCs;
	JPEGScanHeader scanHeader;
	byte[] dataBuffer;
	int currentBitCount;
	int bufferCurrentPosition;
	int restartsToGo;
	int nextRestartNumber;
	JPEGHuffmanTable[] acHuffmanTables;
	JPEGHuffmanTable[] dcHuffmanTables;
	int[][] quantizationTables;
	int currentByte;
	int encoderQFactor = 75;
	int eobrun = 0;
	/* JPEGConstants */
	public static final int DCTSIZE = 8;
	public static final int DCTSIZESQR = 64;
	/* JPEGFixedPointConstants */
	public static final int FIX_0_899976223 = 7373;
	public static final int FIX_1_961570560 = 16069;
	public static final int FIX_2_053119869 = 16819;
	public static final int FIX_0_298631336 = 2446;
	public static final int FIX_1_847759065 = 15137;
	public static final int FIX_1_175875602 = 9633;
	public static final int FIX_3_072711026 = 25172;
	public static final int FIX_0_765366865 = 6270;
	public static final int FIX_2_562915447 = 20995;
	public static final int FIX_0_541196100 = 4433;
	public static final int FIX_0_390180644 = 3196;
	public static final int FIX_1_501321110 = 12299;
	/* JPEGMarkerCodes */
	public static final int APP0  = 0xFFE0;
	public static final int APP15 = 0xFFEF;
	public static final int COM   = 0xFFFE;
	public static final int DAC   = 0xFFCC;
	public static final int DHP   = 0xFFDE;
	public static final int DHT   = 0xFFC4;
	public static final int DNL   = 0xFFDC;
	public static final int DRI   = 0xFFDD;
	public static final int DQT   = 0xFFDB;
	public static final int EOI   = 0xFFD9;
	public static final int EXP   = 0xFFDF;
	public static final int JPG   = 0xFFC8;
	public static final int JPG0  = 0xFFF0;
	public static final int JPG13 = 0xFFFD;
	public static final int RST0  = 0xFFD0;
	public static final int RST1  = 0xFFD1;
	public static final int RST2  = 0xFFD2;
	public static final int RST3  = 0xFFD3;
	public static final int RST4  = 0xFFD4;
	public static final int RST5  = 0xFFD5;
	public static final int RST6  = 0xFFD6;
	public static final int RST7  = 0xFFD7;
	public static final int SOF0  = 0xFFC0;
	public static final int SOF1  = 0xFFC1;
	public static final int SOF2  = 0xFFC2;
	public static final int SOF3  = 0xFFC3;
	public static final int SOF5  = 0xFFC5;
	public static final int SOF6  = 0xFFC6;
	public static final int SOF7  = 0xFFC7;
	public static final int SOF9  = 0xFFC9;
	public static final int SOF10 = 0xFFCA;
	public static final int SOF11 = 0xFFCB;
	public static final int SOF13 = 0xFFCD;
	public static final int SOF14 = 0xFFCE;
	public static final int SOF15 = 0xFFCF;
	public static final int SOI   = 0xFFD8;
	public static final int SOS   = 0xFFDA;
	public static final int TEM   = 0xFF01;
	/* JPEGFrameComponentParameterConstants */
	public static final int TQI	= 0;
	public static final int HI	= 1;
	public static final int VI	= 2;
	public static final int CW	= 3;
	public static final int CH	= 4;
	/* JPEGScanComponentParameterConstants */
	public static final int DC	= 0;
	public static final int AC	= 1;
	/* JFIF Component Constants */
	public static final int ID_Y		= 1 - 1;
	public static final int ID_CB	= 2 - 1;
	public static final int ID_CR	= 3 - 1;
	public static final RGB[] RGB16 = new RGB[] {
		new RGB(0,0,0),
		new RGB(0x80,0,0),
		new RGB(0,0x80,0),
		new RGB(0x80,0x80,0),
		new RGB(0,0,0x80),
		new RGB(0x80,0,0x80),
		new RGB(0,0x80,0x80),
		new RGB(0xC0,0xC0,0xC0),
		new RGB(0x80,0x80,0x80),
		new RGB(0xFF,0,0),
		new RGB(0,0xFF,0),
		new RGB(0xFF,0xFF,0),
		new RGB(0,0,0xFF),
		new RGB(0xFF,0,0xFF),
		new RGB(0,0xFF,0xFF),
		new RGB(0xFF,0xFF,0xFF),
	};
	public static final int[] ExtendTest = {
		0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 
		4096, 8192, 16384, 32768, 65536, 131072, 262144
	};
	public static final int[] ExtendOffset = new int[] {
		0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047, 
		-4095, -8191, -16383, -32767, -65535, -131071, -262143
	};
	public static final int[] ZigZag8x8 = {
		0, 1, 8, 16, 9, 2, 3, 10,
		17, 24, 32, 25, 18, 11, 4, 5,
		12, 19, 26, 33, 40, 48, 41, 34,
		27, 20, 13, 6, 7, 14, 21, 28,
		35, 42, 49, 56, 57, 50, 43, 36,
		29, 22, 15, 23, 30, 37, 44, 51,
		58, 59, 52, 45, 38, 31, 39, 46,
		53, 60, 61, 54, 47, 55, 62, 63
	};

	public static int[] CrRTable, CbBTable, CrGTable, CbGTable;
	public static int[] RYTable, GYTable, BYTable,
		RCbTable, GCbTable, BCbTable, RCrTable, GCrTable, BCrTable, NBitsTable;
	static {
		initialize();
	}
void compress(ImageData image, byte[] dataYComp, byte[] dataCbComp, byte[] dataCrComp) {
	int srcWidth = image.width;
	int srcHeight = image.height;
	int vhFactor = maxV * maxH;
	int[] frameComponent;
	imageComponents = new byte[nComponents][];
	for (int i = 0; i < nComponents; i++) {
		frameComponent = frameComponents[componentIds[i]];
		imageComponents[i] = new byte[frameComponent[CW] * frameComponent[CH]];
	}
	frameComponent = frameComponents[componentIds[ID_Y]];
	for (int yPos = 0; yPos < srcHeight; yPos++) {
		int srcOfs = yPos * srcWidth;
		int dstOfs = yPos * frameComponent[CW];
		System.arraycopy(dataYComp, srcOfs, imageComponents[ID_Y], dstOfs, srcWidth);
	}
	frameComponent = frameComponents[componentIds[ID_CB]];
	for (int yPos = 0; yPos < srcHeight / maxV; yPos++) {
		int destRowIndex = yPos * frameComponent[CW];
		for (int xPos = 0; xPos < srcWidth / maxH; xPos++) {
			int sum = 0;
			for (int iv = 0; iv < maxV; iv++) {
				int srcIndex = (yPos * maxV + iv) * srcWidth + (xPos * maxH);
				for (int ih = 0; ih < maxH; ih++) {
					sum += dataCbComp[srcIndex + ih] & 0xFF;
				}
			}
			imageComponents[ID_CB][destRowIndex + xPos] = (byte)(sum / vhFactor);
		}
	}
	frameComponent = frameComponents[componentIds[ID_CR]];
	for (int yPos = 0; yPos < srcHeight / maxV; yPos++) {
		int destRowIndex = yPos * frameComponent[CW];
		for (int xPos = 0; xPos < srcWidth / maxH; xPos++) {
			int sum = 0;
			for (int iv = 0; iv < maxV; iv++) {
				int srcIndex = (yPos * maxV + iv) * srcWidth + (xPos * maxH);
				for (int ih = 0; ih < maxH; ih++) {
					sum += dataCrComp[srcIndex + ih] & 0xFF;
				}
			}
			imageComponents[ID_CR][destRowIndex + xPos] = (byte)(sum / vhFactor);
		}
	}
	for (int iComp = 0; iComp < nComponents; iComp++) {
		byte[] imageComponent = imageComponents[iComp];
		frameComponent = frameComponents[componentIds[iComp]];
		int hFactor = frameComponent[HI];
		int vFactor = frameComponent[VI];
		int componentWidth = frameComponent[CW];
		int componentHeight = frameComponent[CH];
		int compressedWidth = srcWidth / (maxH / hFactor);
		int compressedHeight = srcHeight / (maxV / vFactor);
		if (compressedWidth < componentWidth) {
			int delta = componentWidth - compressedWidth;
			for (int yPos = 0; yPos < compressedHeight; yPos++) {
				int dstOfs = ((yPos + 1) * componentWidth - delta);
				int dataValue = imageComponent[dstOfs - 1] & 0xFF;
				for (int i = 0; i < delta; i++) {
					imageComponent[dstOfs + i] = (byte)dataValue;
				}
			}
		}
		if (compressedHeight < componentHeight) {
			int srcOfs = (compressedHeight - 1) * componentWidth;
			for (int yPos = compressedHeight; yPos <= componentHeight; yPos++) {
				int dstOfs = (yPos - 1) * componentWidth;
				System.arraycopy(imageComponent, srcOfs, imageComponent, dstOfs, componentWidth);
			}
		}
	}
}
void convert4BitRGBToYCbCr(ImageData image) {
	RGB[] rgbs = image.getRGBs();
	int paletteSize = rgbs.length;
	byte[] yComp = new byte[paletteSize];
	byte[] cbComp = new byte[paletteSize];
	byte[] crComp = new byte[paletteSize];
	int srcWidth = image.width;
	int srcHeight = image.height;
	for (int i = 0; i < paletteSize; i++) {
		RGB color = rgbs[i];
		int r = color.red;
		int g = color.green;
		int b = color.blue;
		int n = RYTable[r] + GYTable[g] + BYTable[b];
		yComp[i] = (byte)(n >> 16);
		if ((n < 0) && ((n & 0xFFFF) != 0)) yComp[i]--;
		n = RCbTable[r] + GCbTable[g] + BCbTable[b];
		cbComp[i] = (byte)(n >> 16);
		if ((n < 0) && ((n & 0xFFFF) != 0)) cbComp[i]--;
		n = RCrTable[r] + GCrTable[g] + BCrTable[b];
		crComp[i] = (byte)(n >> 16);
		if ((n < 0) && ((n & 0xFFFF) != 0)) crComp[i]--;
	}
	int bSize = srcWidth * srcHeight;
	byte[] dataYComp = new byte[bSize];
	byte[] dataCbComp = new byte[bSize];
	byte[] dataCrComp = new byte[bSize];
	byte[] origData = image.data;
	int bytesPerLine = image.bytesPerLine;
	int maxScanlineByte = srcWidth >> 1;
	for (int yPos = 0; yPos < srcHeight; yPos++) {
		for (int xPos = 0; xPos < maxScanlineByte; xPos++) {
			int srcIndex = yPos * bytesPerLine + xPos;
			int dstIndex = yPos * srcWidth + (xPos * 2);
			int value2 = origData[srcIndex] & 0xFF;
			int value1 = value2 >> 4;
			value2 &= 0x0F;
			dataYComp[dstIndex] = yComp[value1];
			dataCbComp[dstIndex] = cbComp[value1];
			dataCrComp[dstIndex] = crComp[value1];
			dataYComp[dstIndex + 1] = yComp[value2];
			dataCbComp[dstIndex + 1] = cbComp[value2];
			dataCrComp[dstIndex + 1] = crComp[value2];
		}
	}
	compress(image, dataYComp, dataCbComp, dataCrComp);
}
void convert8BitRGBToYCbCr(ImageData image) {
	RGB[] rgbs = image.getRGBs();
	int paletteSize = rgbs.length;
	byte[] yComp = new byte[paletteSize];
	byte[] cbComp = new byte[paletteSize];
	byte[] crComp = new byte[paletteSize];
	int srcWidth = image.width;
	int srcHeight = image.height;
	for (int i = 0; i < paletteSize; i++) {
		RGB color = rgbs[i];
		int r = color.red;
		int g = color.green;
		int b = color.blue;
		int n = RYTable[r] + GYTable[g] + BYTable[b];
		yComp[i] = (byte)(n >> 16);
		if ((n < 0) && ((n & 0xFFFF) != 0)) yComp[i]--;
		n = RCbTable[r] + GCbTable[g] + BCbTable[b];
		cbComp[i] = (byte)(n >> 16);
		if ((n < 0) && ((n & 0xFFFF) != 0)) cbComp[i]--;
		n = RCrTable[r] + GCrTable[g] + BCrTable[b];
		crComp[i] = (byte)(n >> 16);
		if ((n < 0) && ((n & 0xFFFF) != 0)) crComp[i]--;
	}
	int dstWidth = image.width;
	int dstHeight = srcHeight;
	int stride = ((srcWidth + 3) >> 2) << 2;
	int bSize = dstWidth * dstHeight;
	byte[] dataYComp = new byte[bSize];
	byte[] dataCbComp = new byte[bSize];
	byte[] dataCrComp = new byte[bSize];
	byte[] origData = image.data;
	for (int yPos = 0; yPos < srcHeight; yPos++) {
		int srcRowIndex = yPos * stride;
		int dstRowIndex = yPos * dstWidth;
		for (int xPos = 0; xPos < srcWidth; xPos++) {
			int value = origData[srcRowIndex + xPos] & 0xFF;
			int dstIndex = dstRowIndex + xPos;
			dataYComp[dstIndex] = yComp[value];
			dataCbComp[dstIndex] = cbComp[value];
			dataCrComp[dstIndex] = crComp[value];
		}
	}
	compress(image, dataYComp, dataCbComp, dataCrComp);
}
byte[] convertCMYKToRGB() {
	/* Unsupported CMYK format. Answer an empty byte array. */
	return new byte[0];
}
void convertImageToYCbCr(ImageData image) {
	switch (image.depth) {
		case 4:
			convert4BitRGBToYCbCr(image);
			return;
		case 8:
			convert8BitRGBToYCbCr(image);
			return;
		case 16:
		case 24:
		case 32:
			convertMultiRGBToYCbCr(image);
			return;
		default:
			SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
	}
	return;
}
void convertMultiRGBToYCbCr(ImageData image) {
	int srcWidth = image.width;
	int srcHeight = image.height;
	int bSize = srcWidth * srcHeight;
	byte[] dataYComp = new byte[bSize];
	byte[] dataCbComp = new byte[bSize];
	byte[] dataCrComp = new byte[bSize];
	PaletteData palette = image.palette;
	int[] buffer = new int[srcWidth];
	if (palette.isDirect) {
		int redMask = palette.redMask;
		int greenMask = palette.greenMask;
		int blueMask = palette.blueMask;
		int redShift = palette.redShift;
		int greenShift = palette.greenShift;
		int blueShift = palette.blueShift;
		for (int yPos = 0; yPos < srcHeight; yPos++) {
			image.getPixels(0, yPos, srcWidth, buffer, 0);
			int dstRowIndex = yPos * srcWidth;
			for (int xPos = 0; xPos < srcWidth; xPos++) {
				int pixel = buffer[xPos];
				int dstDataIndex = dstRowIndex + xPos;
				int r = pixel & redMask;
				r = (redShift < 0) ? r >>> -redShift : r << redShift;
				int g = pixel & greenMask;
				g = (greenShift < 0) ? g >>> -greenShift : g << greenShift;
				int b = pixel & blueMask;
				b = (blueShift < 0) ? b >>> -blueShift : b << blueShift;				
				dataYComp[dstDataIndex] = (byte)((RYTable[r] + GYTable[g] + BYTable[b]) >> 16);
				dataCbComp[dstDataIndex] = (byte)((RCbTable[r] + GCbTable[g] + BCbTable[b]) >> 16);
				dataCrComp[dstDataIndex] = (byte)((RCrTable[r] + GCrTable[g] + BCrTable[b]) >> 16);
			}
		}
	} else {
		for (int yPos = 0; yPos < srcHeight; yPos++) {
			image.getPixels(0, yPos, srcWidth, buffer, 0);
			int dstRowIndex = yPos * srcWidth;
			for (int xPos = 0; xPos < srcWidth; xPos++) {
				int pixel = buffer[xPos];
				int dstDataIndex = dstRowIndex + xPos;
				RGB rgb = palette.getRGB(pixel);
				int r = rgb.red;
				int g = rgb.green;
				int b = rgb.blue;
				dataYComp[dstDataIndex] = (byte)((RYTable[r] + GYTable[g] + BYTable[b]) >> 16);
				dataCbComp[dstDataIndex] = (byte)((RCbTable[r] + GCbTable[g] + BCbTable[b]) >> 16);
				dataCrComp[dstDataIndex] = (byte)((RCrTable[r] + GCrTable[g] + BCrTable[b]) >> 16);
			}
		}
	}
	compress(image, dataYComp, dataCbComp, dataCrComp);
}
byte[] convertYToRGB() {
	int compWidth = frameComponents[componentIds[ID_Y]][CW];
	int bytesPerLine = (((imageWidth * 8 + 7) / 8) + 3) / 4 * 4;
	byte[] data = new byte[bytesPerLine * imageHeight];
	byte[] yComp = imageComponents[ID_Y];
	int destIndex = 0;
	for (int i = 0; i < imageHeight; i++) {
		int srcIndex = i * compWidth;
		for (int j = 0; j < bytesPerLine; j++) {
			int y = yComp[srcIndex] & 0xFF;
			if (y < 0) {
				y = 0;
			} else {
				if (y > 255) y = 255;
			}
			if (j >= imageWidth) {
				y = 0;
			}
			data[destIndex] = (byte)y;
			srcIndex++;
			destIndex++;
		}
	}
	return data;
}
byte[] convertYCbCrToRGB() {
	/**
	 * Convert existing image components into an RGB format.
	 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
	 * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
	 * The conversion equations to be implemented are therefore
	 * 	R = Y                + 1.40200 * Cr
	 * 	G = Y - 0.34414 * Cb - 0.71414 * Cr
	 * 	B = Y + 1.77200 * Cb
	 * where Cb and Cr represent the incoming values less MAXJSAMPLE/2.
	 * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
	 * 
	 * To avoid floating-point arithmetic, we represent the fractional constants
	 * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
	 * the products by 2^16, with appropriate rounding, to get the correct answer.
	 * Notice that Y, being an integral input, does not contribute any fraction
	 * so it need not participate in the rounding.
	 * 
	 * For even more speed, we avoid doing any multiplications in the inner loop
	 * by precalculating the constants times Cb and Cr for all possible values.
	 * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
	 * for 12-bit samples it is still acceptable.  It's not very reasonable for
	 * 16-bit samples, but if you want lossless storage you shouldn't be changing
	 * colorspace anyway.
	 * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
	 * values for the G calculation are left scaled up, since we must add them
	 * together before rounding.
	 */
	int bSize = imageWidth * imageHeight * nComponents;
	byte[] rgbData = new byte[bSize];
	int destIndex = 0;
	expandImageComponents();
	byte[] yComp = imageComponents[ID_Y];
	byte[] cbComp = imageComponents[ID_CB];
	byte[] crComp = imageComponents[ID_CR];
	int compWidth = frameComponents[componentIds[ID_Y]][CW];
	for (int v = 0; v < imageHeight; v++) {
		int srcIndex = v * compWidth;
		for (int i = 0; i < imageWidth; i++) {
			int y = yComp[srcIndex] & 0xFF;
			int cb = cbComp[srcIndex] & 0xFF;
			int cr = crComp[srcIndex] & 0xFF;
			int r = y + CrRTable[cr];
			int g = y + ((CbGTable[cb] + CrGTable[cr]) >> 16);
			int b = y + CbBTable[cb];
			if (r < 0) {
				r = 0;
			} else {
				if (r > 255) r = 255;
			}
			if (g < 0) {
				g = 0;
			} else {
				if (g > 255) g = 255;
			}
			if (b < 0) {
				b = 0;
			} else {
				if (b > 255) b = 255;
			}
			rgbData[destIndex] = (byte)b;
			rgbData[destIndex + 1] = (byte)g;
			rgbData[destIndex + 2] = (byte)r;
			destIndex += 3;
			srcIndex++;
		}
	}
	return rgbData;
}
void decodeACCoefficients(int[] dataUnit, int iComp) {
	int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
	JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
	int k = 1;
	while (k < 64) {
		int rs = decodeUsingTable(acTable);
		int r = rs >> 4;
		int s = rs & 0xF;
		if (s == 0) {
			if (r == 15) {
				k += 16;
			} else {
				break;
			}
		} else {
			k += r;
			int bits = receive(s);
			dataUnit[ZigZag8x8[k]] = extendBy(bits, s);
			k++;
		}
	}
}
void decodeACFirstCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit) {
	if (eobrun > 0) {
		eobrun--;
		return;
	}
	int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
	JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
	int k = start;
	while (k <= end) {
		int rs = decodeUsingTable(acTable);
		int r = rs >> 4;
		int s = rs & 0xF;
		if (s == 0) {
			if (r == 15) {
				k += 16;
			} else {
				eobrun = (1 << r) + receive(r) - 1;
				break;
			}
		} else {
			k += r;
			int bits = receive(s);
			dataUnit[ZigZag8x8[k]] = extendBy(bits, s) << approxBit;
			k++;
		}
	}
}
void decodeACRefineCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit) {
	int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
	JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
	int k = start;
	while (k <= end) {
		if (eobrun > 0) {
			while (k <= end) {
				int zzIndex = ZigZag8x8[k];
				if (dataUnit[zzIndex] != 0) {
					dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
				}
				k++;
			}
			eobrun--;
		} else {
			int rs = decodeUsingTable(acTable);
			int r = rs >> 4;
			int s = rs & 0xF;
			if (s == 0) {
				if (r == 15) {
					int zeros = 0;
					while (zeros < 16 && k <= end) {
						int zzIndex = ZigZag8x8[k];
						if (dataUnit[zzIndex] != 0) {
							dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
						} else {
							zeros++;
						}
						k++;
					}
				} else {
					eobrun = (1 << r) + receive(r);
				}
			} else {
				int bit = receive(s);
				int zeros = 0;
				int zzIndex = ZigZag8x8[k];
				while ((zeros < r || dataUnit[zzIndex] != 0) && k <= end) {
					if (dataUnit[zzIndex] != 0) {
						dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
					} else {
						zeros++;
					}
					k++;
					zzIndex = ZigZag8x8[k];
				}
				if (bit != 0) {
					dataUnit[zzIndex] = 1 << approxBit;
				} else {
					dataUnit[zzIndex] = -1 << approxBit;
				}
				k++;
			}
		}
	}
}
int refineAC(int ac, int approxBit) {
	if (ac > 0) {
		int bit = nextBit();
		if (bit != 0) {
			ac += 1 << approxBit;
		}
	} else if (ac < 0) {
		int bit = nextBit();
		if (bit != 0) {
			ac += -1 << approxBit;
		}
	}
	return ac;
}
void decodeDCCoefficient(int[] dataUnit, int iComp, boolean first, int approxBit) {
	int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
	JPEGHuffmanTable dcTable = dcHuffmanTables[sParams[DC]];
	int lastDC = 0;
	if (progressive && !first) {
		int bit = nextBit();
		lastDC = dataUnit[0] + (bit << approxBit);
	} else {
		lastDC = precedingDCs[iComp];
		int nBits = decodeUsingTable(dcTable);
		if (nBits != 0) {
			int bits = receive(nBits);
			int diff = extendBy(bits, nBits);
			lastDC += diff;
			precedingDCs[iComp] = lastDC;
		}
		if (progressive) {
			lastDC = lastDC << approxBit;
		}
	}
	dataUnit[0] = lastDC;
}
void dequantize(int[] dataUnit, int iComp) {
	int[] qTable = quantizationTables[frameComponents[componentIds[iComp]][TQI]];
	for (int i = 0; i < dataUnit.length; i++) {
		int zzIndex = ZigZag8x8[i];
		dataUnit[zzIndex] = dataUnit[zzIndex] * qTable[i];
	}
}
byte[] decodeImageComponents() {
	if (nComponents == 3) { // compIds 1, 2, 3
		return convertYCbCrToRGB();
	}
//	if (nComponents == 3) { // compIds 1, 4, 5
//		Unsupported CMYK format.
//		return convertYIQToRGB();
//	}
	if (nComponents == 4) {
		return convertCMYKToRGB();
	}
	return convertYToRGB();
}
void decodeMCUAtXAndY(int xmcu, int ymcu, int nComponentsInScan, boolean first, int start, int end, int approxBit) {
	for (int iComp = 0; iComp < nComponentsInScan; iComp++) {
		int scanComponent = iComp;
		while (scanHeader.componentParameters[componentIds[scanComponent]] == null) {
			scanComponent++;
		}
		int[] frameComponent = frameComponents[componentIds[scanComponent]];
		int hi = frameComponent[HI];
		int vi = frameComponent[VI];
		if (nComponentsInScan == 1) {
			hi = 1;
			vi = 1;
		}
		int compWidth = frameComponent[CW];
		for (int ivi = 0; ivi < vi; ivi++) {
			for (int ihi = 0; ihi < hi; ihi++) {
				if (progressive) {
					// Progressive: First scan - create a new data unit.
					// Subsequent scans - refine the existing data unit.
					int index = (ymcu * vi + ivi) * compWidth + xmcu * hi + ihi;
					dataUnit = dataUnits[scanComponent][index];
					if (dataUnit == null) {
						dataUnit = new int[64];
						dataUnits[scanComponent][index] = dataUnit;
					}
				} else {
					// Sequential: Clear and reuse the data unit buffer.
					for (int i = 0; i < dataUnit.length; i++) {
						dataUnit[i] = 0;
					}
				}
				if (!progressive || scanHeader.isDCProgressiveScan()) {
					decodeDCCoefficient(dataUnit, scanComponent, first, approxBit);
				}
				if (!progressive) {
					decodeACCoefficients(dataUnit, scanComponent);
				} else {
					if (scanHeader.isACProgressiveScan()) {
						if (first) {
							decodeACFirstCoefficients(dataUnit, scanComponent, start, end, approxBit);
						} else {
							decodeACRefineCoefficients(dataUnit, scanComponent, start, end, approxBit);
						}
					}
					if (loader.hasListeners()) {
						// Dequantization, IDCT, up-sampling and color conversion
						// are done on a copy of the coefficient data in order to
						// display the image incrementally.
						int[] temp = dataUnit;
						dataUnit = new int[64];
						System.arraycopy(temp, 0, dataUnit, 0, 64);
					}
				}
				if (!progressive || (progressive && loader.hasListeners())) {
					dequantize(dataUnit, scanComponent);
					inverseDCT(dataUnit);
					storeData(dataUnit, scanComponent, xmcu, ymcu, hi, ihi, vi, ivi);
				}
			}
		}
	}
}
void decodeScan() {
	if (progressive && !scanHeader.verifyProgressiveScan()) {
		SWT.error(SWT.ERROR_INVALID_IMAGE);
	}
	int nComponentsInScan = scanHeader.getNumberOfImageComponents();
	int mcuRowsInScan = interleavedMcuRows;
	int mcusPerRow = interleavedMcuCols;
	if (nComponentsInScan == 1) {
		// Non-interleaved.
		int scanComponent = 0;
		while (scanHeader.componentParameters[componentIds[scanComponent]] == null) {
			scanComponent++;
		}
		int[] frameComponent = frameComponents[componentIds[scanComponent]];
		int hi = frameComponent[HI];
		int vi = frameComponent[VI];
		int mcuWidth = DCTSIZE * maxH / hi;
		int mcuHeight = DCTSIZE * maxV / vi;
		mcusPerRow = (imageWidth + mcuWidth - 1) / mcuWidth;
		mcuRowsInScan = (imageHeight + mcuHeight - 1) / mcuHeight;
	}
	boolean first = scanHeader.isFirstScan();
	int start = scanHeader.getStartOfSpectralSelection();
	int end = scanHeader.getEndOfSpectralSelection();
	int approxBit = scanHeader.getApproxBitPositionLow();
	restartsToGo = restartInterval;
	nextRestartNumber = 0;
	for (int ymcu = 0; ymcu < mcuRowsInScan; ymcu++) {
		for (int xmcu = 0; xmcu < mcusPerRow; xmcu++) {
			if (restartInterval != 0) {
				if (restartsToGo == 0) processRestartInterval();
				restartsToGo--;
			}
			decodeMCUAtXAndY(xmcu, ymcu, nComponentsInScan, first, start, end, approxBit);
		}
	}
}
int decodeUsingTable(JPEGHuffmanTable huffmanTable) {
	int i = 0;
	int[] maxCodes = huffmanTable.getDhMaxCodes();
	int[] minCodes = huffmanTable.getDhMinCodes();
	int[] valPtrs = huffmanTable.getDhValPtrs();
	int[] huffVals = huffmanTable.getDhValues();
	int code = nextBit();
	while (code > maxCodes[i]) {
		code = code * 2 + nextBit();
		i++;
	}
	int j = valPtrs[i] + code - minCodes[i];
	return huffVals[j];
}
void emit(int huffCode, int nBits) {
	if (nBits == 0) {
		SWT.error(SWT.ERROR_INVALID_IMAGE);
	}
	int[] power2m1 = new int[] {
		1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 
		16383, 32767, 65535, 131125
	};
	int code = (huffCode & power2m1[nBits - 1]) << (24 - nBits - currentBitCount);
	byte[] codeBuffer = new byte[4];
	codeBuffer[0] = (byte)(code & 0xFF);
	codeBuffer[1] = (byte)((code >> 8) & 0xFF);
	codeBuffer[2] = (byte)((code >> 16) & 0xFF);
	codeBuffer[3] = (byte)((code >> 24) & 0xFF);
	int abs = nBits - (8 - currentBitCount);
	if (abs < 0) abs = -abs;
	if ((abs >> 3) > 0) {
		currentByte += codeBuffer[2];
		emitByte((byte)currentByte);
		emitByte(codeBuffer[1]);
		currentByte = codeBuffer[0];
		currentBitCount += nBits - 16;
	} else {
		currentBitCount += nBits;
		if (currentBitCount >= 8) {
			currentByte += codeBuffer[2];
			emitByte((byte)currentByte);
			currentByte = codeBuffer[1];
			currentBitCount -= 8;
		} else {
			currentByte += codeBuffer[2];
		}
	}
}
void emitByte(byte byteValue) {
	if (bufferCurrentPosition >= 512) {
		resetOutputBuffer();
	}
	dataBuffer[bufferCurrentPosition] = byteValue;
	bufferCurrentPosition++;
	if (byteValue == -1) {
		emitByte((byte)0);
	}
}
void encodeACCoefficients(int[] dataUnit, int iComp) {
	int[] sParams = scanHeader.componentParameters[iComp];
	JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
	int[] ehCodes = acTable.ehCodes;
	byte[] ehSizes = acTable.ehCodeLengths;
	int r = 0;
	int k = 1;
	while (k < 64) {
		k++;
		int acValue = dataUnit[ZigZag8x8[k - 1]];
		if (acValue == 0) {
			if (k == 64) {
				emit(ehCodes[0], ehSizes[0] & 0xFF);
			} else {
				r++;
			}
		} else {
			while (r > 15) {
				emit(ehCodes[0xF0], ehSizes[0xF0] & 0xFF);
				r -= 16;
			}
			if (acValue < 0) {
				int absACValue = acValue;
				if (absACValue < 0) absACValue = -absACValue;
				int nBits = NBitsTable[absACValue];
				int rs = r * 16 + nBits;
				emit(ehCodes[rs], ehSizes[rs] & 0xFF);
				emit(0xFFFFFF - absACValue, nBits);
			} else {
				int nBits = NBitsTable[acValue];
				int rs = r * 16 + nBits;
				emit(ehCodes[rs], ehSizes[rs] & 0xFF);
				emit(acValue, nBits);
			}
			r = 0;
		}
	}
}
void encodeDCCoefficients(int[] dataUnit, int iComp) {
	int[] sParams = scanHeader.componentParameters[iComp];
	JPEGHuffmanTable dcTable = dcHuffmanTables[sParams[DC]];
	int lastDC = precedingDCs[iComp];
	int dcValue = dataUnit[0];
	int diff = dcValue - lastDC;
	precedingDCs[iComp] = dcValue;
	if (diff < 0) {
		int absDiff = 0 - diff;
		int nBits = NBitsTable[absDiff];
		emit(dcTable.ehCodes[nBits], dcTable.ehCodeLengths[nBits]);
		emit(0xFFFFFF - absDiff, nBits);
	} else {
		int nBits = NBitsTable[diff];
		emit(dcTable.ehCodes[nBits], dcTable.ehCodeLengths[nBits]);
		if (nBits != 0) {
			emit(diff, nBits);
		}
	}
}
void encodeMCUAtXAndY(int xmcu, int ymcu) {
	int nComponentsInScan = scanHeader.getNumberOfImageComponents();
	dataUnit = new int[64];
	for (int iComp = 0; iComp < nComponentsInScan; iComp++) {
		int[] frameComponent = frameComponents[componentIds[iComp]];
		int hi = frameComponent[HI];
		int vi = frameComponent[VI];
		for (int ivi = 0; ivi < vi; ivi++) {
			for (int ihi = 0; ihi < hi; ihi++) {
				extractData(dataUnit, iComp, xmcu, ymcu, ihi, ivi);
				forwardDCT(dataUnit);
				quantizeData(dataUnit, iComp);
				encodeDCCoefficients(dataUnit, iComp);
				encodeACCoefficients(dataUnit, iComp);
			}
		}
	}
}
void encodeScan() {
	for (int ymcu = 0; ymcu < interleavedMcuRows; ymcu++) {
		for (int xmcu = 0; xmcu < interleavedMcuCols; xmcu++) {
			encodeMCUAtXAndY(xmcu, ymcu);
		}
	}
	if (currentBitCount != 0) {
		emitByte((byte)currentByte);
	}
	resetOutputBuffer();
}
void expandImageComponents() {
	for (int iComp = 0; iComp < nComponents; iComp++) {
		int[] frameComponent = frameComponents[componentIds[iComp]];
		int hi = frameComponent[HI];
		int vi = frameComponent[VI];
		int upH = maxH / hi;
		int upV = maxV / vi;
		if ((upH * upV) > 1) {
			byte[] component = imageComponents[iComp];
			int compWidth = frameComponent[CW];
			int compHeight = frameComponent[CH];
			int upCompWidth = compWidth * upH;
			int upCompHeight = compHeight * upV;
			ImageData src = new ImageData(compWidth, compHeight, 8, new PaletteData(RGB16), 4, component);
			ImageData dest = src.scaledTo(upCompWidth, upCompHeight);
			imageComponents[iComp] = dest.data;
		}
	}
}
int extendBy(int diff, int t) {
	if (diff < ExtendTest[t]) {
		return diff + ExtendOffset[t];
	} else {
		return diff;
	}
}
void extractData(int[] dataUnit, int iComp, int xmcu, int ymcu, int ihi, int ivi) {
	byte[] compImage = imageComponents[iComp];
	int[] frameComponent = frameComponents[componentIds[iComp]];
	int hi = frameComponent[HI];
	int vi = frameComponent[VI];
	int compWidth = frameComponent[CW];
	int srcIndex = ((ymcu * vi + ivi) * compWidth * DCTSIZE) + ((xmcu * hi + ihi) * DCTSIZE);
	int destIndex = 0;
	for (int i = 0; i < DCTSIZE; i++) {
		for (int col = 0; col < DCTSIZE; col++) {
			dataUnit[destIndex] = (compImage[srcIndex + col] & 0xFF) - 128;
			destIndex++;
		}
		srcIndex += compWidth;
	}
}
void forwardDCT(int[] dataUnit) {
	for (int row = 0; row < 8; row++) {
		int rIndex = row * DCTSIZE;
		int tmp0 = dataUnit[rIndex] + dataUnit[rIndex + 7];
		int tmp7 = dataUnit[rIndex] - dataUnit[rIndex + 7];
		int tmp1 = dataUnit[rIndex + 1] + dataUnit[rIndex + 6];
		int tmp6 = dataUnit[rIndex + 1] - dataUnit[rIndex + 6];
		int tmp2 = dataUnit[rIndex + 2] + dataUnit[rIndex + 5];
		int tmp5 = dataUnit[rIndex + 2] - dataUnit[rIndex + 5];
		int tmp3 = dataUnit[rIndex + 3] + dataUnit[rIndex + 4];
		int tmp4 = dataUnit[rIndex + 3] - dataUnit[rIndex + 4];

		/**
		 * Even part per LL&M figure 1 --- note that published figure 
		 * is faulty; rotator 'sqrt(2)*c1' should be 'sqrt(2)*c6'.
		 */
		int tmp10 = tmp0 + tmp3;
		int tmp13 = tmp0 - tmp3;
		int tmp11 = tmp1 + tmp2;
		int tmp12 = tmp1 - tmp2;

		dataUnit[rIndex] = (tmp10 + tmp11) * 4;
		dataUnit[rIndex + 4]  = (tmp10 - tmp11) * 4;

		int z1 = (tmp12 + tmp13) * FIX_0_541196100;
		int n = z1 + (tmp13 * FIX_0_765366865) + 1024;
		dataUnit[rIndex + 2] = n >> 11;
		if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 2]--;
		n = z1 + (tmp12 * (0 - FIX_1_847759065)) + 1024;
 		dataUnit[rIndex + 6] = n >> 11;
		if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 6]--;

		/**
		 * Odd part per figure 8 --- note paper omits factor of sqrt(2).
		 * cK represents cos(K*pi/16).
		 * i0..i3 in the paper are tmp4..tmp7 here.
		 */
		z1 = tmp4 + tmp7;
		int z2 = tmp5 + tmp6;
		int z3 = tmp4 + tmp6;
		int z4 = tmp5 + tmp7;
		int z5 = (z3 + z4) * FIX_1_175875602;	// sqrt(2) * c3

		tmp4 *= FIX_0_298631336;	// sqrt(2) * (-c1+c3+c5-c7)
		tmp5 *= FIX_2_053119869;	// sqrt(2) * ( c1+c3-c5+c7)
		tmp6 *= FIX_3_072711026;	// sqrt(2) * ( c1+c3+c5-c7)
		tmp7 *= FIX_1_501321110;	// sqrt(2) * ( c1+c3-c5-c7)
		z1 *= 0 - FIX_0_899976223;	// sqrt(2) * (c7-c3)
		z2 *= 0 - FIX_2_562915447;	// sqrt(2) * (-c1-c3)
		z3 *= 0 - FIX_1_961570560;	// sqrt(2) * (-c3-c5)
		z4 *= 0 - FIX_0_390180644;	// sqrt(2) * (c5-c3)

		z3 += z5;
		z4 += z5;

		n = tmp4 + z1 + z3 + 1024;
		dataUnit[rIndex + 7] = n >> 11;
		if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 7]--;
		n = tmp5 + z2 + z4 + 1024;
		dataUnit[rIndex + 5] = n >> 11;
		if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 5]--;
		n = tmp6 + z2 + z3 + 1024;
		dataUnit[rIndex + 3] = n >> 11;
		if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 3]--;
		n = tmp7 + z1 + z4 + 1024;
		dataUnit[rIndex + 1] = n >> 11;
		if ((n < 0) && ((n & 0x07FF) != 0)) dataUnit[rIndex + 1]--;
	}

	/**
	 * Pass 2: process columns.
	 * Note that we must descale the results by a factor of 8 == 2**3,
	 * and also undo the PASS1_BITS scaling.
	 */
	for (int col = 0; col < 8; col++) {
		int c0 = col;
		int c1 = col + 8;
		int c2 = col + 16;
		int c3 = col + 24;
		int c4 = col + 32;
		int c5 = col + 40;
		int c6 = col + 48;
		int c7 = col + 56;
		int tmp0 = dataUnit[c0] + dataUnit[c7];
		int tmp7 = dataUnit[c0] - dataUnit[c7];
		int tmp1 = dataUnit[c1] + dataUnit[c6];
		int tmp6 = dataUnit[c1] - dataUnit[c6];
		int tmp2 = dataUnit[c2] + dataUnit[c5];
		int tmp5 = dataUnit[c2] - dataUnit[c5];
		int tmp3 = dataUnit[c3] + dataUnit[c4];
		int tmp4 = dataUnit[c3] - dataUnit[c4];

		/**
		 * Even part per LL&M figure 1 --- note that published figure 
		 * is faulty; rotator 'sqrt(2)*c1' should be 'sqrt(2)*c6'.
		 */
		int tmp10 = tmp0 + tmp3;
		int tmp13 = tmp0 - tmp3;
		int tmp11 = tmp1 + tmp2;
		int tmp12 = tmp1 - tmp2;

		int n = tmp10 + tmp11 + 16;
		dataUnit[c0] = n >> 5;
		if ((n < 0) && ((n & 0x1F) != 0)) dataUnit[c0]--;
		n = tmp10 - tmp11 + 16;
		dataUnit[c4] = n >> 5;
		if ((n < 0) && ((n & 0x1F) != 0)) dataUnit[c4]--;

		int z1 = (tmp12 + tmp13) * FIX_0_541196100;
		n = z1 + (tmp13 * FIX_0_765366865) + 131072;
		dataUnit[c2] = n >> 18;
		if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c2]--;
		n = z1 + (tmp12 * (0 - FIX_1_847759065)) + 131072;
		dataUnit[c6] = n >> 18;
		if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c6]--;

		/**
		 * Odd part per figure 8 --- note paper omits factor of sqrt(2).
		 * cK represents cos(K*pi/16).
		 * i0..i3 in the paper are tmp4..tmp7 here.
		 */
		z1 = tmp4 + tmp7;
		int z2 = tmp5 + tmp6;
		int z3 = tmp4 + tmp6;
		int z4 = tmp5 + tmp7;
		int z5 = (z3 + z4) * FIX_1_175875602;	// sqrt(2) * c3

		tmp4 *= FIX_0_298631336;	// sqrt(2) * (-c1+c3+c5-c7)
		tmp5 *= FIX_2_053119869;	// sqrt(2) * ( c1+c3-c5+c7)
		tmp6 *= FIX_3_072711026;	// sqrt(2) * ( c1+c3+c5-c7)
		tmp7 *= FIX_1_501321110;	// sqrt(2) * ( c1+c3-c5-c7)
		z1 *= 0 - FIX_0_899976223;	// sqrt(2) * (c7-c3)
		z2 *= 0 - FIX_2_562915447;	// sqrt(2) * (-c1-c3)
		z3 *= 0 - FIX_1_961570560;	// sqrt(2) * (-c3-c5)
		z4 *= 0 - FIX_0_390180644;	// sqrt(2) * (c5-c3)

		z3 += z5;
		z4 += z5;

		n = tmp4 + z1 + z3 + 131072;
		dataUnit[c7] = n >> 18;
		if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c7]--;
		n = tmp5 + z2 + z4 + 131072;
		dataUnit[c5] = n >> 18;
		if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c5]--;
		n = tmp6 + z2 + z3 + 131072;
		dataUnit[c3] = n >> 18;
		if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c3]--;
		n = tmp7 + z1 + z4 + 131072;
		dataUnit[c1] = n >> 18;
		if ((n < 0) && ((n & 0x3FFFF) != 0)) dataUnit[c1]--;
	}
}
void getAPP0() {
	JPEGAppn appn = new JPEGAppn(inputStream);
	if (!appn.verify()) {
		SWT.error(SWT.ERROR_INVALID_IMAGE);
	}
}
void getCOM() {
	new JPEGComment(inputStream);
}
void getDAC() {
	new JPEGArithmeticConditioningTable(inputStream);
}
void getDHT() {
	JPEGHuffmanTable dht = new JPEGHuffmanTable(inputStream);
	if (!dht.verify()) {
		SWT.error(SWT.ERROR_INVALID_IMAGE);
	}
	if (acHuffmanTables == null) {
		acHuffmanTables = new JPEGHuffmanTable[4];
	}
	if (dcHuffmanTables == null) {
		dcHuffmanTables = new JPEGHuffmanTable[4];
	}
	JPEGHuffmanTable[] dhtTables = dht.getAllTables();
	for (int i = 0; i < dhtTables.length; i++) {
		JPEGHuffmanTable dhtTable = dhtTables[i];
		if (dhtTable.getTableClass() == 0) {
			dcHuffmanTables[dhtTable.getTableIdentifier()] = dhtTable;
		} else {
			acHuffmanTables[dhtTable.getTableIdentifier()] = dhtTable;
		}
	}
}
void getDNL() {
	new JPEGRestartInterval(inputStream);
}
void getDQT() {
	JPEGQuantizationTable dqt = new JPEGQuantizationTable(inputStream);
	int[][] currentTables = quantizationTables;
	if (currentTables == null) {
		currentTables = new int[4][];
	}
	int[] dqtTablesKeys = dqt.getQuantizationTablesKeys();
	int[][] dqtTablesValues = dqt.getQuantizationTablesValues();
	for (int i = 0; i < dqtTablesKeys.length; i++) {
		int index = dqtTablesKeys[i];
		currentTables[index] = dqtTablesValues[i];
	}
	quantizationTables = currentTables;
}
void getDRI() {
	JPEGRestartInterval dri = new JPEGRestartInterval(inputStream);
	if (!dri.verify()) {
		SWT.error(SWT.ERROR_INVALID_IMAGE);
	}
	restartInterval = dri.getRestartInterval();
}
static void initialize() {
	initializeRGBYCbCrTables();
	initializeYCbCrRGBTables();
	initializeBitCountTable();
}
static void initializeBitCountTable() {
	int nBits = 1;
	int power2 = 2;
	NBitsTable = new int[2048];
	NBitsTable[0] = 0;
	for (int i = 1; i < NBitsTable.length; i++) {
		if (!(i < power2)) {
			nBits++;
			power2 *= 2;
		}
		NBitsTable[i] = nBits;
	}
}
static void initializeRGBYCbCrTables() {
	RYTable = new int[256];
	GYTable = new int[256];
	BYTable = new int[256];
	RCbTable = new int[256];
	GCbTable = new int[256];
	BCbTable = new int[256];
	RCrTable = BCbTable;
	GCrTable = new int[256];
	BCrTable = new int[256];
	for (int i = 0; i < 256; i++) {
		RYTable[i] = i * 19595;
		GYTable[i] = i * 38470;
		BYTable[i] = i * 7471 + 32768;
		RCbTable[i] = i * -11059;
		GCbTable[i] = i * -21709;
		BCbTable[i] = i * 32768 + 8388608;
		GCrTable[i] = i * -27439;
		BCrTable[i] = i * -5329;
	}
}
static void initializeYCbCrRGBTables() {
	CrRTable = new int[256];
	CbBTable = new int[256];
	CrGTable = new int[256];
	CbGTable = new int[256];
	for (int i = 0; i < 256; i++) {
		int x2 = 2 * i - 255;
		CrRTable[i] = (45941 * x2 + 32768) >> 16;
		CbBTable[i] = (58065 * x2 + 32768) >> 16;
		CrGTable[i] = -23401 * x2;
		CbGTable[i] = -11277 * x2 + 32768;
	}
}
void inverseDCT(int[] dataUnit) {
	for (int row = 0; row < 8; row++) {
		int rIndex = row * DCTSIZE;
		/**
		 * Due to quantization, we will usually find that many of the input
		 * coefficients are zero, especially the AC terms.  We can exploit this
		 * by short-circuiting the IDCT calculation for any row in which all
		 * the AC terms are zero.  In that case each output is equal to the
		 * DC coefficient (with scale factor as needed).
		 * With typical images and quantization tables, half or more of the
		 * row DCT calculations can be simplified this way.
		 */
		if (isZeroInRow(dataUnit, rIndex)) {
			int dcVal = dataUnit[rIndex] << 2;
			for (int i = rIndex + 7; i >= rIndex; i--) {
				dataUnit[i] = dcVal;
			}
		} else {
			/**
			 * Even part: reverse the even part of the forward DCT.
			 * The rotator is sqrt(2)*c(-6).
			 */
			int z2 = dataUnit[rIndex + 2];
			int z3 = dataUnit[rIndex + 6];
			int z1 = (z2 + z3) * FIX_0_541196100;
			int tmp2 = z1 + (z3 * (0 - FIX_1_847759065));
			int tmp3 = z1 + (z2 * FIX_0_765366865);
			int tmp0 = (dataUnit[rIndex] + dataUnit[rIndex + 4]) << 13;
			int tmp1 = (dataUnit[rIndex] - dataUnit[rIndex + 4]) << 13;
			int tmp10 = tmp0 + tmp3;
			int tmp13 = tmp0 - tmp3;
			int tmp11 = tmp1 + tmp2;
			int tmp12 = tmp1 - tmp2;
			/**
			 * Odd part per figure 8; the matrix is unitary and hence its
			 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
			 */
			tmp0 = dataUnit[rIndex + 7];
			tmp1 = dataUnit[rIndex + 5];
			tmp2 = dataUnit[rIndex + 3];
			tmp3 = dataUnit[rIndex + 1];
			z1 = tmp0 + tmp3;
			z2 = tmp1 + tmp2;
			z3 = tmp0 + tmp2;
			int z4 = tmp1 + tmp3;
			int z5 = (z3 + z4) * FIX_1_175875602; /* sqrt(2) * c3 */
			  
			tmp0 *= FIX_0_298631336;		/* sqrt(2) * (-c1+c3+c5-c7) */
			tmp1 *= FIX_2_053119869;		/* sqrt(2) * ( c1+c3-c5+c7) */
			tmp2 *= FIX_3_072711026;		/* sqrt(2) * ( c1+c3+c5-c7) */
			tmp3 *= FIX_1_501321110;		/* sqrt(2) * ( c1+c3-c5-c7) */
			z1 *= 0 - FIX_0_899976223;	/* sqrt(2) * (c7-c3) */
			z2 *= 0 - FIX_2_562915447;	/* sqrt(2) * (-c1-c3) */
			z3 *= 0 - FIX_1_961570560;	/* sqrt(2) * (-c3-c5) */
			z4 *= 0 - FIX_0_390180644;	/* sqrt(2) * (c5-c3) */

			z3 += z5;
			z4 += z5;
			tmp0 += z1 + z3;
			tmp1 += z2 + z4;
			tmp2 += z2 + z3;
			tmp3 += z1 + z4;

			dataUnit[rIndex] = (tmp10 + tmp3 + 1024) >> 11;
			dataUnit[rIndex + 7] = (tmp10 - tmp3 + 1024) >> 11;
			dataUnit[rIndex + 1] = (tmp11 + tmp2 + 1024) >> 11;
			dataUnit[rIndex + 6] = (tmp11 - tmp2 + 1024) >> 11;
			dataUnit[rIndex + 2] = (tmp12 + tmp1 + 1024) >> 11;
			dataUnit[rIndex + 5] = (tmp12 - tmp1 + 1024) >> 11;
			dataUnit[rIndex + 3] = (tmp13 + tmp0 + 1024) >> 11;
			dataUnit[rIndex + 4] = (tmp13 - tmp0 + 1024) >> 11;
		 }
	}
	/**
	 * Pass 2: process columns.
	 * Note that we must descale the results by a factor of 8 == 2**3,
	 * and also undo the PASS1_BITS scaling.
	 */
	for (int col = 0; col < 8; col++) {
		int c0 = col;
		int c1 = col + 8;
		int c2 = col + 16;
		int c3 = col + 24;
		int c4 = col + 32;
		int c5 = col + 40;
		int c6 = col + 48;
		int c7 = col + 56;
		if (isZeroInColumn(dataUnit, col)) {
			int dcVal = (dataUnit[c0] + 16) >> 5;
			dataUnit[c0] = dcVal;
			dataUnit[c1] = dcVal;
			dataUnit[c2] = dcVal;
			dataUnit[c3] = dcVal;
			dataUnit[c4] = dcVal;
			dataUnit[c5] = dcVal;
			dataUnit[c6] = dcVal;
			dataUnit[c7] = dcVal;
		} else {
			/**
			 * Even part: reverse the even part of the forward DCT.
			 * The rotator is sqrt(2)*c(-6).
			 */
			int z0 = dataUnit[c0];
			int z2 = dataUnit[c2];
			int z3 = dataUnit[c6];
			int z4 = dataUnit[c4];
			int z1 = (z2 + z3) * FIX_0_541196100;
			int tmp2 = z1 + (z3 * (0 - FIX_1_847759065));
			int tmp3 = z1 + (z2 * FIX_0_765366865);
			int tmp0 = (z0 + z4) << 13;
			int tmp1 = (z0 - z4) << 13;
			int tmp10 = tmp0 + tmp3;
			int tmp13 = tmp0 - tmp3;
			int tmp11 = tmp1 + tmp2;
			int tmp12 = tmp1 - tmp2;
			/**
			 * Odd part per figure 8; the matrix is unitary and hence its
			 * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
			 */
			tmp0 = dataUnit[c7];
			tmp1 = dataUnit[c5];
			tmp2 = dataUnit[c3];
			tmp3 = dataUnit[c1];
			z1 = tmp0 + tmp3;
			z2 = tmp1 + tmp2;
			z3 = tmp0 + tmp2;
			z4 = tmp1 + tmp3;
			z0 = (z3 + z4) * FIX_1_175875602;	/* sqrt(2) * c3 */
			
			tmp0 *= FIX_0_298631336;		/* sqrt(2) * (-c1+c3+c5-c7) */
			tmp1 *= FIX_2_053119869;		/* sqrt(2) * ( c1+c3-c5+c7) */
			tmp2 *= FIX_3_072711026;		/* sqrt(2) * ( c1+c3+c5-c7) */
			tmp3 *= FIX_1_501321110;		/* sqrt(2) * ( c1+c3-c5-c7) */
			z1 *= 0 - FIX_0_899976223;	/* sqrt(2) * (c7-c3) */
			z2 *= 0 - FIX_2_562915447;	/* sqrt(2) * (-c1-c3) */
			z3 *= 0 - FIX_1_961570560;	/* sqrt(2) * (-c3-c5) */
			z4 *= 0 - FIX_0_390180644;	/* sqrt(2) * (c5-c3) */
			
			z3 += z0;
			z4 += z0;
			
			tmp0 += z1 + z3;
			tmp1 += z2 + z4;
			tmp2 += z2 + z3;
			tmp3 += z1 + z4;

			/* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
			dataUnit[c0] = (tmp10 + tmp3 + 131072) >> 18;
			dataUnit[c7] = (tmp10 - tmp3 + 131072) >> 18;
			dataUnit[c1] = (tmp11 + tmp2 + 131072) >> 18;
			dataUnit[c6] = (tmp11 - tmp2 + 131072) >> 18;
			dataUnit[c2] = (tmp12 + tmp1 + 131072) >> 18;
			dataUnit[c5] = (tmp12 - tmp1 + 131072) >> 18;
			dataUnit[c3] = (tmp13 + tmp0 + 131072) >> 18;
			dataUnit[c4] = (tmp13 - tmp0 + 131072) >> 18;
		}
	}
}
boolean isFileFormat(LEDataInputStream stream) {
	try {
		JPEGStartOfImage soi = new JPEGStartOfImage(stream);
		stream.unread(soi.reference);
		return soi.verify();  // we no longer check for appN
	} catch (Exception e) {
		return false;
	}
}
boolean isZeroInColumn(int[] dataUnit, int col) {
	return dataUnit[col + 8] == 0 && dataUnit[col + 16] == 0
			&& dataUnit[col + 24] == 0 && dataUnit[col + 32] == 0
			&& dataUnit[col + 40] == 0 && dataUnit[col + 48] == 0
			&& dataUnit[col + 56] == 0;
}
boolean isZeroInRow(int[] dataUnit, int rIndex) {
	return dataUnit[rIndex + 1] == 0 && dataUnit[rIndex + 2] == 0
			&& dataUnit[rIndex + 3] == 0 && dataUnit[rIndex + 4] == 0
			&& dataUnit[rIndex + 5] == 0 && dataUnit[rIndex + 6] == 0
			&& dataUnit[rIndex + 7] == 0;
}
ImageData[] loadFromByteStream() {
	JPEGStartOfImage soi = new JPEGStartOfImage(inputStream);
	if (!soi.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
	restartInterval = 0;

	/* Process the tables preceding the frame header. */
	processTables();
	
	/* Start of Frame. */
	frameHeader = new JPEGFrameHeader(inputStream);
	if (!frameHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
	imageWidth = frameHeader.getSamplesPerLine();
	imageHeight = frameHeader.getNumberOfLines();
	maxH = frameHeader.getMaxHFactor();
	maxV = frameHeader.getMaxVFactor();
	int mcuWidth = maxH * DCTSIZE;
	int mcuHeight = maxV * DCTSIZE;
	interleavedMcuCols = (imageWidth + mcuWidth - 1) / mcuWidth;
	interleavedMcuRows = (imageHeight + mcuHeight - 1) / mcuHeight;
	progressive = frameHeader.isProgressive();
	samplePrecision = frameHeader.getSamplePrecision();
	nComponents = frameHeader.getNumberOfImageComponents();
	frameComponents = frameHeader.componentParameters;
	componentIds = frameHeader.componentIdentifiers;
	imageComponents = new byte[nComponents][];
	if (progressive) {
		// Progressive jpeg: need to keep all of the data units.
		dataUnits = new int[nComponents][][];
	} else {
		// Sequential jpeg: only need one data unit.
		dataUnit = new int[8 * 8];
	}
	for (int i = 0; i < nComponents; i++) {
		int[] frameComponent = frameComponents[componentIds[i]];
		int bufferSize = frameComponent[CW] * frameComponent[CH];
		imageComponents[i] = new byte[bufferSize];
		if (progressive) {
			dataUnits[i] = new int[bufferSize][];
		}
	}

	/* Process the tables preceding the scan header. */
	processTables();
	
	/* Start of Scan. */
	scanHeader = new JPEGScanHeader(inputStream);
	if (!scanHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
	
	/* Process scan(s) and further tables until EOI. */
	int progressiveScanCount = 0;
	boolean done = false;
	while(!done) {
		resetInputBuffer();
		precedingDCs = new int[4];
		decodeScan();
		if (progressive && loader.hasListeners()) {
			ImageData imageData = createImageData();
			loader.notifyListeners(new ImageLoaderEvent(loader, imageData, progressiveScanCount, false));
			progressiveScanCount++;
		}

		/* Unread any buffered data before looking for tables again. */
		int delta = 512 - bufferCurrentPosition - 1;
		if (delta > 0) {
			byte[] unreadBuffer = new byte[delta];
			System.arraycopy(dataBuffer, bufferCurrentPosition + 1, unreadBuffer, 0, delta);
			try {
				inputStream.unread(unreadBuffer);
			} catch (IOException e) {
				SWT.error(SWT.ERROR_IO, e);
			}
		}
		
		/* Process the tables preceding the next scan header. */
		JPEGSegment jpegSegment = processTables();
		if (jpegSegment == null || jpegSegment.getSegmentMarker() == EOI) {
			done = true;
		} else {
			scanHeader = new JPEGScanHeader(inputStream);
			if (!scanHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
		}
	}
	
	if (progressive) {
		for (int ymcu = 0; ymcu < interleavedMcuRows; ymcu++) {
			for (int xmcu = 0; xmcu < interleavedMcuCols; xmcu++) {
				for (int iComp = 0; iComp < nComponents; iComp++) {
					int[] frameComponent = frameComponents[componentIds[iComp]];
					int hi = frameComponent[HI];
					int vi = frameComponent[VI];
					int compWidth = frameComponent[CW];
					for (int ivi = 0; ivi < vi; ivi++) {
						for (int ihi = 0; ihi < hi; ihi++) {
							int index = (ymcu * vi + ivi) * compWidth + xmcu * hi + ihi;
							dataUnit = dataUnits[iComp][index];
							dequantize(dataUnit, iComp);
							inverseDCT(dataUnit);
							storeData(dataUnit, iComp, xmcu, ymcu, hi, ihi, vi, ivi);
						}
					}
				}
			}
		}
	}
	ImageData imageData = createImageData();
	if (progressive && loader.hasListeners()) {
		loader.notifyListeners(new ImageLoaderEvent(loader, imageData, progressiveScanCount, true));
	}
	return new ImageData[] {imageData};
}
ImageData createImageData() {
	return ImageData.internal_new(
		imageWidth,
		imageHeight, 
		nComponents * samplePrecision,
		setUpPalette(),
		nComponents == 1 ? 4 : 1,
		decodeImageComponents(),
		0,
		null,
		null,
		-1,
		-1,
		SWT.IMAGE_JPEG,
		0,
		0,
		0,
		0);
}
int nextBit() {
	if (currentBitCount != 0) {
		currentBitCount--;
		currentByte *= 2;
		if (currentByte > 255) {
			currentByte -= 256;
			return 1;
		} else {
			return 0;
		}
	}
	bufferCurrentPosition++;
	if (bufferCurrentPosition >= 512) {
		resetInputBuffer();
		bufferCurrentPosition = 0;
	}
	currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
	currentBitCount = 8;
	byte nextByte;
	if (bufferCurrentPosition == 511) {
		resetInputBuffer();
		currentBitCount = 8;
		nextByte = dataBuffer[0];
	} else {
		nextByte = dataBuffer[bufferCurrentPosition + 1];
	}
	if (currentByte == 0xFF) {
		if (nextByte == 0) {
			bufferCurrentPosition ++;
			currentBitCount--;
			currentByte *= 2;
			if (currentByte > 255) {
				currentByte -= 256;
				return 1;
			} else {
				return 0;
			}
		} else {
			if ((nextByte & 0xFF) + 0xFF00 == DNL) {
				getDNL();
				return 0;
			} else {
				SWT.error(SWT.ERROR_INVALID_IMAGE);
				return 0;
			}
		}
	} else {
		currentBitCount--;
		currentByte *= 2;
		if (currentByte > 255) {
			currentByte -= 256;
			return 1;
		} else {
			return 0;
		}
	}
}
void processRestartInterval() {
	do {
		bufferCurrentPosition++;
		if (bufferCurrentPosition > 511) {
			resetInputBuffer();
			bufferCurrentPosition = 0;
		}
		currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
	} while (currentByte != 0xFF);
	while (currentByte == 0xFF) {
		bufferCurrentPosition++;
		if (bufferCurrentPosition > 511) {
			resetInputBuffer();
			bufferCurrentPosition = 0;
		}
		currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
	}
	if (currentByte != ((RST0 + nextRestartNumber) & 0xFF)) {
		SWT.error(SWT.ERROR_INVALID_IMAGE);
	}
	bufferCurrentPosition++;
	if (bufferCurrentPosition > 511) {
		resetInputBuffer();
		bufferCurrentPosition = 0;
	}
	currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
	currentBitCount = 8;
	restartsToGo = restartInterval;
	nextRestartNumber = (nextRestartNumber + 1) & 0x7;
	precedingDCs = new int[4];
	eobrun = 0;
}
/* Process all markers until a frame header, scan header, or EOI is found. */
JPEGSegment processTables() {
	while (true) {
		JPEGSegment jpegSegment = seekUnspecifiedMarker(inputStream);
		if (jpegSegment == null) return null;
		JPEGFrameHeader sof = new JPEGFrameHeader(jpegSegment.reference);
		if (sof.verify()) {
			return jpegSegment;
		}
		int marker = jpegSegment.getSegmentMarker();
		switch (marker) {
			case SOI: // there should only be one SOI per file
				SWT.error(SWT.ERROR_INVALID_IMAGE);
			case EOI:
			case SOS:
				return jpegSegment;
			case DQT:
				getDQT();
				break;
			case DHT:
				getDHT();
				break;
			case DAC:
				getDAC();
				break;
			case DRI:
				getDRI();
				break;
			case APP0:
				getAPP0();
				break;
			case COM:
				getCOM();
				break;
			default:
				skipSegmentFrom(inputStream);
			
		}
	}
}
void quantizeData(int[] dataUnit, int iComp) {
	int[] qTable = quantizationTables[frameComponents[componentIds[iComp]][TQI]];
	for (int i = 0; i < dataUnit.length; i++) {
		int zzIndex = ZigZag8x8[i];
		int data = dataUnit[zzIndex];
		int absData = data < 0 ? 0 - data : data;
		int qValue = qTable[i];
		int q2 = qValue >> 1;
		absData += q2;
		if (absData < qValue) {
			dataUnit[zzIndex] = 0;
		} else {
			absData /= qValue;
			if (data >= 0) {
				dataUnit[zzIndex] = absData;
			} else {
				dataUnit[zzIndex] = 0 - absData;
			}
		}
	}
}
int receive(int nBits) {
	int v = 0;
	for (int i = 0; i < nBits; i++) {
		v = v * 2 + nextBit();
	}
	return v;
}
void resetInputBuffer() {
	if (dataBuffer == null) {
		dataBuffer = new byte[512];
	}
	try {
		inputStream.read(dataBuffer);
	} catch (IOException e) {
		SWT.error(SWT.ERROR_IO, e);
	}
	currentBitCount = 0;
	bufferCurrentPosition = -1;
}
void resetOutputBuffer() {
	if (dataBuffer == null) {
		dataBuffer = new byte[512];
	} else {
		try {
			outputStream.write(dataBuffer, 0, bufferCurrentPosition);
		} catch (IOException e) {
			SWT.error(SWT.ERROR_IO, e);
		}
	}
	bufferCurrentPosition = 0;
}
static JPEGSegment seekUnspecifiedMarker(LEDataInputStream byteStream) {
	byte[] byteArray = new byte[2];
	try {
		while (true) {
			if (byteStream.read(byteArray, 0, 1) != 1) return null;
			if (byteArray[0] == (byte) 0xFF) {
				if (byteStream.read(byteArray, 1, 1) != 1) return null;
				if (byteArray[1] != (byte) 0xFF && byteArray[1] != 0) {
					byteStream.unread(byteArray);
					return new JPEGSegment(byteArray);
				}
			}
		}
	} catch (IOException e) {
		SWT.error(SWT.ERROR_IO, e);
	}
	return null;
}
PaletteData setUpPalette() {
	if (nComponents == 1) {
		RGB[] entries = new RGB[256];
		for (int i = 0; i < 256; i++) {
			entries[i] = new RGB(i, i, i);
		}
		return new PaletteData(entries);
	}
	return new PaletteData(0xFF, 0xFF00, 0xFF0000);
}
static void skipSegmentFrom(LEDataInputStream byteStream) {
	try {
		byte[] byteArray = new byte[4];
		JPEGSegment jpegSegment = new JPEGSegment(byteArray);
	
		if (byteStream.read(byteArray) != byteArray.length) {
			SWT.error(SWT.ERROR_INVALID_IMAGE);
		}
		if (!(byteArray[0] == -1 && byteArray[1] != 0 && byteArray[1] != -1)) {
			SWT.error(SWT.ERROR_INVALID_IMAGE);
		}
		int delta = jpegSegment.getSegmentLength() - 2;
		byteStream.skip(delta);
	} catch (Exception e) {
		SWT.error(SWT.ERROR_IO, e);
	}
}
void storeData(int[] dataUnit, int iComp, int xmcu, int ymcu, int hi, int ihi, int vi, int ivi) {
	byte[] compImage = imageComponents[iComp];
	int[] frameComponent = frameComponents[componentIds[iComp]];
	int compWidth = frameComponent[CW];
	int destIndex = ((ymcu * vi + ivi) * compWidth * DCTSIZE) + ((xmcu * hi + ihi) * DCTSIZE);
	int srcIndex = 0;
	for (int i = 0; i < DCTSIZE; i++) {
		for (int col = 0; col < DCTSIZE; col++) {
			int x = dataUnit[srcIndex] + 128;
			if (x < 0) {
				x = 0;
			} else {
				if (x > 255) x = 255;
			}
			compImage[destIndex + col] = (byte)x;
			srcIndex++;
		}
		destIndex += compWidth;
	}
}
void unloadIntoByteStream(ImageLoader loader) {
	ImageData image = loader.data[0];
	if (!new JPEGStartOfImage().writeToStream(outputStream)) {
		SWT.error(SWT.ERROR_IO);
	}
	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});
	if (!appn.writeToStream(outputStream)) {
		SWT.error(SWT.ERROR_IO);
	}
	quantizationTables = new int[4][];
	JPEGQuantizationTable chromDQT = JPEGQuantizationTable.defaultChrominanceTable();
	chromDQT.scaleBy(encoderQFactor);
	int[] jpegDQTKeys = chromDQT.getQuantizationTablesKeys();
	int[][] jpegDQTValues = chromDQT.getQuantizationTablesValues();
	for (int i = 0; i < jpegDQTKeys.length; i++) {
		quantizationTables[jpegDQTKeys[i]] = jpegDQTValues[i];
	}
	JPEGQuantizationTable lumDQT = JPEGQuantizationTable.defaultLuminanceTable();
	lumDQT.scaleBy(encoderQFactor);
	jpegDQTKeys = lumDQT.getQuantizationTablesKeys();
	jpegDQTValues = lumDQT.getQuantizationTablesValues();
	for (int i = 0; i < jpegDQTKeys.length; i++) {
		quantizationTables[jpegDQTKeys[i]] = jpegDQTValues[i];
	}
	if (!lumDQT.writeToStream(outputStream)) {
		SWT.error(SWT.ERROR_IO);
	}
	if (!chromDQT.writeToStream(outputStream)) {
		SWT.error(SWT.ERROR_IO);
	}
	int frameLength, scanLength, precision;
	int[][] frameParams, scanParams;
	if (image.depth == 1) {
		frameLength = 11;
		frameParams = new int[1][];
		frameParams[0] = new int[] {1, 1, 1, 0, 0};
		scanParams = new int[1][];
		scanParams[0] = new int[] {0, 0};
		scanLength = 8;
		nComponents = 1;
		precision = 1;
	} else {
		frameLength = 17;
		frameParams = new int[3][];
		frameParams[0] = new int[] {0, 2, 2, 0, 0};
		frameParams[1] = new int[] {1, 1, 1, 0, 0};
		frameParams[2] = new int[] {1, 1, 1, 0, 0};
		scanParams = new int[3][];
		scanParams[0] = new int[] {0, 0};
		scanParams[1] = new int[] {1, 1};
		scanParams[2] = new int[] {1, 1};
		scanLength = 12;
		nComponents = 3;
		precision = 8;
	}
	imageWidth = image.width;
	imageHeight = image.height;
	frameHeader = new JPEGFrameHeader(new byte[19]);
	frameHeader.setSegmentMarker(SOF0);
	frameHeader.setSegmentLength(frameLength);
	frameHeader.setSamplePrecision(precision);
	frameHeader.setSamplesPerLine(imageWidth);
	frameHeader.setNumberOfLines(imageHeight);
	frameHeader.setNumberOfImageComponents(nComponents);
	frameHeader.componentParameters = frameParams;
	frameHeader.componentIdentifiers = new int[] {0, 1, 2};
	frameHeader.initializeContents();
	if (!frameHeader.writeToStream(outputStream)) {
		SWT.error(SWT.ERROR_IO);
	}
	frameComponents = frameParams;
	componentIds = frameHeader.componentIdentifiers;
	maxH = frameHeader.getMaxHFactor();
	maxV = frameHeader.getMaxVFactor();
	int mcuWidth = maxH * DCTSIZE;
	int mcuHeight = maxV * DCTSIZE;
	interleavedMcuCols = (imageWidth + mcuWidth - 1) / mcuWidth;
	interleavedMcuRows = (imageHeight + mcuHeight - 1) / mcuHeight;
	acHuffmanTables = new JPEGHuffmanTable[4];
	dcHuffmanTables = new JPEGHuffmanTable[4];
	JPEGHuffmanTable[] dhtTables = new JPEGHuffmanTable[] {
		JPEGHuffmanTable.getDefaultDCLuminanceTable(),
		JPEGHuffmanTable.getDefaultDCChrominanceTable(),
		JPEGHuffmanTable.getDefaultACLuminanceTable(),
		JPEGHuffmanTable.getDefaultACChrominanceTable()
	};
	for (int i = 0; i < dhtTables.length; i++) {
		JPEGHuffmanTable dhtTable = dhtTables[i];
		if (!dhtTable.writeToStream(outputStream)) {
			SWT.error(SWT.ERROR_IO);
		}
		JPEGHuffmanTable[] allTables = dhtTable.getAllTables();
		for (int j = 0; j < allTables.length; j++) {
			JPEGHuffmanTable huffmanTable = allTables[j];
			if (huffmanTable.getTableClass() == 0) {
				dcHuffmanTables[huffmanTable.getTableIdentifier()] = huffmanTable;
			} else {
				acHuffmanTables[huffmanTable.getTableIdentifier()] = huffmanTable;
			}
		}
	}
	precedingDCs = new int[4];
	scanHeader = new JPEGScanHeader(new byte[14]);
	scanHeader.setSegmentMarker(SOS);
	scanHeader.setSegmentLength(scanLength);
	scanHeader.setNumberOfImageComponents(nComponents);
	scanHeader.setStartOfSpectralSelection(0);
	scanHeader.setEndOfSpectralSelection(63);
	scanHeader.componentParameters = scanParams;
	scanHeader.initializeContents();
	if (!scanHeader.writeToStream(outputStream)) {
		SWT.error(SWT.ERROR_IO);
	}
	convertImageToYCbCr(image);
	resetOutputBuffer();
	currentByte = 0;
	currentBitCount = 0;
	encodeScan();
	if (!new JPEGEndOfImage().writeToStream(outputStream)) {
		SWT.error(SWT.ERROR_IO);
	}
}
}
