?? jpegfileformat.java
字號:
/******************************************************************************* * Copyright (c) 2000, 2004 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-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; JPEGArithmeticConditioningTable arithmeticTables; JPEGHuffmanTable[] acHuffmanTables; JPEGHuffmanTable[] dcHuffmanTables; int[][] quantizationTables; int currentByte; int decoderQFactor; 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 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 / 65536); if ((n < 0) && (n % 65536 != 0)) yComp[i]--; n = RCbTable[r] + GCbTable[g] + BCbTable[b]; cbComp[i] = (byte)(n / 65536); if ((n < 0) && (n % 65536 != 0)) cbComp[i]--; n = RCrTable[r] + GCrTable[g] + BCrTable[b]; crComp[i] = (byte)(n / 65536); if ((n < 0) && (n % 65536 != 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; for (int yPos = 0; yPos < srcHeight; yPos++) { for (int xPos = 0; xPos < srcWidth / 2; xPos++) { int srcIndex = yPos * (srcWidth / 2) + xPos; int dstIndex = yPos * srcWidth + (xPos * 2); int value2 = origData[srcIndex] & 0xFF; int value1 = value2 / 16; value2 = value2 % 16; 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 / 65536); if ((n < 0) && (n % 65536 != 0)) yComp[i]--; n = RCbTable[r] + GCbTable[g] + BCbTable[b]; cbComp[i] = (byte)(n / 65536); if ((n < 0) && (n % 65536 != 0)) cbComp[i]--; n = RCrTable[r] + GCrTable[g] + BCrTable[b]; crComp[i] = (byte)(n / 65536); if ((n < 0) && (n % 65536 != 0)) crComp[i]--; } int dstWidth = image.width; int dstHeight = srcHeight; int stride = (srcWidth + 3) / 4 * 4; 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]) / 65536); dataCbComp[dstDataIndex] = (byte)((RCbTable[r] + GCbTable[g] + BCbTable[b]) / 65536); dataCrComp[dstDataIndex] = (byte)((RCrTable[r] + GCrTable[g] + BCrTable[b]) / 65536); } } } 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]) / 65536); dataCbComp[dstDataIndex] = (byte)((RCbTable[r] + GCbTable[g] + BCbTable[b]) / 65536); dataCrComp[dstDataIndex] = (byte)((RCrTable[r] + GCrTable[g] + BCrTable[b]) / 65536); } } } 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]) / 65536); 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;}byte[] convertYIQToRGB() { /* Unsupported CMYK format. Answer an empty byte array. */ return new byte[0];}void decodeACCoefficients(int[] dataUnit, int iComp) { int[] sParams = scanHeader.componentParameters[componentIds[iComp]]; JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -