?? pngfileformat.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 java.io.*;import org.eclipse.swt.*;import org.eclipse.swt.graphics.*;final class PNGFileFormat extends FileFormat { static final int SIGNATURE_LENGTH = 8; PngDecodingDataStream decodingStream; PngIhdrChunk headerChunk; PngPlteChunk paletteChunk; PngTrnsChunk trnsChunk; ImageData imageData; byte[] data; byte[] alphaPalette;/** * Skip over signature data. This has already been * verified in isPNGFile(). */void readSignature() throws IOException { byte[] signature = new byte[SIGNATURE_LENGTH]; inputStream.read(signature);}/** * Load the PNG image from the byte stream. */ImageData[] loadFromByteStream() { try { readSignature(); PngChunkReader chunkReader = new PngChunkReader(inputStream); headerChunk = chunkReader.getIhdrChunk(); int imageSize = getAlignedBytesPerRow() * headerChunk.getHeight(); data = new byte[imageSize]; imageData = ImageData.internal_new( headerChunk.getWidth(), headerChunk.getHeight(), headerChunk.getSwtBitsPerPixel(), new PaletteData(0, 0, 0), 4, data, 0, null, null, -1, -1, SWT.IMAGE_PNG, 0, 0, 0, 0); if (headerChunk.usesDirectColor()) { imageData.palette = headerChunk.getPaletteData(); } // Read and process chunks until the IEND chunk is encountered. while (chunkReader.hasMoreChunks()) { readNextChunk(chunkReader); } return new ImageData[] {imageData}; } catch (IOException e) { SWT.error(SWT.ERROR_INVALID_IMAGE); return null; }}/** * Read and handle the next chunk of data from the * PNG file. */void readNextChunk(PngChunkReader chunkReader) { PngChunk chunk = chunkReader.readNextChunk(); switch (chunk.getChunkType()) { case PngChunk.CHUNK_IEND: break; case PngChunk.CHUNK_PLTE: if (!headerChunk.usesDirectColor()) { paletteChunk = (PngPlteChunk) chunk; imageData.palette = paletteChunk.getPaletteData(); } break; case PngChunk.CHUNK_tRNS: PngTrnsChunk trnsChunk = (PngTrnsChunk) chunk; if (trnsChunk.getTransparencyType(headerChunk) == PngTrnsChunk.TRANSPARENCY_TYPE_PIXEL) { imageData.transparentPixel = trnsChunk.getSwtTransparentPixel(headerChunk); } else { alphaPalette = trnsChunk.getAlphaValues(headerChunk, paletteChunk); int transparentCount = 0, transparentPixel = -1; for (int i = 0; i < alphaPalette.length; i++) { if ((alphaPalette[i] & 0xFF) != 255) { transparentCount++; transparentPixel = i; } } if (transparentCount == 0) { alphaPalette = null; } else if (transparentCount == 1 && alphaPalette[transparentPixel] == 0) { alphaPalette = null; imageData.transparentPixel = transparentPixel; } } break; case PngChunk.CHUNK_IDAT: if (chunkReader.readPixelData()) { // All IDAT chunks in an image file must be // sequential. If the pixel data has already // been read and another IDAT block is encountered, // then this is an invalid image. SWT.error(SWT.ERROR_INVALID_IMAGE); } else { // Read in the pixel data for the image. This should // go through all the image's IDAT chunks. PngIdatChunk dataChunk = (PngIdatChunk) chunk; readPixelData(dataChunk, chunkReader); } break; default: if (chunk.isCritical()) { // All critical chunks must be supported. SWT.error(SWT.ERROR_NOT_IMPLEMENTED); } }}void unloadIntoByteStream(ImageData p1) { SWT.error(SWT.ERROR_NOT_IMPLEMENTED);}boolean isFileFormat(LEDataInputStream stream) { try { byte[] signature = new byte[SIGNATURE_LENGTH]; stream.read(signature); stream.unread(signature); if ((signature[0] & 0xFF) != 137) return false; //137 if ((signature[1] & 0xFF) != 80) return false; //P if ((signature[2] & 0xFF) != 78) return false; //N if ((signature[3] & 0xFF) != 71) return false; //G if ((signature[4] & 0xFF) != 13) return false; //<RETURN> if ((signature[5] & 0xFF) != 10) return false; //<LINEFEED> if ((signature[6] & 0xFF) != 26) return false; //<CTRL/Z> if ((signature[7] & 0xFF) != 10) return false; //<LINEFEED> return true; } catch (Exception e) { return false; }}/** * SWT does not support 16-bit depths. If this image uses * 16-bit depths, convert the data to an 8-bit depth. */byte[] validateBitDepth(byte[] data) { if (headerChunk.getBitDepth() > 8) { byte[] result = new byte[data.length / 2]; compress16BitDepthTo8BitDepth(data, 0, result, 0, result.length); return result; } else { return data; }}/** * SWT does not support greyscale as a color type. For * plain grayscale, we create a palette. For Grayscale * with Alpha, however, we need to convert the pixels * to use RGB values. * Note: This method assumes that the bit depth of the * data has already been restricted to 8 or less. */void setPixelData(byte[] data, ImageData imageData) { switch (headerChunk.getColorType()) { case PngIhdrChunk.COLOR_TYPE_GRAYSCALE_WITH_ALPHA: { int width = imageData.width; int height = imageData.height; int destBytesPerLine = imageData.bytesPerLine; /* * If the image uses 16-bit depth, it is converted * to an 8-bit depth image. */ int srcBytesPerLine = getAlignedBytesPerRow(); if (headerChunk.getBitDepth() > 8) srcBytesPerLine /= 2; byte[] rgbData = new byte[destBytesPerLine * height]; byte[] alphaData = new byte[width * height]; for (int y = 0; y < height; y++) { int srcIndex = srcBytesPerLine * y; int destIndex = destBytesPerLine * y; int destAlphaIndex = width * y; for (int x = 0; x < width; x++) { byte grey = data[srcIndex]; byte alpha = data[srcIndex + 1]; rgbData[destIndex + 0] = grey; rgbData[destIndex + 1] = grey; rgbData[destIndex + 2] = grey; alphaData[destAlphaIndex] = alpha; srcIndex += 2; destIndex += 3; destAlphaIndex++; } } imageData.data = rgbData; imageData.alphaData = alphaData; break; } case PngIhdrChunk.COLOR_TYPE_RGB_WITH_ALPHA: { int width = imageData.width; int height = imageData.height; int destBytesPerLine = imageData.bytesPerLine; int srcBytesPerLine = getAlignedBytesPerRow(); /* * If the image uses 16-bit depth, it is converted * to an 8-bit depth image. */ if (headerChunk.getBitDepth() > 8) srcBytesPerLine /= 2; byte[] rgbData = new byte[destBytesPerLine * height]; byte[] alphaData = new byte[width * height]; for (int y = 0; y < height; y++) { int srcIndex = srcBytesPerLine * y; int destIndex = destBytesPerLine * y; int destAlphaIndex = width * y; for (int x = 0; x < width; x++) { rgbData[destIndex + 0] = data[srcIndex + 0]; rgbData[destIndex + 1] = data[srcIndex + 1]; rgbData[destIndex + 2] = data[srcIndex + 2]; alphaData[destAlphaIndex] = data[srcIndex + 3]; srcIndex += 4; destIndex += 3; destAlphaIndex++; } } imageData.data = rgbData; imageData.alphaData = alphaData; break; } case PngIhdrChunk.COLOR_TYPE_RGB: imageData.data = data; break; case PngIhdrChunk.COLOR_TYPE_PALETTE: imageData.data = data; if (alphaPalette != null) { int size = imageData.width * imageData.height; byte[] alphaData = new byte[size]; byte[] pixelData = new byte[size]; imageData.getPixels(0, 0, size, pixelData, 0); for (int i = 0; i < pixelData.length; i++) { alphaData[i] = alphaPalette[pixelData[i] & 0xFF]; } imageData.alphaData = alphaData; } break; default: imageData.data = data; break; }}/** * PNG supports some color types and bit depths that are * unsupported by SWT. If the image uses an unsupported * color type (either of the gray scale types) or bit * depth (16), convert the data to an SWT-supported * format. Then assign the data into the ImageData given. */
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -