package org.eclipse.swt.internal.image;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved
 */

import java.io.*;
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;

public 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);
			}
			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);
}
/**
 * Answer whether the specified input stream
 * contains a PNG image.
 */
public static boolean isPNGFile(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.
 */
void setImageDataValues(byte[] data, ImageData imageData) {
	byte[] result = validateBitDepth(data);
	setPixelData(result, imageData);
}
/**
 * Read the image data from the data stream. This must handle
 * decoding the data, filtering, and interlacing.
 */
void readPixelData(PngIdatChunk chunk, PngChunkReader chunkReader) {
	decodingStream = new PngDecodingDataStream(chunk, chunkReader);
	int interlaceMethod = headerChunk.getInterlaceMethod();
	if (interlaceMethod == PngIhdrChunk.INTERLACE_METHOD_NONE) {
		readNonInterlacedImage();
	} else {
		readInterlacedImage();
	}
	decodingStream.assertImageDataAtEnd();
	decodingStream.checkAdler();
}
/**
 * Answer the number of bytes in a word-aligned row of pixel data.
 */
int getAlignedBytesPerRow() {
	return ((getBytesPerRow(headerChunk.getWidth()) + 3) / 4) * 4;
}
/**
 * Answer the number of bytes in each row of the image
 * data. Each PNG row is byte-aligned, so images with bit
 * depths less than a byte may have unused bits at the
 * end of each row. The value of these bits is undefined.
 */
int getBytesPerRow() {
	return getBytesPerRow(headerChunk.getWidth());
}
/**
 * Answer the number of bytes needed to represent a pixel.
 * This value depends on the image's color type and bit
 * depth. 
 * Note that this method rounds up if an image's pixel size
 * isn't byte-aligned.
 */
int getBytesPerPixel() {
	int bitsPerPixel = headerChunk.getBitsPerPixel();
	return (bitsPerPixel + 7) / 8;	
}
/**
 * Answer the number of bytes in a row of the given pixel
 * width. Each row is byte-aligned, so images with bit
 * depths less than a byte may have unused bits at the
 * end of each row. The value of these bits is undefined.
 */
int getBytesPerRow(int rowWidthInPixels) {
	int bitsPerPixel = headerChunk.getBitsPerPixel();
	int bitsPerRow = bitsPerPixel * rowWidthInPixels;
	int bitsPerByte = 8;
	return (bitsPerRow + (bitsPerByte - 1)) / bitsPerByte;
}
/**
 * 1. Read one of the seven frames of interlaced data.
 * 2. Update the imageData.
 * 3. Notify the image loader's listeners of the frame load.
 */
void readInterlaceFrame(
	int rowInterval,
	int columnInterval,
	int startRow,
	int startColumn,
	int frameCount) 
{
	int width = headerChunk.getWidth();
	int alignedBytesPerRow = getAlignedBytesPerRow();
	int height = headerChunk.getHeight();
	if (startRow >= height || startColumn >= width) return;
	
	int pixelsPerRow = (width - startColumn + columnInterval - 1) / columnInterval;
	int bytesPerRow = getBytesPerRow(pixelsPerRow);
	byte[] row1 = new byte[bytesPerRow];
	byte[] row2 = new byte[bytesPerRow];
	byte[] currentRow = row1;	
	byte[] lastRow = row2;	
	for (int row = startRow; row < height; row += rowInterval) {
		byte filterType = decodingStream.getNextDecodedByte();
		for (int col = 0; col < bytesPerRow; col++) {
			currentRow[col] = decodingStream.getNextDecodedByte();
		}
		filterRow(currentRow, lastRow, filterType);
		if (headerChunk.getBitDepth() >= 8) {
			int bytesPerPixel = getBytesPerPixel();
			int dataOffset = (row * alignedBytesPerRow) + (startColumn * bytesPerPixel);
			for (int rowOffset = 0; rowOffset < currentRow.length; rowOffset += bytesPerPixel) {
				for (int byteOffset = 0; byteOffset < bytesPerPixel; byteOffset++) {
					data[dataOffset + byteOffset] = currentRow[rowOffset + byteOffset];
				}
				dataOffset += (columnInterval * bytesPerPixel);
			}
		} else {
			int bitsPerPixel = headerChunk.getBitDepth();
			int pixelsPerByte = 8 / bitsPerPixel;
			int column = startColumn;
			int rowBase = row * alignedBytesPerRow;
			int valueMask = 0;
			for (int i = 0; i < bitsPerPixel; i++) {
				valueMask <<= 1;
				valueMask |= 1;
			}
			int maxShift = 8 - bitsPerPixel;
			for (int byteOffset = 0; byteOffset < currentRow.length; byteOffset++) {
				for (int bitOffset = maxShift; bitOffset >= 0; bitOffset -= bitsPerPixel) {
					if (column < width) {
						int dataOffset = rowBase + (column * bitsPerPixel / 8);							
						int value = (currentRow[byteOffset] >> bitOffset) & valueMask;
						int dataShift = maxShift - (bitsPerPixel * (column % pixelsPerByte));
						data[dataOffset] |= value << dataShift;
					}
					column += columnInterval;
				}
			}
		}
		currentRow = (currentRow == row1) ? row2 : row1;
		lastRow = (lastRow == row1) ? row2 : row1;
	}
	setImageDataValues(data, imageData);
	fireInterlacedFrameEvent(frameCount);
}
/**
 * Read the pixel data for an interlaced image from the
 * data stream.
 */
void readInterlacedImage() {
	readInterlaceFrame(8, 8, 0, 0, 0);
	readInterlaceFrame(8, 8, 0, 4, 1);	
	readInterlaceFrame(8, 4, 4, 0, 2);	
	readInterlaceFrame(4, 4, 0, 2, 3);
	readInterlaceFrame(4, 2, 2, 0, 4);
	readInterlaceFrame(2, 2, 0, 1, 5);	
	readInterlaceFrame(2, 1, 1, 0, 6);
}
/**
 * Fire an event to let listeners know that an interlaced
 * frame has been loaded.
 * finalFrame should be true if the image has finished
 * loading, false if there are more frames to come.
 */
void fireInterlacedFrameEvent(int frameCount) {
	if (loader.hasListeners()) {
		ImageData image = (ImageData) imageData.clone();
		boolean finalFrame = frameCount == 6;
		loader.notifyListeners(new ImageLoaderEvent(loader, image, frameCount, finalFrame));
	}
}
/**
 * Read the pixel data for a non-interlaced image from the
 * data stream.
 * Update the imageData to reflect the new data.
 */
void readNonInterlacedImage() {
	int dataOffset = 0;
	int alignedBytesPerRow = getAlignedBytesPerRow();
	int bytesPerRow = getBytesPerRow();
	byte[] row1 = new byte[bytesPerRow];
	byte[] row2 = new byte[bytesPerRow];
	byte[] currentRow = row1;	
	byte[] lastRow = row2;
	for (int row = 0; row < headerChunk.getHeight(); row++) {
		byte filterType = decodingStream.getNextDecodedByte();
		for (int col = 0; col < bytesPerRow; col++) {
			currentRow[col] = decodingStream.getNextDecodedByte();
		}
		filterRow(currentRow, lastRow, filterType);
		System.arraycopy(currentRow, 0, data, dataOffset, bytesPerRow);
		dataOffset += alignedBytesPerRow;
		currentRow = (currentRow == row1) ? row2 : row1;
		lastRow = (lastRow == row1) ? row2 : row1;
	}
	setImageDataValues(data, imageData);
}
/**
 * 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.
 */
static void compress16BitDepthTo8BitDepth(
	byte[] source,
	int sourceOffset,
	byte[] destination, 
	int destinationOffset,
	int numberOfValues) 
{
	//double multiplier = (Compatibility.pow2(8) - 1) / (Compatibility.pow2(16) - 1);
	for (int i = 0; i < numberOfValues; i++) {
		int sourceIndex = sourceOffset + (2 * i);
		int destinationIndex = destinationOffset + i;
		//int value = (source[sourceIndex] << 8) | source[sourceIndex + 1];
		//byte compressedValue = (byte)(value * multiplier);
		byte compressedValue = source[sourceIndex];
		destination[destinationIndex] = compressedValue;
	}
}
/**
 * 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.
 */
static int compress16BitDepthTo8BitDepth(int value) {
	//double multiplier = (Compatibility.pow2(8) - 1) / (Compatibility.pow2(16) - 1);
	//byte compressedValue = (byte)(value * multiplier);
	return value >> 8;
}
/**
 * PNG supports four filtering types. These types are applied
 * per row of image data. This method unfilters the given row
 * based on the filterType.
 */
void filterRow(byte[] row, byte[] previousRow, int filterType) {
	int byteOffset = headerChunk.getFilterByteOffset();
	switch (filterType) {
		case PngIhdrChunk.FILTER_NONE:
			break;
		case PngIhdrChunk.FILTER_SUB:
			for (int i = byteOffset; i < row.length; i++) {
				int current = row[i] & 0xFF;
				int left = row[i - byteOffset] & 0xFF;
				row[i] = (byte)((current + left) & 0xFF);
			}
			break;
		case PngIhdrChunk.FILTER_UP:
			for (int i = 0; i < row.length; i++) {
				int current = row[i] & 0xFF;
				int above = previousRow[i] & 0xFF;				
				row[i] = (byte)((current + above) & 0xFF);
			}
			break;
		case PngIhdrChunk.FILTER_AVERAGE:
			for (int i = 0; i < row.length; i++) {
				int left = (i < byteOffset) ? 0 : row[i - byteOffset] & 0xFF;
				int above = previousRow[i] & 0xFF;
				int current = row[i] & 0xFF;
				row[i] = (byte)((current + ((left + above) / 2)) & 0xFF);
			}
			break;
		case PngIhdrChunk.FILTER_PAETH:
			for (int i = 0; i < row.length; i++) {
				int left = (i < byteOffset) ? 0 : row[i - byteOffset] & 0xFF;
				int aboveLeft = (i < byteOffset) ? 0 : previousRow[i - byteOffset] & 0xFF;
				int above = previousRow[i] & 0xFF;
				
				int a = Math.abs(above - aboveLeft);
				int b = Math.abs(left - aboveLeft);
				int c = Math.abs(left - aboveLeft + above - aboveLeft);
				
				int preductor = 0;
				if (a <= b && a <= c) {
					preductor = left;
				} else if (b <= c) {
					preductor = above;
				} else {
					preductor = aboveLeft;
				}
				
				int currentValue = row[i] & 0xFF;
				row[i] = (byte) ((currentValue + preductor) & 0xFF);
			}
			break;
	}
}

}
