⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tiffdirectory.java

📁 源码为Eclipse开源开发平台桌面开发工具SWT的源代码,
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************* * Copyright (c) 2000, 2003 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 TIFFDirectory {	TIFFRandomFileAccess file;	boolean isLittleEndian;	ImageLoader loader;	int depth;		/* Directory fields */	int imageWidth;	int imageLength;	int[] bitsPerSample;	int compression;	int photometricInterpretation;	int[] stripOffsets;	int samplesPerPixel;	int rowsPerStrip;	int[] stripByteCounts;	int t4Options;	int colorMapOffset;		/* Encoder fields */	ImageData image;	LEDataOutputStream out;		static final int NO_VALUE = -1;		static final short TAG_ImageWidth = 256;	static final short TAG_ImageLength = 257;	static final short TAG_BitsPerSample = 258;	static final short TAG_Compression = 259;	static final short TAG_PhotometricInterpretation = 262;	static final short TAG_StripOffsets = 273;	static final short TAG_SamplesPerPixel = 277;	static final short TAG_RowsPerStrip = 278;	static final short TAG_StripByteCounts = 279;	static final short TAG_XResolution = 282;	static final short TAG_YResolution = 283;	static final short TAG_T4Options = 292;	static final short TAG_ResolutionUnit = 296;	static final short TAG_ColorMap = 320;		static final int TYPE_BYTE = 1;	static final int TYPE_ASCII = 2;	static final int TYPE_SHORT = 3;	static final int TYPE_LONG = 4;	static final int TYPE_RATIONAL = 5;		/* Different compression schemes */	static final int COMPRESSION_NONE = 1;	static final int COMPRESSION_CCITT_3_1 = 2;	static final int COMPRESSION_PACKBITS = 32773;		static final int IFD_ENTRY_SIZE = 12;	public TIFFDirectory(TIFFRandomFileAccess file, boolean isLittleEndian, ImageLoader loader) {	this.file = file;	this.isLittleEndian = isLittleEndian;	this.loader = loader;}public TIFFDirectory(ImageData image) {	this.image = image;}/* PackBits decoder */int decodePackBits(byte[] src, byte[] dest, int offsetDest) {	int destIndex = offsetDest;	int srcIndex = 0;	while (srcIndex < src.length) {		byte n = src[srcIndex];		if (0 <= n && n <= 127) {			/* Copy next n+1 bytes literally */			System.arraycopy(src, ++srcIndex, dest, destIndex, n + 1);			srcIndex += n + 1;					destIndex += n + 1;			} else if (-127 <= n && n <= -1) {			/* Copy next byte -n+1 times */			byte value = src[++srcIndex];			for (int j = 0; j < -n + 1; j++) {				dest[destIndex++] = value;			}			srcIndex++;		} else {			/* Noop when n == -128 */			srcIndex++;		}	}	/* Number of bytes copied */	return destIndex - offsetDest;}int getEntryValue(int type, byte[] buffer, int index) {	return toInt(buffer, index + 8, type);}void getEntryValue(int type, byte[] buffer, int index, int[] values) throws IOException {	int start = index + 8;	int size;	int offset = toInt(buffer, start, TYPE_LONG);	switch (type) {		case TYPE_SHORT: size = 2; break;		case TYPE_LONG: size = 4; break; 		case TYPE_RATIONAL: size = 8; break;		case TYPE_ASCII:		case TYPE_BYTE: size = 1; break;		default: SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT); return;	}	if (values.length * size > 4) {		buffer = new byte[values.length * size]; 		file.seek(offset);		file.read(buffer);		start = 0;	}	for (int i = 0; i < values.length; i++) {		values[i] = toInt(buffer, start + i * size, type);	}}void decodePixels(ImageData image) throws IOException {	/* Each row is byte aligned */ 	byte[] imageData = new byte[(imageWidth * depth + 7) / 8 * imageLength];	image.data = imageData;	int destIndex = 0;	int length = stripOffsets.length;	for (int i = 0; i < length; i++) {		/* Read a strip */		byte[] data = new byte[stripByteCounts[i]];		file.seek(stripOffsets[i]);		file.read(data);		if (compression == COMPRESSION_NONE) {			System.arraycopy(data, 0, imageData, destIndex, data.length);			destIndex += data.length;		} else if (compression == COMPRESSION_PACKBITS) {			destIndex += decodePackBits(data, imageData, destIndex);		} else if (compression == COMPRESSION_CCITT_3_1 || compression == 3) {			TIFFModifiedHuffmanCodec codec = new TIFFModifiedHuffmanCodec();			int nRows = rowsPerStrip;			if (i == length -1) {				int n = imageLength % rowsPerStrip;				if (n != 0) nRows = n;			}			destIndex += codec.decode(data, imageData, destIndex, imageWidth, nRows);		}		if (loader.hasListeners()) {			loader.notifyListeners(new ImageLoaderEvent(loader, image, i, i == length - 1));		}	}}PaletteData getColorMap() throws IOException {	int numColors = 1 << bitsPerSample[0];	/* R, G, B entries are 16 bit wide (2 bytes) */	int numBytes = 3 * 2 * numColors;	byte[] buffer = new byte[numBytes];	file.seek(colorMapOffset);	file.read(buffer);	RGB[] colors = new RGB[numColors];	/**	 * SWT does not support 16-bit depth color formats.	 * Convert the 16-bit data to 8-bit data.	 * The correct way to do this is to multiply each	 * 16 bit value by the value:	 * (2^8 - 1) / (2^16 - 1).	 * The fast way to do this is just to drop the low	 * byte of the 16-bit value.	 */	int offset = isLittleEndian ? 1 : 0;	int startG = 2 * numColors;	int startB = startG + 2 * numColors;	for (int i = 0; i < numColors; i++) {		int r = buffer[offset] & 0xFF;		int g = buffer[startG + offset] & 0xFF;		int b = buffer[startB + offset] & 0xFF;		colors[i] = new RGB(r, g, b);		offset += 2;	}	return new PaletteData(colors);}PaletteData getGrayPalette() {	int numColors = 1 << bitsPerSample[0];	RGB[] rgbs = new RGB[numColors];	for (int i = 0; i < numColors; i++) {		int value = i * 0xFF / (numColors - 1);		if (photometricInterpretation == 0) value = 0xFF - value;		rgbs[i] = new RGB(value, value, value);	}	return new PaletteData(rgbs);}PaletteData getRGBPalette(int bitsR, int bitsG, int bitsB) {		int blueMask = 0;	for (int i = 0; i < bitsB; i++) {		blueMask |= 1 << i;	}	int greenMask = 0;	for (int i = bitsB; i < bitsB + bitsG; i++) {		greenMask |= 1 << i;	}	int redMask = 0;	for (int i = bitsB + bitsG; i < bitsB + bitsG + bitsR; i++) {		redMask |= 1 << i;	}		return new PaletteData(redMask, greenMask, blueMask);}int formatStrips(int rowByteSize, int nbrRows, byte[] data, int maxStripByteSize, int offsetPostIFD, int extraBytes, int[][] strips) {	/* 	* Calculate the nbr of required strips given the following requirements: 	* - each strip should, if possible, not be greater than maxStripByteSize	* - each strip should contain 1 or more entire rows	* 	* Format the strip fields arrays so that the image data is stored in one	* contiguous block. This block is stored after the IFD and after any tag	* info described in the IFD.	*/	int n, nbrRowsPerStrip;	if (rowByteSize > maxStripByteSize) {		/* Each strip contains 1 row */		n = data.length / rowByteSize;		nbrRowsPerStrip = 1;	} else {		int nbr = (data.length + maxStripByteSize - 1) / maxStripByteSize;		nbrRowsPerStrip = nbrRows / nbr;		n = (nbrRows + nbrRowsPerStrip - 1) / nbrRowsPerStrip;		}	int stripByteSize = rowByteSize * nbrRowsPerStrip;	int[] offsets = new int[n];	int[] counts = new int[n];	/* 	* Nbr of bytes between the end of the IFD directory and the start of	* the image data. Keep space for at least the offsets and counts	* data, each field being TYPE_LONG (4 bytes). If other tags require	* space between the IFD and the image block, use the extraBytes	* parameter.	* If there is only one strip, the offsets and counts data is stored	* directly in the IFD and we need not reserve space for it.	*/	int postIFDData = n == 1 ? 0 : n * 2 * 4;	int startOffset = offsetPostIFD + extraBytes + postIFDData; /* offset of image data */		int offset = startOffset;	for (int i = 0; i < n; i++) {		/* 		* Store all strips sequentially to allow us		* to copy all pixels in one contiguous area.		*/		offsets[i] = offset;		counts[i] = stripByteSize;		offset += stripByteSize;	}	/* The last strip may contain fewer rows */	int mod = data.length % stripByteSize;	if (mod != 0) counts[counts.length - 1] = mod;		strips[0] = offsets;	strips[1] = counts;	return nbrRowsPerStrip;}int[] formatColorMap(RGB[] rgbs) {	/* 	* In a TIFF ColorMap, all red come first, followed by	* green and blue. All values must be converted from	* 8 bit to 16 bit. 	*/	int[] colorMap = new int[rgbs.length * 3];	int offsetGreen = rgbs.length;	int offsetBlue = rgbs.length * 2;	for (int i = 0; i < rgbs.length; i++) {		colorMap[i] = rgbs[i].red << 8 | rgbs[i].red;		colorMap[i + offsetGreen] = rgbs[i].green << 8 | rgbs[i].green;		colorMap[i + offsetBlue] = rgbs[i].blue << 8 | rgbs[i].blue;	}	return colorMap;}void parseEntries(byte[] buffer) throws IOException {	for (int offset = 0; offset < buffer.length; offset += IFD_ENTRY_SIZE) {		int tag = toInt(buffer, offset, TYPE_SHORT);		int type = toInt(buffer, offset + 2, TYPE_SHORT);		int count = toInt(buffer, offset + 4, TYPE_LONG);		switch (tag) {			case TAG_ImageWidth: {				imageWidth = getEntryValue(type, buffer, offset);				break;			}			case TAG_ImageLength: {				imageLength = getEntryValue(type, buffer, offset);				break;			}			case TAG_BitsPerSample: {				if (type != TYPE_SHORT) SWT.error(SWT.ERROR_INVALID_IMAGE);				bitsPerSample = new int[count];				getEntryValue(type, buffer, offset, bitsPerSample);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -