You are viewing a plain text version of this content. The canonical link for it is here.
Posted to sanselan-commits@incubator.apache.org by cm...@apache.org on 2008/07/15 22:31:25 UTC

svn commit: r677073 [1/2] - in /incubator/sanselan/trunk/src: main/java/org/apache/sanselan/common/ main/java/org/apache/sanselan/formats/gif/ main/java/org/apache/sanselan/formats/png/ main/java/org/apache/sanselan/formats/png/chunks/ test/data/images...

Author: cmchen
Date: Tue Jul 15 15:31:25 2008
New Revision: 677073

URL: http://svn.apache.org/viewvc?rev=677073&view=rev
Log:
jira issue: SANSELAN-5

Fixed two issues in the PNG reader.  Wasn't handling the 16-bit mode 4 PNGs properly.  Also, wasn't gamma-correcting non-palette values properly in PNGs.  

Added very helpful pngs (and variants) to the test suite and added a unit test around png->gif conversion.  

Also, took the opportunity to remove some debuging statements and dead code.

Added:
    incubator/sanselan/trunk/src/test/data/images/png/2/
    incubator/sanselan/trunk/src/test/data/images/png/2/12118.png   (with props)
    incubator/sanselan/trunk/src/test/data/images/png/2/28569-4.png   (with props)
    incubator/sanselan/trunk/src/test/data/images/png/2/28569-8.png   (with props)
    incubator/sanselan/trunk/src/test/data/images/png/2/28569.png   (with props)
    incubator/sanselan/trunk/src/test/data/images/png/2/info.txt   (with props)
    incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/png/ConvertPngToGifTest.java   (with props)
    incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/png/PngBaseTest.java   (with props)
Modified:
    incubator/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileParser.java
    incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/gif/GifImageParser.java
    incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/BitParser.java
    incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/GammaCorrection.java
    incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngImageParser.java
    incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngWriter.java
    incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/ScanExpediter.java
    incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/ScanExpediterInterlaced.java
    incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/ScanExpediterSimple.java
    incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/chunks/PNGChunkPLTE.java
    incubator/sanselan/trunk/src/test/java/org/apache/sanselan/SanselanTest.java
    incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/png/PngReadTest.java

Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileParser.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileParser.java?rev=677073&r1=677072&r2=677073&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileParser.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileParser.java Tue Jul 15 15:31:25 2008
@@ -63,6 +63,11 @@
 		return byteOrder;
 	}
 
+	protected final int convertByteArrayToInt(String name, int start, byte bytes[])
+	{
+		return convertByteArrayToInt(name, bytes, start, byteOrder);
+	}
+
 	protected final int convertByteArrayToInt(String name, byte bytes[])
 	{
 		return convertByteArrayToInt(name, bytes, byteOrder);

Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/gif/GifImageParser.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/gif/GifImageParser.java?rev=677073&r1=677072&r2=677073&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/gif/GifImageParser.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/gif/GifImageParser.java Tue Jul 15 15:31:25 2008
@@ -43,51 +43,40 @@
 import org.apache.sanselan.palette.Palette;
 import org.apache.sanselan.palette.PaletteFactory;
 import org.apache.sanselan.util.Debug;
+import org.apache.sanselan.util.ParamMap;
 
-public class GifImageParser extends ImageParser
-{
+public class GifImageParser extends ImageParser {
 
-	public GifImageParser()
-	{
+	public GifImageParser() {
 		super.setByteOrder(BYTE_ORDER_LSB);
 	}
 
-	public String getName()
-	{
+	public String getName() {
 		return "Gif-Custom";
 	}
 
-	public String getDefaultExtension()
-	{
+	public String getDefaultExtension() {
 		return DEFAULT_EXTENSION;
 	}
 
 	private static final String DEFAULT_EXTENSION = ".gif";
 
-	private static final String ACCEPTED_EXTENSIONS[] = {
-		DEFAULT_EXTENSION,
-	};
+	private static final String ACCEPTED_EXTENSIONS[] = { DEFAULT_EXTENSION, };
 
-	protected String[] getAcceptedExtensions()
-	{
+	protected String[] getAcceptedExtensions() {
 		return ACCEPTED_EXTENSIONS;
 	}
 
-	protected ImageFormat[] getAcceptedTypes()
-	{
-		return new ImageFormat[]{
-			ImageFormat.IMAGE_FORMAT_GIF, //
+	protected ImageFormat[] getAcceptedTypes() {
+		return new ImageFormat[] { ImageFormat.IMAGE_FORMAT_GIF, //
 		};
 	}
 
-	private static final byte GIF_HEADER_SIGNATURE[] = {
-			71, 73, 70
-	};
+	private static final byte GIF_HEADER_SIGNATURE[] = { 71, 73, 70 };
 
 	private GIFHeaderInfo readHeader(InputStream is,
 			FormatCompliance formatCompliance) throws ImageReadException,
-			IOException
-	{
+			IOException {
 		byte identifier1 = readByte("identifier1", is, "Not a Valid GIF File");
 		byte identifier2 = readByte("identifier2", is, "Not a Valid GIF File");
 		byte identifier3 = readByte("identifier3", is, "Not a Valid GIF File");
@@ -96,16 +85,12 @@
 		byte version2 = readByte("version2", is, "Not a Valid GIF File");
 		byte version3 = readByte("version3", is, "Not a Valid GIF File");
 
-		if (formatCompliance != null)
-		{
+		if (formatCompliance != null) {
 			formatCompliance.compare_bytes("Signature", GIF_HEADER_SIGNATURE,
-					new byte[]{
-							identifier1, identifier2, identifier3,
-					});
+					new byte[] { identifier1, identifier2, identifier3, });
 			formatCompliance.compare("version", 56, version1);
-			formatCompliance.compare("version", new int[]{
-					55, 57,
-			}, version2);
+			formatCompliance
+					.compare("version", new int[] { 55, 57, }, version2);
 			formatCompliance.compare("version", 97, version3);
 		}
 
@@ -121,8 +106,7 @@
 		int logicalScreenHeight = read2Bytes("Logical Screen Height", is,
 				"Not a Valid GIF File");
 
-		if (formatCompliance != null)
-		{
+		if (formatCompliance != null) {
 			formatCompliance.checkBounds("Width", 1, Integer.MAX_VALUE,
 					logicalScreenWidth);
 			formatCompliance.checkBounds("Height", 1, Integer.MAX_VALUE,
@@ -153,8 +137,7 @@
 			System.out.println("SizeofGlobalColorTable: "
 					+ sizeofGlobalColorTable);
 
-		if (formatCompliance != null)
-		{
+		if (formatCompliance != null) {
 			if (globalColorTableFlag && backgroundColorIndex != -1)
 				formatCompliance.checkBounds("Background Color Index", 0,
 						convertColorTableSize(sizeofGlobalColorTable),
@@ -169,8 +152,7 @@
 	}
 
 	private GraphicControlExtension readGraphicControlExtension(int code,
-			InputStream is) throws ImageReadException, IOException
-	{
+			InputStream is) throws ImageReadException, IOException {
 		readByte("block_size", is, "GIF: corrupt GraphicControlExt");
 		int packed = readByte("packed fields", is,
 				"GIF: corrupt GraphicControlExt");
@@ -189,8 +171,7 @@
 	}
 
 	private byte[] readSubBlock(InputStream is) throws ImageReadException,
-			IOException
-	{
+			IOException {
 		int block_size = 0xff & readByte("block_size", is, "GIF: corrupt block");
 
 		byte bytes[] = readByteArray("block", block_size, is,
@@ -200,22 +181,19 @@
 	}
 
 	protected GenericGIFBlock readGenericGIFBlock(InputStream is, int code)
-			throws ImageReadException, IOException
-	{
+			throws ImageReadException, IOException {
 		return readGenericGIFBlock(is, code, null);
 	}
 
 	protected GenericGIFBlock readGenericGIFBlock(InputStream is, int code,
-			byte first[]) throws ImageReadException, IOException
-	{
+			byte first[]) throws ImageReadException, IOException {
 		byte bytes[] = null;
 		ArrayList subblocks = new ArrayList();
 
 		if (first != null)
 			subblocks.add(first);
 
-		while (true)
-		{
+		while (true) {
 			bytes = readSubBlock(is);
 			if (bytes.length < 1)
 				break;
@@ -233,105 +211,100 @@
 
 	private ArrayList readBlocks(GIFHeaderInfo ghi, InputStream is,
 			boolean stop_before_image_data, FormatCompliance formatCompliance)
-			throws ImageReadException, IOException
-	{
+			throws ImageReadException, IOException {
 		ArrayList result = new ArrayList();
 
-		while (true)
-		{
+		while (true) {
 			int code = is.read();
-			//			this.debugNumber("code: ", code);
+			// this.debugNumber("code: ", code);
 
-			switch (code)
-			{
-				case -1 :
-					throw new ImageReadException("GIF: unexpected end of data");
+			switch (code) {
+			case -1:
+				throw new ImageReadException("GIF: unexpected end of data");
+
+			case IMAGE_SEPARATOR:
+				ImageDescriptor id = readImageDescriptor(ghi, code, is,
+						stop_before_image_data, formatCompliance);
+				result.add(id);
 
-				case IMAGE_SEPARATOR :
-					ImageDescriptor id = readImageDescriptor(ghi, code, is,
-							stop_before_image_data, formatCompliance);
-					result.add(id);
+				break;
 
+			case 0x21: // extension
+			{
+				int extension_code = is.read();
+				// this.debugNumber("extension_code: ", extension_code);
+				int complete_code = ((0xff & code) << 8)
+						| (0xff & extension_code);
+
+				switch (extension_code) {
+				case 0xf9:
+					GraphicControlExtension gce = readGraphicControlExtension(
+							complete_code, is);
+					result.add(gce);
 					break;
 
-				case 0x21 : // extension
-				{
-					int extension_code = is.read();
-					//					this.debugNumber("extension_code: ", extension_code);
-					int complete_code = ((0xff & code) << 8)
-							| (0xff & extension_code);
-
-					switch (extension_code)
-					{
-						case 0xf9 :
-							GraphicControlExtension gce = readGraphicControlExtension(
-									complete_code, is);
-							result.add(gce);
-							break;
-
-						case COMMENT_EXTENSION : {
-							GenericGIFBlock block = readGenericGIFBlock(is,
-									complete_code);
-							result.add(block);
-							break;
-						}
+				case COMMENT_EXTENSION: {
+					GenericGIFBlock block = readGenericGIFBlock(is,
+							complete_code);
+					result.add(block);
+					break;
+				}
 
-						case PLAIN_TEXT_EXTENSION : {
-							GenericGIFBlock block = readGenericGIFBlock(is,
-									complete_code);
-							result.add(block);
-							break;
-						}
+				case PLAIN_TEXT_EXTENSION: {
+					GenericGIFBlock block = readGenericGIFBlock(is,
+							complete_code);
+					result.add(block);
+					break;
+				}
 
-						case 0xff : // 255 (hex 0xFF) Application Extension Label
-						{
-							byte label[] = readSubBlock(is);
-
-							if (formatCompliance != null)
-								formatCompliance.addComment(
-										"Unknown Application Extension ("
-												+ new String(label) + ")",
-										complete_code);
-
-							// if (label == new String("ICCRGBG1"))
-							{
-								// GIF's can have embedded ICC Profiles - who knew?
-							}
+				case 0xff: // 255 (hex 0xFF) Application Extension Label
+				{
+					byte label[] = readSubBlock(is);
 
-							if ((label != null) && (label.length > 0))
-							{
-								GenericGIFBlock block = readGenericGIFBlock(is,
-										complete_code, label);
-								byte bytes[] = block.appendSubBlocks();
+					if (formatCompliance != null)
+						formatCompliance.addComment(
+								"Unknown Application Extension ("
+										+ new String(label) + ")",
+								complete_code);
 
-								result.add(block);
-							}
-							break;
-						}
+					// if (label == new String("ICCRGBG1"))
+					{
+						// GIF's can have embedded ICC Profiles - who knew?
+					}
 
-						default : {
+					if ((label != null) && (label.length > 0)) {
+						GenericGIFBlock block = readGenericGIFBlock(is,
+								complete_code, label);
+						byte bytes[] = block.appendSubBlocks();
 
-							if (formatCompliance != null)
-								formatCompliance.addComment("Unknown block",
-										complete_code);
-
-							GenericGIFBlock block = readGenericGIFBlock(is,
-									complete_code);
-							result.add(block);
-							break;
-						}
+						result.add(block);
 					}
-				}
 					break;
+				}
 
-				case TERMINATOR_BYTE :
-					return result;
+				default: {
 
-				case 0x00 : // bad byte, but keep going and see what happens
+					if (formatCompliance != null)
+						formatCompliance.addComment("Unknown block",
+								complete_code);
+
+					GenericGIFBlock block = readGenericGIFBlock(is,
+							complete_code);
+					result.add(block);
 					break;
+				}
+				}
+			}
+				break;
+
+			case TERMINATOR_BYTE:
+				return result;
+
+			case 0x00: // bad byte, but keep going and see what happens
+				break;
 
-				default :
-					throw new ImageReadException("GIF: unknown code: " + code);
+			default:
+				throw new ImageReadException("GIF: unknown code: " + code);
 			}
 		}
 	}
@@ -339,8 +312,7 @@
 	private ImageDescriptor readImageDescriptor(GIFHeaderInfo ghi,
 			int blockCode, InputStream is, boolean stop_before_image_data,
 			FormatCompliance formatCompliance) throws ImageReadException,
-			IOException
-	{
+			IOException {
 		int ImageLeftPosition = read2Bytes("Image Left Position", is,
 				"Not a Valid GIF File");
 		int ImageTopPosition = read2Bytes("Image Top Position", is,
@@ -350,8 +322,7 @@
 		byte PackedFields = readByte("Packed Fields", is,
 				"Not a Valid GIF File");
 
-		if (formatCompliance != null)
-		{
+		if (formatCompliance != null) {
 			formatCompliance.checkBounds("Width", 1, ghi.logicalScreenWidth,
 					imageWidth);
 			formatCompliance.checkBounds("Height", 1, ghi.logicalScreenHeight,
@@ -386,8 +357,7 @@
 					formatCompliance);
 
 		byte imageData[] = null;
-		if (!stop_before_image_data)
-		{
+		if (!stop_before_image_data) {
 			int LZWMinimumCodeSize = is.read();
 
 			GenericGIFBlock block = readGenericGIFBlock(is, -1);
@@ -398,9 +368,7 @@
 			MyLZWDecompressor myLzwDecompressor = new MyLZWDecompressor(
 					LZWMinimumCodeSize, BYTE_ORDER_LSB);
 			imageData = myLzwDecompressor.decompress(bais, size);
-		}
-		else
-		{
+		} else {
 			int LZWMinimumCodeSize = is.read();
 			if (debug)
 				System.out.println("LZWMinimumCodeSize: " + LZWMinimumCodeSize);
@@ -416,8 +384,7 @@
 		return result;
 	}
 
-	private int simple_pow(int base, int power)
-	{
+	private int simple_pow(int base, int power) {
 		int result = 1;
 
 		for (int i = 0; i < power; i++)
@@ -426,15 +393,13 @@
 		return result;
 	}
 
-	private int convertColorTableSize(int ct_size)
-	{
+	private int convertColorTableSize(int ct_size) {
 		return 3 * simple_pow(2, ct_size + 1);
 	}
 
 	private byte[] readColorTable(InputStream is, int ct_size,
 			FormatCompliance formatCompliance) throws ImageReadException,
-			IOException
-	{
+			IOException {
 		int actual_size = convertColorTableSize(ct_size);
 
 		byte bytes[] = readByteArray("block", actual_size, is,
@@ -444,33 +409,24 @@
 	}
 
 	private GIFHeaderInfo readHeader(ByteSource byteSource)
-			throws ImageReadException, IOException
-	{
+			throws ImageReadException, IOException {
 		InputStream is = null;
-		try
-		{
+		try {
 			is = byteSource.getInputStream();
 
 			return readHeader(is, FormatCompliance.getDefault());
-		}
-		finally
-		{
-			try
-			{
+		} finally {
+			try {
 				is.close();
-			}
-			catch (Exception e)
-			{
+			} catch (Exception e) {
 				Debug.debug(e);
 			}
 
 		}
 	}
 
-	private GIFBlock findBlock(ArrayList v, int code)
-	{
-		for (int i = 0; i < v.size(); i++)
-		{
+	private GIFBlock findBlock(ArrayList v, int code) {
+		for (int i = 0; i < v.size(); i++) {
 			GIFBlock fGIFBlock = (GIFBlock) v.get(i);
 			if (fGIFBlock.blockCode == code)
 				return fGIFBlock;
@@ -480,19 +436,16 @@
 
 	private ImageContents readFile(ByteSource byteSource,
 			boolean stop_before_image_data) throws ImageReadException,
-			IOException
-	{
+			IOException {
 		return readFile(byteSource, stop_before_image_data, FormatCompliance
 				.getDefault());
 	}
 
 	private ImageContents readFile(ByteSource byteSource,
 			boolean stop_before_image_data, FormatCompliance formatCompliance)
-			throws ImageReadException, IOException
-	{
+			throws ImageReadException, IOException {
 		InputStream is = null;
-		try
-		{
+		try {
 			is = byteSource.getInputStream();
 
 			GIFHeaderInfo ghi = readHeader(is, formatCompliance);
@@ -509,16 +462,11 @@
 					blocks);
 
 			return result;
-		}
-		finally
-		{
-			try
-			{
-				//					bis.close();
+		} finally {
+			try {
+				// bis.close();
 				is.close();
-			}
-			catch (Exception e)
-			{
+			} catch (Exception e) {
 				Debug.debug(e);
 			}
 
@@ -526,15 +474,12 @@
 	}
 
 	public byte[] getICCProfileBytes(ByteSource byteSource, Map params)
-			throws ImageReadException, IOException
-	{
+			throws ImageReadException, IOException {
 		return null;
 	}
 
-	public Dimension getImageSize(ByteSource byteSource,
-			Map params)
-			throws ImageReadException, IOException
-	{
+	public Dimension getImageSize(ByteSource byteSource, Map params)
+			throws ImageReadException, IOException {
 		GIFHeaderInfo bhi = readHeader(byteSource);
 
 		if (bhi == null)
@@ -544,33 +489,27 @@
 
 	}
 
-	public byte[] embedICCProfile(byte image[], byte profile[])
-	{
+	public byte[] embedICCProfile(byte image[], byte profile[]) {
 		return null;
 	}
 
-	public boolean embedICCProfile(File src, File dst, byte profile[])
-	{
+	public boolean embedICCProfile(File src, File dst, byte profile[]) {
 		return false;
 	}
 
 	public IImageMetadata getMetadata(ByteSource byteSource, Map params)
-			throws ImageReadException, IOException
-	{
+			throws ImageReadException, IOException {
 		return null;
 	}
 
 	private ArrayList getComments(ArrayList v) throws ImageReadException,
-			IOException
-	{
+			IOException {
 		ArrayList result = new ArrayList();
 		int code = 0x21fe;
 
-		for (int i = 0; i < v.size(); i++)
-		{
+		for (int i = 0; i < v.size(); i++) {
 			GIFBlock block = (GIFBlock) v.get(i);
-			if (block.blockCode == code)
-			{
+			if (block.blockCode == code) {
 				byte bytes[] = ((GenericGIFBlock) block).appendSubBlocks();
 				result.add(new String(bytes));
 			}
@@ -580,8 +519,7 @@
 	}
 
 	public ImageInfo getImageInfo(ByteSource byteSource, Map params)
-			throws ImageReadException, IOException
-	{
+			throws ImageReadException, IOException {
 		ImageContents blocks = readFile(byteSource, false);
 
 		if (blocks == null)
@@ -625,8 +563,7 @@
 				+ ((char) blocks.gifHeaderInfo.version3);
 
 		boolean isTransparent = false;
-		if (gce != null)
-		{
+		if (gce != null) {
 			if (gce.transparency)
 				isTransparent = true;
 		}
@@ -645,8 +582,7 @@
 	}
 
 	public boolean dumpImageFile(PrintWriter pw, ByteSource byteSource)
-			throws ImageReadException, IOException
-	{
+			throws ImageReadException, IOException {
 		pw.println("gif.dumpImageFile");
 
 		{
@@ -663,8 +599,7 @@
 				return false;
 
 			pw.println("gif.blocks: " + blocks.blocks.size());
-			for (int i = 0; i < blocks.blocks.size(); i++)
-			{
+			for (int i = 0; i < blocks.blocks.size(); i++) {
 				GIFBlock fGIFBlock = (GIFBlock) blocks.blocks.get(i);
 				this.debugNumber(pw, "\t" + i + " ("
 						+ fGIFBlock.getClass().getName() + ")",
@@ -679,8 +614,7 @@
 	}
 
 	private int[] getColorTable(byte bytes[]) throws ImageReadException,
-			IOException
-	{
+			IOException {
 		if ((bytes.length % 3) != 0)
 			throw new ImageReadException("Bad Color Table Length: "
 					+ bytes.length);
@@ -688,8 +622,7 @@
 
 		int result[] = new int[length];
 
-		for (int i = 0; i < length; i++)
-		{
+		for (int i = 0; i < length; i++) {
 			int red = 0xff & bytes[(i * 3) + 0];
 			int green = 0xff & bytes[(i * 3) + 1];
 			int blue = 0xff & bytes[(i * 3) + 2];
@@ -704,8 +637,7 @@
 	}
 
 	public FormatCompliance getFormatCompliance(ByteSource byteSource)
-			throws ImageReadException, IOException
-	{
+			throws ImageReadException, IOException {
 		FormatCompliance result = new FormatCompliance(byteSource
 				.getDescription());
 
@@ -715,8 +647,7 @@
 	}
 
 	public BufferedImage getBufferedImage(ByteSource byteSource, Map params)
-			throws ImageReadException, IOException
-	{
+			throws ImageReadException, IOException {
 		ImageContents imageContents = readFile(byteSource, false);
 
 		if (imageContents == null)
@@ -753,11 +684,12 @@
 			if (gce.transparency)
 				transparentIndex = gce.transparentColorIndex;
 
-			//			Debug.debug("charles TransparentIndex", TransparentIndex);
+			// Debug.debug("charles TransparentIndex", TransparentIndex);
 
 			int counter = 0;
-			//			ByteArrayInputStream bais = new ByteArrayInputStream(id.ImageData);
-			//			for (int y = 0; y < height; y++)
+			// ByteArrayInputStream bais = new
+			// ByteArrayInputStream(id.ImageData);
+			// for (int y = 0; y < height; y++)
 
 			int rows_in_pass_1 = (height + 7) / 8;
 			int rows_in_pass_2 = (height + 3) / 8;
@@ -766,27 +698,22 @@
 
 			DataBuffer db = result.getRaster().getDataBuffer();
 
-			for (int row = 0; row < height; row++)
-			{
+			for (int row = 0; row < height; row++) {
 
 				int y;
-				if (id.interlaceFlag)
-				{
+				if (id.interlaceFlag) {
 					int the_row = row;
 					if (the_row < rows_in_pass_1)
 						y = the_row * 8;
-					else
-					{
+					else {
 						the_row -= rows_in_pass_1;
 						if (the_row < (rows_in_pass_2))
 							y = 4 + (the_row * 8);
-						else
-						{
+						else {
 							the_row -= rows_in_pass_2;
 							if (the_row < (rows_in_pass_3))
 								y = 2 + (the_row * 4);
-							else
-							{
+							else {
 								the_row -= rows_in_pass_3;
 								if (the_row < (rows_in_pass_4))
 									y = 1 + (the_row * 2);
@@ -796,13 +723,11 @@
 							}
 						}
 					}
-					//					System.out.println("row(" + row + "): " + y);
-				}
-				else
+					// System.out.println("row(" + row + "): " + y);
+				} else
 					y = row;
 
-				for (int x = 0; x < width; x++)
-				{
+				for (int x = 0; x < width; x++) {
 
 					int index = 0xff & id.imageData[counter++];
 					int rgb = colortable[index];
@@ -821,12 +746,10 @@
 	}
 
 	private void writeAsSubBlocks(OutputStream os, byte bytes[])
-			throws IOException
-	{
+			throws IOException {
 		int index = 0;
 
-		while (index < bytes.length)
-		{
+		while (index < bytes.length) {
 			int block_size = Math.min(bytes.length - index, 255);
 			os.write(block_size);
 			os.write(bytes, index, block_size);
@@ -840,17 +763,20 @@
 	private static final int SORT_FLAG_MASK = 1 << 5;
 
 	public void writeImage(BufferedImage src, OutputStream os, Map params)
-			throws ImageWriteException, IOException
-	{
+			throws ImageWriteException, IOException {
 		// make copy of params; we'll clear keys as we consume them.
 		params = new HashMap(params);
 
+		boolean verbose = ParamMap.getParamBoolean(params, PARAM_KEY_VERBOSE,
+				false);
+
 		// clear format key.
 		if (params.containsKey(PARAM_KEY_FORMAT))
 			params.remove(PARAM_KEY_FORMAT);
+		if (params.containsKey(PARAM_KEY_VERBOSE))
+			params.remove(PARAM_KEY_VERBOSE);
 
-		if (params.size() > 0)
-		{
+		if (params.size() > 0) {
 			Object firstKey = params.keySet().iterator().next();
 			throw new ImageWriteException("Unknown parameter: " + firstKey);
 		}
@@ -864,16 +790,15 @@
 
 		Palette palette2 = new PaletteFactory().makePaletteSimple(src,
 				max_colors);
-		//		int palette[] = new PaletteFactory().makePaletteSimple(src, 256);
-		//		Map palette_map = paletteToMap(palette);
+		// int palette[] = new PaletteFactory().makePaletteSimple(src, 256);
+		// Map palette_map = paletteToMap(palette);
 
-		if (palette2 == null)
-		{
+		if (palette2 == null) {
 			palette2 = new PaletteFactory().makePaletteQuantized(src,
 					max_colors);
-			System.out.println("quantizing");
-		}
-		else
+			if (verbose)
+				System.out.println("quantizing");
+		} else if (verbose)
 			System.out.println("exact palette");
 
 		if (palette2 == null)
@@ -898,14 +823,10 @@
 			bos.write2Bytes(width);
 			bos.write2Bytes(height);
 
-			int colorTableScaleLessOne = (palette_size > 128)
-					? 7
-					: (palette_size > 64) ? 6 : (palette_size > 32)
-							? 5
-							: (palette_size > 16) ? 4 : (palette_size > 8)
-									? 3
-									: (palette_size > 4)
-											? 2
+			int colorTableScaleLessOne = (palette_size > 128) ? 7
+					: (palette_size > 64) ? 6 : (palette_size > 32) ? 5
+							: (palette_size > 16) ? 4 : (palette_size > 8) ? 3
+									: (palette_size > 4) ? 2
 											: (palette_size > 2) ? 1 : 0;
 
 			int colorTableSizeInFormat = 1 << (colorTableScaleLessOne + 1);
@@ -919,8 +840,7 @@
 				int sortFlagMask = 8;
 				int sizeOfGlobalColorTable = 0;
 
-				int packedFields = ((globalColorTableFlag
-						? globalColorTableFlagMask
+				int packedFields = ((globalColorTableFlag ? globalColorTableFlagMask
 						: 0)
 						| (sortFlag ? sortFlagMask : 0)
 						| ((7 & colorResolution) << 4) | (7 & sizeOfGlobalColorTable));
@@ -939,40 +859,40 @@
 
 			}
 
-			if (hasAlpha)
-			{ // write GraphicControlExtension
+			if (hasAlpha) { // write GraphicControlExtension
 				bos.write((byte) 0x21);
 				bos.write((byte) 0xf9);
-				//				bos.write(0xff & (kGraphicControlExtension >> 8));
-				//				bos.write(0xff & (kGraphicControlExtension >> 0));
+				// bos.write(0xff & (kGraphicControlExtension >> 8));
+				// bos.write(0xff & (kGraphicControlExtension >> 0));
 
 				bos.write((byte) 4); // block size;
 				int fPackedFields = hasAlpha ? 1 : 0; // transparency flag
 				bos.write((byte) fPackedFields);
-				bos.write((byte) 0); //  Delay Time
-				bos.write((byte) 0); //  Delay Time
-				bos.write((byte) (hasAlpha ? palette2.length() : 0)); //   Transparent Color Index
+				bos.write((byte) 0); // Delay Time
+				bos.write((byte) 0); // Delay Time
+				bos.write((byte) (hasAlpha ? palette2.length() : 0)); // Transparent
+				// Color
+				// Index
 				bos.write((byte) 0); // terminator
 			}
 
-			{ //  Image Descriptor.
+			{ // Image Descriptor.
 				bos.write(IMAGE_SEPARATOR);
 				bos.write2Bytes(0); // Image Left Position
-				bos.write2Bytes(0); //  Image Top Position
+				bos.write2Bytes(0); // Image Top Position
 				bos.write2Bytes(width); // Image Width
-				bos.write2Bytes(height); //  Image Height
+				bos.write2Bytes(height); // Image Height
 
 				{
 					boolean LocalColorTableFlag = true;
-					//					boolean LocalColorTableFlag = false;
+					// boolean LocalColorTableFlag = false;
 					boolean InterlaceFlag = false;
 					boolean SortFlag = false;
 					int SizeOfLocalColorTable = colorTableScaleLessOne;
 
-					//					int SizeOfLocalColorTable = 0;
+					// int SizeOfLocalColorTable = 0;
 
-					int PackedFields = ((LocalColorTableFlag
-							? LOCAL_COLOR_TABLE_FLAG_MASK
+					int PackedFields = ((LocalColorTableFlag ? LOCAL_COLOR_TABLE_FLAG_MASK
 							: 0)
 							| (InterlaceFlag ? INTERLACE_FLAG_MASK : 0)
 							| (SortFlag ? SORT_FLAG_MASK : 0) | (7 & SizeOfLocalColorTable));
@@ -981,10 +901,8 @@
 			}
 
 			{ // write Local Color Table.
-				for (int i = 0; i < colorTableSizeInFormat; i++)
-				{
-					if (i < palette2.length())
-					{
+				for (int i = 0; i < colorTableSizeInFormat; i++) {
+					if (i < palette2.length()) {
 						int rgb = palette2.getEntry(i);
 
 						int red = 0xff & (rgb >> 16);
@@ -994,9 +912,7 @@
 						bos.write(red);
 						bos.write(green);
 						bos.write(blue);
-					}
-					else
-					{
+					} else {
 						bos.write(0);
 						bos.write(0);
 						bos.write(0);
@@ -1007,32 +923,32 @@
 			{ // get Image Data.
 				int image_data_total = 0;
 
-				int LZWMinimumCodeSize = colorTableScaleLessOne + 1; // TODO: make better choice here.
+				int LZWMinimumCodeSize = colorTableScaleLessOne + 1; // TODO:
+				// make
+				// better
+				// choice
+				// here.
 				bos.write(LZWMinimumCodeSize);
 
 				MyLZWCompressor compressor = new MyLZWCompressor(
-						LZWMinimumCodeSize, BYTE_ORDER_LSB, false); // GIF Mode);
+						LZWMinimumCodeSize, BYTE_ORDER_LSB, false); // GIF
+				// Mode);
 
 				byte imagedata[] = new byte[width * height];
-				for (int y = 0; y < height; y++)
-				{
-					for (int x = 0; x < width; x++)
-					{
+				for (int y = 0; y < height; y++) {
+					for (int x = 0; x < width; x++) {
 						int argb = src.getRGB(x, y);
 						int rgb = 0xffffff & argb;
 						int index;
 
-						if (hasAlpha)
-						{
+						if (hasAlpha) {
 							int alpha = 0xff & (argb >> 24);
 							final int alphaThreshold = 255;
 							if (alpha < alphaThreshold)
 								index = palette2.length(); // is transparent
 							else
 								index = palette2.getPaletteIndex(rgb);
-						}
-						else
-						{
+						} else {
 							index = palette2.getPaletteIndex(rgb);
 						}
 
@@ -1045,7 +961,7 @@
 				image_data_total += compressed.length;
 			}
 
-			palette2.dump();
+//			palette2.dump();
 
 			bos.write(TERMINATOR_BYTE);
 		}

Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/BitParser.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/BitParser.java?rev=677073&r1=677072&r2=677073&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/BitParser.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/BitParser.java Tue Jul 15 15:31:25 2008
@@ -19,70 +19,57 @@
 import java.io.IOException;
 
 import org.apache.sanselan.ImageReadException;
+import org.apache.sanselan.util.Debug;
 
 public class BitParser
 {
 	private final byte bytes[];
-	private final int BitsPerPixel;
-	private final int BitDepth;
+	private final int bitsPerPixel;
+	private final int bitDepth;
 
-	public BitParser(byte bytes[], int BitsPerPixel, int BitDepth)
+	public BitParser(byte bytes[], int bitsPerPixel, int bitDepth)
 	{
 		this.bytes = bytes;
-		this.BitsPerPixel = BitsPerPixel;
-		this.BitDepth = BitDepth;
+		this.bitsPerPixel = bitsPerPixel;
+		this.bitDepth = bitDepth;
 	}
 
-	public int getSample(int pixel_index_in_scanline, int SampleIndex)
+	public int getSample(int pixelIndexInScanline, int sampleIndex)
 			throws ImageReadException, IOException
 	{
-		int pixel_index_bits = BitsPerPixel * pixel_index_in_scanline;
-		int sample_index_bits = pixel_index_bits + (SampleIndex * BitDepth);
-		//		int sample_index_bytes = sample_index_bits / 8;
-		int sample_index_bytes = sample_index_bits >> 3;
-		//		int sample_index_bytes = pixel_index_bits / 8;
-
-		//		System.out.println("sample_index_bytes: " + sample_index_bytes);
-
-		if (BitDepth == 8)
-			return 0xff & bytes[sample_index_bytes];
-		else if (BitDepth < 8)
+		int pixelIndexBits = bitsPerPixel * pixelIndexInScanline;
+		int sampleIndexBits = pixelIndexBits + (sampleIndex * bitDepth);
+		int sampleIndexBytes = sampleIndexBits >> 3;
+
+		if (bitDepth == 8)
+			return 0xff & bytes[sampleIndexBytes];
+		else if (bitDepth < 8)
 		{
-			int b = 0xff & bytes[sample_index_bytes];
-			//			int bits_to_shift = 8 - ((pixel_index_bits % 8) + BitsPerPixel);
-			int bits_to_shift = 8 - ((pixel_index_bits & 7) + BitDepth);
-			//			int bits_to_shift = 8 - ((pixel_index_bits % 8) + BitDepth);
-			b >>= bits_to_shift;
+			int b = 0xff & bytes[sampleIndexBytes];
+			int bitsToShift = 8 - ((pixelIndexBits & 7) + bitDepth);
+			b >>= bitsToShift;
 
-			int bitmask = (1 << BitDepth) - 1;
+			int bitmask = (1 << bitDepth) - 1;
 			return b & bitmask;
-			//			switch (BitDepth)
-			//			{
-			//				case 1 :
-			//					return b & 1;
-			//				case 2 :
-			//					return b & 3;
-			//				case 4 :
-			//					return b & 15;
-			//			}
-		}
-		else if (BitDepth == 16)
+		} else if (bitDepth == 16)
 		{
-			return ((0xff & (bytes[sample_index_bytes] << 8)) | (0xff & bytes[sample_index_bytes + 1]));
+			return (((0xff & bytes[sampleIndexBytes]) << 8) | (0xff & bytes[sampleIndexBytes + 1]));
 		}
 
-		throw new ImageReadException("PNG: bad BitDepth: " + BitDepth);
+		throw new ImageReadException("PNG: bad BitDepth: " + bitDepth);
 	}
 
-	public int getSampleAsByte(int pixel_index_in_scanline, int SampleIndex)
+	public int getSampleAsByte(int pixelIndexInScanline, int sampleIndex)
 			throws ImageReadException, IOException
 	{
-		int sample = getSample(pixel_index_in_scanline, SampleIndex);
-		int rot = 8 - BitDepth;
+		int sample = getSample(pixelIndexInScanline, sampleIndex);
+
+		int rot = 8 - bitDepth;
 		if (rot > 0)
 			sample <<= rot;
 		else if (rot < 0)
 			sample >>= -rot;
+
 		return 0xff & sample;
 	}
 }
\ No newline at end of file

Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/GammaCorrection.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/GammaCorrection.java?rev=677073&r1=677072&r2=677073&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/GammaCorrection.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/GammaCorrection.java Tue Jul 15 15:31:25 2008
@@ -20,42 +20,40 @@
 {
 	private static final boolean DEBUG = false;
 
-	//		private final double src_gamma, dst_gamma;
-	private final int lookup_table[];
+	private final int lookupTable[];
 
 	public GammaCorrection(double src_gamma, double dst_gamma)
 	{
-		//			this.src_gamma = src_gamma;
-		//			this.dst_gamma = dst_gamma;
+
 		if (DEBUG)
 		{
 			System.out.println("src_gamma: " + src_gamma);
 			System.out.println("dst_gamma: " + dst_gamma);
 		}
 
-		lookup_table = new int[256];
+		lookupTable = new int[256];
 		for (int i = 0; i < 256; i++)
 		{
-			lookup_table[i] = correctSample(i, src_gamma, dst_gamma);
+			lookupTable[i] = correctSample(i, src_gamma, dst_gamma);
 			if (DEBUG)
 			{
-				System.out.println("lookup_table[" + i + "]: "
-						+ lookup_table[i]);
+				System.out
+						.println("lookup_table[" + i + "]: " + lookupTable[i]);
 			}
 		}
 	}
 
 	public int correctSample(int sample)
 	{
-		return lookup_table[sample];
+		return lookupTable[sample];
 	}
 
 	public int correctARGB(int pixel)
 	{
 		int alpha = (0xff000000) & pixel;
-		int red = (pixel & 0xff) >> 16;
-		int green = (pixel & 0xff) >> 8;
-		int blue = (pixel & 0xff) >> 0;
+		int red = (pixel >> 16) & 0xff;
+		int green = (pixel >> 8) & 0xff;
+		int blue = (pixel >> 0) & 0xff;
 
 		red = correctSample(red);
 		green = correctSample(green);
@@ -69,12 +67,12 @@
 
 	private int correctSample(int sample, double src_gamma, double dst_gamma)
 	{
-		//			if (kUseAdobeGammaMethod && val <= 32)
-		//			{
-		//				double slope = Math.round(255.0d * Math.pow((32.0 / 255.0d),
-		//						src_gamma / dst_gamma)) / 32.d;
-		//				return (int) (sample * slope);
-		//			}
+		// if (kUseAdobeGammaMethod && val <= 32)
+		// {
+		// double slope = Math.round(255.0d * Math.pow((32.0 / 255.0d),
+		// src_gamma / dst_gamma)) / 32.d;
+		// return (int) (sample * slope);
+		// }
 
 		return (int) Math.round(255.0d * Math.pow((sample / 255.0d), src_gamma
 				/ dst_gamma));

Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngImageParser.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngImageParser.java?rev=677073&r1=677072&r2=677073&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngImageParser.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngImageParser.java Tue Jul 15 15:31:25 2008
@@ -59,13 +59,14 @@
 import org.apache.sanselan.icc.IccProfileParser;
 import org.apache.sanselan.util.Debug;
 import org.apache.sanselan.util.IOUtils;
+import org.apache.sanselan.util.ParamMap;
 
 public class PngImageParser extends ImageParser implements PngConstants
 {
 
 	public PngImageParser()
 	{
-		//		setDebug(true);
+		// setDebug(true);
 	}
 
 	public String getName()
@@ -80,9 +81,7 @@
 
 	private static final String DEFAULT_EXTENSION = ".png";
 
-	private static final String ACCEPTED_EXTENSIONS[] = {
-		DEFAULT_EXTENSION,
-	};
+	private static final String ACCEPTED_EXTENSIONS[] = { DEFAULT_EXTENSION, };
 
 	protected String[] getAcceptedExtensions()
 	{
@@ -91,16 +90,15 @@
 
 	protected ImageFormat[] getAcceptedTypes()
 	{
-		return new ImageFormat[]{
-			ImageFormat.IMAGE_FORMAT_PNG, //
+		return new ImageFormat[] { ImageFormat.IMAGE_FORMAT_PNG, //
 		};
 	}
 
-	//	private final static int tRNS = CharsToQuad('t', 'R', 'N', 's');
+	// private final static int tRNS = CharsToQuad('t', 'R', 'N', 's');
 
 	private boolean keepChunk(int ChunkType, int ChunkTypes[])
 	{
-		//		System.out.println("keepChunk: ");
+		// System.out.println("keepChunk: ");
 		if (ChunkTypes == null)
 			return true;
 
@@ -137,8 +135,7 @@
 			{
 				bytes = readByteArray("Chunk Data", length, is,
 						"Not a Valid PNG File: Couldn't read Chunk Data.");
-			}
-			else
+			} else
 				skipBytes(is, length, "Not a Valid PNG File");
 
 			if (debug)
@@ -203,14 +200,12 @@
 			readSignature(is);
 			chunks = readChunks(is, ChunkTypes, return_after_first);
 			return chunks;
-		}
-		finally
+		} finally
 		{
 			try
 			{
 				is.close();
-			}
-			catch (Exception e)
+			} catch (Exception e)
 			{
 				Debug.debug(e);
 			}
@@ -220,13 +215,11 @@
 	public byte[] getICCProfileBytes(ByteSource byteSource, Map params)
 			throws ImageReadException, IOException
 	{
-		ArrayList chunks = readChunks(byteSource, new int[]{
-			iCCP,
-		}, true);
+		ArrayList chunks = readChunks(byteSource, new int[] { iCCP, }, true);
 
 		if ((chunks == null) || (chunks.size() < 1))
 		{
-			//			throw new ImageReadException("Png: No chunks");
+			// throw new ImageReadException("Png: No chunks");
 			return null;
 		}
 
@@ -240,13 +233,10 @@
 		return (bytes);
 	}
 
-	public Dimension getImageSize(ByteSource byteSource,
-			Map params)
+	public Dimension getImageSize(ByteSource byteSource, Map params)
 			throws ImageReadException, IOException
 	{
-		ArrayList chunks = readChunks(byteSource, new int[]{
-			IHDR,
-		}, true);
+		ArrayList chunks = readChunks(byteSource, new int[] { IHDR, }, true);
 
 		if ((chunks == null) || (chunks.size() < 1))
 			throw new ImageReadException("Png: No chunks");
@@ -272,9 +262,8 @@
 	public IImageMetadata getMetadata(ByteSource byteSource, Map params)
 			throws ImageReadException, IOException
 	{
-		ArrayList chunks = readChunks(byteSource, new int[]{
-				tEXt, zTXt,
-		}, true);
+		ArrayList chunks = readChunks(byteSource, new int[] { tEXt, zTXt, },
+				true);
 
 		if ((chunks == null) || (chunks.size() < 1))
 			return null;
@@ -293,89 +282,97 @@
 
 	private boolean isGrayscale(int colorType) throws ImageReadException
 	{
-		//		Color type is a single-byte integer that describes the interpretation of the
-		//		image data. Color type codes represent sums of the following values:
-		//			1 (palette used), 2 (color used), and 4 (alpha channel used).
-		//			Valid values are 0, 2, 3, 4, and 6.
-		//
-		//		Bit depth restrictions for each color type are imposed to simplify implementations
-		//		and to prohibit combinations that do not compress well. Decoders must support all
-		//		valid combinations of bit depth and color type. The allowed combinations are:
-		//
-		//		   Color    Allowed    Interpretation
-		//		   Type    Bit Depths
+		// Color type is a single-byte integer that describes the interpretation
+		// of the
+		// image data. Color type codes represent sums of the following values:
+		// 1 (palette used), 2 (color used), and 4 (alpha channel used).
+		// Valid values are 0, 2, 3, 4, and 6.
+		//
+		// Bit depth restrictions for each color type are imposed to simplify
+		// implementations
+		// and to prohibit combinations that do not compress well. Decoders must
+		// support all
+		// valid combinations of bit depth and color type. The allowed
+		// combinations are:
+		//
+		// Color Allowed Interpretation
+		// Type Bit Depths
+		//
+		// 0 1,2,4,8,16 Each pixel is a grayscale sample.
+		//
+		// 2 8,16 Each pixel is an R,G,B triple.
 		//
-		//		   0       1,2,4,8,16  Each pixel is a grayscale sample.
+		// 3 1,2,4,8 Each pixel is a palette index;
+		// a PLTE chunk must appear.
 		//
-		//		   2       8,16        Each pixel is an R,G,B triple.
+		// 4 8,16 Each pixel is a grayscale sample,
+		// followed by an alpha sample.
 		//
-		//		   3       1,2,4,8     Each pixel is a palette index;
-		//		                       a PLTE chunk must appear.
-		//
-		//		   4       8,16        Each pixel is a grayscale sample,
-		//		                       followed by an alpha sample.
-		//
-		//		   6       8,16        Each pixel is an R,G,B triple,
-		//		                       followed by an alpha sample.
+		// 6 8,16 Each pixel is an R,G,B triple,
+		// followed by an alpha sample.
 		switch (colorType)
 		{
-			case COLOR_TYPE_GREYSCALE :
-				return true;
-			case COLOR_TYPE_TRUE_COLOR :
-				return false;
-			case COLOR_TYPE_INDEXED_COLOR :
-				return false;
-			case COLOR_TYPE_GREYSCALE_WITH_ALPHA :
-				return true;
-			case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA :
-				return false;
+		case COLOR_TYPE_GREYSCALE:
+			return true;
+		case COLOR_TYPE_TRUE_COLOR:
+			return false;
+		case COLOR_TYPE_INDEXED_COLOR:
+			return false;
+		case COLOR_TYPE_GREYSCALE_WITH_ALPHA:
+			return true;
+		case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA:
+			return false;
 		}
 
-		//		return -1;
+		// return -1;
 		throw new ImageReadException("PNG: unknown color type: " + colorType);
 	}
 
 	private int samplesPerPixel(int colorType) throws ImageReadException
 	{
-		//		Color type is a single-byte integer that describes the interpretation of the
-		//		image data. Color type codes represent sums of the following values:
-		//			1 (palette used), 2 (color used), and 4 (alpha channel used).
-		//			Valid values are 0, 2, 3, 4, and 6.
+		// Color type is a single-byte integer that describes the interpretation
+		// of the
+		// image data. Color type codes represent sums of the following values:
+		// 1 (palette used), 2 (color used), and 4 (alpha channel used).
+		// Valid values are 0, 2, 3, 4, and 6.
+		//
+		// Bit depth restrictions for each color type are imposed to simplify
+		// implementations
+		// and to prohibit combinations that do not compress well. Decoders must
+		// support all
+		// valid combinations of bit depth and color type. The allowed
+		// combinations are:
+		//
+		// Color Allowed Interpretation
+		// Type Bit Depths
+		//
+		// 0 1,2,4,8,16 Each pixel is a grayscale sample.
+		//
+		// 2 8,16 Each pixel is an R,G,B triple.
 		//
-		//		Bit depth restrictions for each color type are imposed to simplify implementations
-		//		and to prohibit combinations that do not compress well. Decoders must support all
-		//		valid combinations of bit depth and color type. The allowed combinations are:
+		// 3 1,2,4,8 Each pixel is a palette index;
+		// a PLTE chunk must appear.
 		//
-		//		   Color    Allowed    Interpretation
-		//		   Type    Bit Depths
+		// 4 8,16 Each pixel is a grayscale sample,
+		// followed by an alpha sample.
 		//
-		//		   0       1,2,4,8,16  Each pixel is a grayscale sample.
-		//
-		//		   2       8,16        Each pixel is an R,G,B triple.
-		//
-		//		   3       1,2,4,8     Each pixel is a palette index;
-		//		                       a PLTE chunk must appear.
-		//
-		//		   4       8,16        Each pixel is a grayscale sample,
-		//		                       followed by an alpha sample.
-		//
-		//		   6       8,16        Each pixel is an R,G,B triple,
-		//		                       followed by an alpha sample.
+		// 6 8,16 Each pixel is an R,G,B triple,
+		// followed by an alpha sample.
 		switch (colorType)
 		{
-			case COLOR_TYPE_GREYSCALE :
-				return 1;
-			case COLOR_TYPE_TRUE_COLOR :
-				return 3;
-			case COLOR_TYPE_INDEXED_COLOR :
-				return 1; // is this accurate ?  how may bits per index?
-			case COLOR_TYPE_GREYSCALE_WITH_ALPHA :
-				return 2;
-			case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA :
-				return 4;
+		case COLOR_TYPE_GREYSCALE:
+			return 1;
+		case COLOR_TYPE_TRUE_COLOR:
+			return 3;
+		case COLOR_TYPE_INDEXED_COLOR:
+			return 1; // is this accurate ? how may bits per index?
+		case COLOR_TYPE_GREYSCALE_WITH_ALPHA:
+			return 2;
+		case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA:
+			return 4;
 		}
 
-		//		return -1;
+		// return -1;
 		throw new ImageReadException("PNG: unknown color type: " + colorType);
 	}
 
@@ -398,18 +395,21 @@
 	{
 		switch (ColorType)
 		{
-			case COLOR_TYPE_GREYSCALE : //       1,2,4,8,16  Each pixel is a grayscale sample.
-			case COLOR_TYPE_TRUE_COLOR : //     8,16        Each pixel is an R,G,B triple.
-			case COLOR_TYPE_INDEXED_COLOR : //     1,2,4,8     Each pixel is a palette index;
-				return false;
-			case COLOR_TYPE_GREYSCALE_WITH_ALPHA : //     8,16        Each pixel is a grayscale sample,
-				//					                       followed by an alpha sample.
-			case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA : //    8,16        Each pixel is an R,G,B triple,
-				//					                       followed by an alpha sample.
-				return true;
-			default :
-				throw new ImageReadException("PNG: unknown color type: "
-						+ ColorType);
+		case COLOR_TYPE_GREYSCALE: // 1,2,4,8,16 Each pixel is a grayscale
+			// sample.
+		case COLOR_TYPE_TRUE_COLOR: // 8,16 Each pixel is an R,G,B triple.
+		case COLOR_TYPE_INDEXED_COLOR: // 1,2,4,8 Each pixel is a palette index;
+			return false;
+		case COLOR_TYPE_GREYSCALE_WITH_ALPHA: // 8,16 Each pixel is a grayscale
+			// sample,
+			// followed by an alpha sample.
+		case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA: // 8,16 Each pixel is an R,G,B
+			// triple,
+			// followed by an alpha sample.
+			return true;
+		default:
+			throw new ImageReadException("PNG: unknown color type: "
+					+ ColorType);
 		}
 	}
 
@@ -417,58 +417,64 @@
 	{
 		switch (ColorType)
 		{
-			case COLOR_TYPE_GREYSCALE : //       1,2,4,8,16  Each pixel is a grayscale sample.
-				return "grayscale";
-			case COLOR_TYPE_TRUE_COLOR : //     8,16        Each pixel is an R,G,B triple.
-				return "rgb";
-			case COLOR_TYPE_INDEXED_COLOR : //     1,2,4,8     Each pixel is a palette index;
-				return "indexed rgb";
-			case COLOR_TYPE_GREYSCALE_WITH_ALPHA : //     8,16        Each pixel is a grayscale sample,
-				//					                       followed by an alpha sample.
-				return "grayscale w/ alpha";
-			case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA : //    8,16        Each pixel is an R,G,B triple,
-				//					                       followed by an alpha sample.
-				return "RGB w/ alpha";
-			default :
-				return "Unknown Color Type";
+		case COLOR_TYPE_GREYSCALE: // 1,2,4,8,16 Each pixel is a grayscale
+			// sample.
+			return "grayscale";
+		case COLOR_TYPE_TRUE_COLOR: // 8,16 Each pixel is an R,G,B triple.
+			return "rgb";
+		case COLOR_TYPE_INDEXED_COLOR: // 1,2,4,8 Each pixel is a palette index;
+			return "indexed rgb";
+		case COLOR_TYPE_GREYSCALE_WITH_ALPHA: // 8,16 Each pixel is a grayscale
+			// sample,
+			// followed by an alpha sample.
+			return "grayscale w/ alpha";
+		case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA: // 8,16 Each pixel is an R,G,B
+			// triple,
+			// followed by an alpha sample.
+			return "RGB w/ alpha";
+		default:
+			return "Unknown Color Type";
 		}
 	}
 
-	// TODO: I have been too casual about making inner classes subclass of BinaryFileParser
+	// TODO: I have been too casual about making inner classes subclass of
+	// BinaryFileParser
 	// I may not have always preserved byte order correctly.
 
 	private TransparencyFilter getTransparencyFilter(int ColorType,
 			PNGChunk pngChunktRNS) throws ImageReadException, IOException
 	{
-		//		this.printCharQuad("pngChunktRNS.ChunkType", pngChunktRNS.ChunkType);
-		//		this.debugNumber("pngChunktRNS.Length", pngChunktRNS.Length);
+		// this.printCharQuad("pngChunktRNS.ChunkType", pngChunktRNS.ChunkType);
+		// this.debugNumber("pngChunktRNS.Length", pngChunktRNS.Length);
 
 		switch (ColorType)
 		{
-			case COLOR_TYPE_GREYSCALE : //       1,2,4,8,16  Each pixel is a grayscale sample.
-				return new TransparencyFilterGrayscale(pngChunktRNS.bytes);
-			case COLOR_TYPE_TRUE_COLOR : //     8,16        Each pixel is an R,G,B triple.
-				return new TransparencyFilterTrueColor(pngChunktRNS.bytes);
-			case COLOR_TYPE_INDEXED_COLOR : //     1,2,4,8     Each pixel is a palette index;
-				return new TransparencyFilterIndexedColor(pngChunktRNS.bytes);
-			case COLOR_TYPE_GREYSCALE_WITH_ALPHA : //     8,16        Each pixel is a grayscale sample,
-			case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA : //    8,16        Each pixel is an R,G,B triple,
-			default :
-				throw new ImageReadException(
-						"Simple Transparency not compatible with ColorType: "
-								+ ColorType);
+		case COLOR_TYPE_GREYSCALE: // 1,2,4,8,16 Each pixel is a grayscale
+			// sample.
+			return new TransparencyFilterGrayscale(pngChunktRNS.bytes);
+		case COLOR_TYPE_TRUE_COLOR: // 8,16 Each pixel is an R,G,B triple.
+			return new TransparencyFilterTrueColor(pngChunktRNS.bytes);
+		case COLOR_TYPE_INDEXED_COLOR: // 1,2,4,8 Each pixel is a palette index;
+			return new TransparencyFilterIndexedColor(pngChunktRNS.bytes);
+		case COLOR_TYPE_GREYSCALE_WITH_ALPHA: // 8,16 Each pixel is a grayscale
+			// sample,
+		case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA: // 8,16 Each pixel is an R,G,B
+			// triple,
+		default:
+			throw new ImageReadException(
+					"Simple Transparency not compatible with ColorType: "
+							+ ColorType);
 		}
 	}
 
 	public ImageInfo getImageInfo(ByteSource byteSource, Map params)
 			throws ImageReadException, IOException
 	{
-		ArrayList chunks = readChunks(byteSource, new int[]{
-				IHDR, pHYs, tEXt, zTXt, tRNS, PLTE,
-		}, false);
+		ArrayList chunks = readChunks(byteSource, new int[] { IHDR, pHYs, tEXt,
+				zTXt, tRNS, PLTE, }, false);
 
-		//		if(chunks!=null)
-		//		System.out.println("chunks: " + chunks.size());
+		// if(chunks!=null)
+		// System.out.println("chunks: " + chunks.size());
 
 		if ((chunks == null) || (chunks.size() < 1))
 			throw new ImageReadException("PNG: no chunks");
@@ -487,8 +493,7 @@
 		{
 			isTransparent = true;
 			pngChunktRNS = (PNGChunk) IHDRs.get(0);
-		}
-		else
+		} else
 			hasAlphaChannel(pngChunkIHDR.colorType);
 
 		PNGChunkpHYs pngChunkpHYs = null;
@@ -503,22 +508,22 @@
 		ArrayList tEXts = filterChunks(chunks, tEXt);
 		ArrayList zTXts = filterChunks(chunks, zTXt);
 
-		//			private class PNGChunkpHYs extends PNGChunk
-		//			{
-		//				public final int PixelsPerUnitXAxis;
-		//				public final int PixelsPerUnitYAxis;
-		//				public final int UnitSpecifier;
-
-		{
-			//			private class PNGChunkIHDR extends PNGChunk
-			//			{
-			//				public final int Width;
-			//				public final int Height;
-			//				public final int BitDepth;
-			//				public final int ColorType;
-			//				public final int CompressionMethod;
-			//				public final int FilterMethod;
-			//				public final int InterlaceMethod;
+		// private class PNGChunkpHYs extends PNGChunk
+		// {
+		// public final int PixelsPerUnitXAxis;
+		// public final int PixelsPerUnitYAxis;
+		// public final int UnitSpecifier;
+
+		{
+			// private class PNGChunkIHDR extends PNGChunk
+			// {
+			// public final int Width;
+			// public final int Height;
+			// public final int BitDepth;
+			// public final int ColorType;
+			// public final int CompressionMethod;
+			// public final int FilterMethod;
+			// public final int InterlaceMethod;
 
 			ArrayList Comments = new ArrayList();
 
@@ -548,12 +553,15 @@
 			int PhysicalWidthDpi = -1;
 			float PhysicalWidthInch = -1;
 
-			//			if (pngChunkpHYs != null)
-			//			{
-			//				System.out.println("\t" + "pngChunkpHYs.UnitSpecifier: " + pngChunkpHYs.UnitSpecifier );
-			//				System.out.println("\t" + "pngChunkpHYs.PixelsPerUnitYAxis: " + pngChunkpHYs.PixelsPerUnitYAxis );
-			//				System.out.println("\t" + "pngChunkpHYs.PixelsPerUnitXAxis: " + pngChunkpHYs.PixelsPerUnitXAxis );
-			//			}
+			// if (pngChunkpHYs != null)
+			// {
+			// System.out.println("\t" + "pngChunkpHYs.UnitSpecifier: " +
+			// pngChunkpHYs.UnitSpecifier );
+			// System.out.println("\t" + "pngChunkpHYs.PixelsPerUnitYAxis: " +
+			// pngChunkpHYs.PixelsPerUnitYAxis );
+			// System.out.println("\t" + "pngChunkpHYs.PixelsPerUnitXAxis: " +
+			// pngChunkpHYs.PixelsPerUnitXAxis );
+			// }
 			if ((pngChunkpHYs != null) && (pngChunkpHYs.UnitSpecifier == 1)) // meters
 			{
 				double meters_per_inch = 0.0254;
@@ -581,20 +589,24 @@
 			int ColorType;
 			switch (pngChunkIHDR.colorType)
 			{
-				case COLOR_TYPE_GREYSCALE : //       1,2,4,8,16  Each pixel is a grayscale sample.
-				case COLOR_TYPE_GREYSCALE_WITH_ALPHA : //     8,16        Each pixel is a grayscale sample,
-					//					                       followed by an alpha sample.
-					ColorType = ImageInfo.COLOR_TYPE_GRAYSCALE;
-					break;
-				case COLOR_TYPE_TRUE_COLOR : //     8,16        Each pixel is an R,G,B triple.
-				case COLOR_TYPE_INDEXED_COLOR : //     1,2,4,8     Each pixel is a palette index;
-				case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA : //    8,16        Each pixel is an R,G,B triple,
-					//					                       followed by an alpha sample.
-					ColorType = ImageInfo.COLOR_TYPE_RGB;
-					break;
-				default :
-					throw new ImageReadException("Png: Unknown ColorType: "
-							+ pngChunkIHDR.colorType);
+			case COLOR_TYPE_GREYSCALE: // 1,2,4,8,16 Each pixel is a grayscale
+				// sample.
+			case COLOR_TYPE_GREYSCALE_WITH_ALPHA: // 8,16 Each pixel is a
+				// grayscale sample,
+				// followed by an alpha sample.
+				ColorType = ImageInfo.COLOR_TYPE_GRAYSCALE;
+				break;
+			case COLOR_TYPE_TRUE_COLOR: // 8,16 Each pixel is an R,G,B triple.
+			case COLOR_TYPE_INDEXED_COLOR: // 1,2,4,8 Each pixel is a palette
+				// index;
+			case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA: // 8,16 Each pixel is an
+				// R,G,B triple,
+				// followed by an alpha sample.
+				ColorType = ImageInfo.COLOR_TYPE_RGB;
+				break;
+			default:
+				throw new ImageReadException("Png: Unknown ColorType: "
+						+ pngChunkIHDR.colorType);
 			}
 
 			String compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_PNG_FILTER;
@@ -612,9 +624,20 @@
 	public BufferedImage getBufferedImage(ByteSource byteSource, Map params)
 			throws ImageReadException, IOException
 	{
-		ArrayList chunks = readChunks(byteSource, new int[]{
-				IHDR, PLTE, IDAT, tRNS, iCCP, gAMA, sRGB,
-		}, false);
+
+		boolean verbose = ParamMap.getParamBoolean(params, PARAM_KEY_VERBOSE,
+				false);
+
+		if (params.containsKey(PARAM_KEY_VERBOSE))
+			params.remove(PARAM_KEY_VERBOSE);
+
+		// if (params.size() > 0) {
+		// Object firstKey = params.keySet().iterator().next();
+		// throw new ImageWriteException("Unknown parameter: " + firstKey);
+		// }
+
+		ArrayList chunks = readChunks(byteSource, new int[] { IHDR, PLTE, IDAT,
+				tRNS, iCCP, gAMA, sRGB, }, false);
 
 		if ((chunks == null) || (chunks.size() < 1))
 			throw new ImageReadException("PNG: no chunks");
@@ -644,7 +667,7 @@
 		{
 			PNGChunkIDAT pngChunkIDAT = (PNGChunkIDAT) IDATs.get(i);
 			byte bytes[] = pngChunkIDAT.bytes;
-			//						System.out.println(i + ": bytes: " + bytes.length);
+			// System.out.println(i + ": bytes: " + bytes.length);
 			baos.write(bytes);
 		}
 
@@ -680,8 +703,7 @@
 				// no color management neccesary.
 				if (debug)
 					System.out.println("sRGB, no color management neccesary.");
-			}
-			else if (iCCPs.size() == 1)
+			} else if (iCCPs.size() == 1)
 			{
 				if (debug)
 					System.out.println("iCCP.");
@@ -690,16 +712,13 @@
 				byte bytes[] = pngChunkiCCP.UncompressedProfile;
 
 				icc_profile = ICC_Profile.getInstance(bytes);
-			}
-			else if (gAMAs.size() == 1)
+			} else if (gAMAs.size() == 1)
 			{
 				PNGChunkgAMA pngChunkgAMA = (PNGChunkgAMA) gAMAs.get(0);
 				double gamma = pngChunkgAMA.getGamma();
-				//				if (debug)
-				//				System.out.println("gamma: " + gamma);
 
 				// charles: what is the correct target value here?
-				//				double targetGamma = 2.2;
+				// double targetGamma = 2.2;
 				double targetGamma = 1.0;
 				double diff = Math.abs(targetGamma - gamma);
 				if (diff >= 0.5)
@@ -718,115 +737,16 @@
 			int colorType = pngChunkIHDR.colorType;
 			int bitDepth = pngChunkIHDR.bitDepth;
 
-			//			System.out.println("color_type: " + color_type);
-			//			System.out.println("BitDepth: " + BitDepth);
-
-			//			int transfer_type;
-			//			int BytesPerSample;
 			int bitsPerSample = bitDepth;
 
 			if (pngChunkIHDR.filterMethod != 0)
 				throw new ImageReadException("PNG: unknown FilterMethod: "
 						+ pngChunkIHDR.filterMethod);
 
-			//			transfer_type = DataBuffer.TYPE_BYTE;
-			//			switch (BitDepth)
-			//			{
-			//				case 1 :
-			//				case 2 :
-			//				case 4 :
-			//				case 8 :
-			//					transfer_type = DataBuffer.TYPE_BYTE;
-			//					//					BytesPerSample = 1;
-			//					break;
-			//				case 16 :
-			//					transfer_type = DataBuffer.TYPE_INT;
-			//					//					BytesPerSample = 2;
-			//					break;
-			//				default :
-			//					throw new ImageReadException("PNG: unknown bit depth: " + BitDepth);
-			//			}
-
-			//			ColorModel cm = null;
 			int samplesPerPixel = samplesPerPixel(pngChunkIHDR.colorType);
 			boolean isGrayscale = isGrayscale(pngChunkIHDR.colorType);
 
-			//			switch (colorType)
-			//			{
-			//				case 0 : //       1,2,4,8,16  Each pixel is a grayscale sample.
-			//				{
-			//					ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
-			//
-			//					//					BytesPerPixel = getBytesPerPixel( BitsPerSample,  SamplesPerPixel);
-			//					//					BytesPerPixel = BytesPerSample * SamplesPerPixel;
-			//					cm = new ComponentColorModel(cs, true, false,
-			//							ColorModel.TRANSLUCENT, transfer_type);
-			//					break;
-			//				}
-			//				case 2 : //     8,16        Each pixel is an R,G,B triple.
-			//				{
-			//					ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
-			//
-			//					//					BytesPerPixel = getBytesPerPixel( BitsPerSample,  SamplesPerPixel);
-			//					//					BytesPerPixel = BytesPerSample * SamplesPerPixel;
-			//					cm = new ComponentColorModel(cs, true, false,
-			//							ColorModel.TRANSLUCENT, transfer_type);
-			//					//										cm = ColorModel.getRGBdefault();
-			//					break;
-			//				}
-			//					//
-			//				case 3 : //     1,2,4,8     Each pixel is a palette index;
-			//					//					                       a PLTE chunk must appear.
-			//				{
-			//					ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
-			//
-			//					//					BytesPerPixel = getBytesPerPixel( BitsPerSample,  SamplesPerPixel);
-			//					//					BytesPerPixel = BytesPerSample * SamplesPerPixel;
-			//					cm = new ComponentColorModel(cs, true, false,
-			//							ColorModel.TRANSLUCENT, transfer_type);
-			//					//										cm = ColorModel.getRGBdefault();
-			//
-			//					//					SamplesPerPixel = 1;
-			//					//					//					bits_per_pixel = 8;
-			//					//					//					BytesPerPixel = 1;
-			//					//					cm = ColorModel.getRGBdefault();
-			//					//					//					ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
-			//					//					//					cm = new ComponentColorModel(cs, false, false,
-			//					//					//							ColorModel.OPAQUE, transfer_type);
-			//					break;
-			//				}
-			//				case 4 : //     8,16        Each pixel is a grayscale sample,
-			//					//					                       followed by an alpha sample.
-			//				{
-			//					ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
-			//
-			//					//					BytesPerPixel = getBytesPerPixel( BitsPerSample,  SamplesPerPixel);
-			//					//					BytesPerPixel = BytesPerSample * SamplesPerPixel;
-			//					cm = new ComponentColorModel(cs, true, false,
-			//							ColorModel.TRANSLUCENT, transfer_type);
-			//					break;
-			//				}
-			//				case 6 : //    8,16        Each pixel is an R,G,B triple,
-			//				{
-			//					ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
-			//
-			//					//					BytesPerPixel = getBytesPerPixel( BitsPerSample,  SamplesPerPixel);
-			//					//					BytesPerPixel = BytesPerSample * SamplesPerPixel;
-			//					cm = new ComponentColorModel(cs, true, false,
-			//							ColorModel.TRANSLUCENT, transfer_type);
-			//					break;
-			//				}
-			//				default :
-			//					throw new ImageReadException("PNG: unknown color type: "
-			//							+ BitDepth);
-			//			}
-
-			//			cm = ColorModel.getRGBdefault();
-			//
-
 			int bitsPerPixel = bitsPerSample * samplesPerPixel;
-			//			Debug.debug("bitsPerSample", bitsPerSample);
-			//			Debug.debug("samplesPerPixel", samplesPerPixel);
 
 			boolean hasAlpha = colorType == COLOR_TYPE_GREYSCALE_WITH_ALPHA
 					|| colorType == COLOR_TYPE_TRUE_COLOR_WITH_ALPHA;
@@ -842,19 +762,6 @@
 			ByteArrayInputStream bais = new ByteArrayInputStream(compressed);
 			InflaterInputStream iis = new InflaterInputStream(bais);
 
-			byte bytes[] = IOUtils.getInputStreamBytes(iis);
-
-			bais = new ByteArrayInputStream(compressed);
-			iis = new InflaterInputStream(bais);
-
-			//			ZInputStream iis = new ZInputStream(bais);
-			//			ByteArrayInputStream iis = new ByteArrayInputStream(uncompressed);
-
-			//			int bitsPerScanLine = bitsPerPixel * width;
-
-			//			Debug.debug("bitsPerScanLine", bitsPerScanLine);
-			//			Debug.debug("bitsPerPixel", bitsPerPixel);
-
 			ScanExpediter scanExpediter;
 
 			if (pngChunkIHDR.interlaceMethod == 0)

Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngWriter.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngWriter.java?rev=677073&r1=677072&r2=677073&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngWriter.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngWriter.java Tue Jul 15 15:31:25 2008
@@ -29,51 +29,38 @@
 import org.apache.sanselan.palette.Palette;
 import org.apache.sanselan.palette.PaletteFactory;
 import org.apache.sanselan.util.Debug;
+import org.apache.sanselan.util.ParamMap;
 
-public class PngWriter implements PngConstants
-{
+public class PngWriter implements PngConstants {
 	private final boolean verbose;
 
-	public PngWriter(boolean verbose)
-	{
+	public PngWriter(boolean verbose) {
 		this.verbose = verbose;
 	}
 
-	public PngWriter(Map params)
-	{
-		this.verbose = getParamBoolean(params, PARAM_KEY_VERBOSE, false);
-	}
-
-	private boolean getParamBoolean(Map params, Object key,
-			boolean default_value)
-	{
-		boolean result = default_value;
-		{
-			Object o = params == null ? null : params.get(key);
-			if (o != null && o instanceof Boolean)
-				result = ((Boolean) o).booleanValue();
-		}
-		return result;
+	public PngWriter(Map params) {
+		this.verbose = ParamMap.getParamBoolean(params, PARAM_KEY_VERBOSE,
+				false);
 	}
 
 	/*
-	 1. IHDR: image header, which is the first chunk in a PNG datastream.
-	 2. PLTE: palette table associated with indexed PNG images.
-	 3. IDAT: image data chunks.
-	 4. IEND: image trailer, which is the last chunk in a PNG datastream.
-
-	 The remaining 14 chunk types are termed ancillary chunk types, which encoders may generate and decoders may interpret.
-
-	 1. Transparency information: tRNS (see 11.3.2: Transparency information).
-	 2. Colour space information: cHRM, gAMA, iCCP, sBIT, sRGB (see 11.3.3: Colour space information).
-	 3. Textual information: iTXt, tEXt, zTXt (see 11.3.4: Textual information).
-	 4. Miscellaneous information: bKGD, hIST, pHYs, sPLT (see 11.3.5: Miscellaneous information).
-	 5. Time information: tIME (see 11.3.6: Time stamp information).
-
+	 * 1. IHDR: image header, which is the first chunk in a PNG datastream. 2.
+	 * PLTE: palette table associated with indexed PNG images. 3. IDAT: image
+	 * data chunks. 4. IEND: image trailer, which is the last chunk in a PNG
+	 * datastream.
+	 * 
+	 * The remaining 14 chunk types are termed ancillary chunk types, which
+	 * encoders may generate and decoders may interpret.
+	 * 
+	 * 1. Transparency information: tRNS (see 11.3.2: Transparency information).
+	 * 2. Colour space information: cHRM, gAMA, iCCP, sBIT, sRGB (see 11.3.3:
+	 * Colour space information). 3. Textual information: iTXt, tEXt, zTXt (see
+	 * 11.3.4: Textual information). 4. Miscellaneous information: bKGD, hIST,
+	 * pHYs, sPLT (see 11.3.5: Miscellaneous information). 5. Time information:
+	 * tIME (see 11.3.6: Time stamp information).
 	 */
 
-	private final void writeInt(OutputStream os, int value) throws IOException
-	{
+	private final void writeInt(OutputStream os, int value) throws IOException {
 		os.write(0xff & (value >> 24));
 		os.write(0xff & (value >> 16));
 		os.write(0xff & (value >> 8));
@@ -81,16 +68,15 @@
 	}
 
 	private final void writeChunk(OutputStream os, byte chunk_type[],
-			byte data[]) throws IOException
-	{
+			byte data[]) throws IOException {
 		int data_length = data == null ? 0 : data.length;
 		writeInt(os, data_length);
 		os.write(chunk_type);
 		if (data != null)
 			os.write(data);
 
-		//		Debug.debug("writeChunk chunk_type", chunk_type);
-		//		Debug.debug("writeChunk data", data);
+		// Debug.debug("writeChunk chunk_type", chunk_type);
+		// Debug.debug("writeChunk data", data);
 
 		{
 			PngCrc png_crc = new PngCrc();
@@ -101,19 +87,18 @@
 					crc1, data, data.length);
 			int crc = (int) png_crc.finish_partial_crc(crc2);
 
-			//			Debug.debug("crc1", crc1 + " (" + Long.toHexString(crc1)
-			//					+ ")");
-			//			Debug.debug("crc2", crc2 + " (" + Long.toHexString(crc2)
-			//					+ ")");
-			//			Debug.debug("crc3", crc + " (" + Integer.toHexString(crc)
-			//					+ ")");
+			// Debug.debug("crc1", crc1 + " (" + Long.toHexString(crc1)
+			// + ")");
+			// Debug.debug("crc2", crc2 + " (" + Long.toHexString(crc2)
+			// + ")");
+			// Debug.debug("crc3", crc + " (" + Integer.toHexString(crc)
+			// + ")");
 
 			writeInt(os, crc);
 		}
 	}
 
-	private static class ImageHeader
-	{
+	private static class ImageHeader {
 		public final int width;
 		public final int height;
 		public final byte bit_depth;
@@ -124,8 +109,7 @@
 
 		public ImageHeader(int width, int height, byte bit_depth,
 				byte colorType, byte compression_method, byte filter_method,
-				byte interlace_method)
-		{
+				byte interlace_method) {
 			this.width = width;
 			this.height = height;
 			this.bit_depth = bit_depth;
@@ -138,8 +122,7 @@
 	}
 
 	private void writeChunkIHDR(OutputStream os, ImageHeader value)
-			throws IOException
-	{
+			throws IOException {
 		ByteArrayOutputStream baos = new ByteArrayOutputStream();
 		writeInt(baos, value.width);
 		writeInt(baos, value.height);
@@ -149,23 +132,21 @@
 		baos.write(0xff & value.filter_method);
 		baos.write(0xff & value.interlace_method);
 
-		//		Debug.debug("baos", baos.toByteArray());
+		// Debug.debug("baos", baos.toByteArray());
 
 		writeChunk(os, IHDR_CHUNK_TYPE, baos.toByteArray());
 	}
 
 	private void writeChunkPLTE(OutputStream os, Palette palette)
-			throws IOException
-	{
+			throws IOException {
 		int length = palette.length();
 		byte bytes[] = new byte[length * 3];
 
-		//		Debug.debug("length", length);
-		for (int i = 0; i < length; i++)
-		{
+		// Debug.debug("length", length);
+		for (int i = 0; i < length; i++) {
 			int rgb = palette.getEntry(i);
 			int index = i * 3;
-			//			Debug.debug("index", index);
+			// Debug.debug("index", index);
 			bytes[index + 0] = (byte) (0xff & (rgb >> 16));
 			bytes[index + 1] = (byte) (0xff & (rgb >> 8));
 			bytes[index + 2] = (byte) (0xff & (rgb >> 0));
@@ -174,33 +155,28 @@
 		writeChunk(os, PLTE_CHUNK_TYPE, bytes);
 	}
 
-	private void writeChunkIEND(OutputStream os) throws IOException
-	{
+	private void writeChunkIEND(OutputStream os) throws IOException {
 		writeChunk(os, IEND_CHUNK_TYPE, null);
 	}
 
 	private void writeChunkIDAT(OutputStream os, byte bytes[])
-			throws IOException
-	{
+			throws IOException {
 		writeChunk(os, IDAT_CHUNK_TYPE, bytes);
 	}
 
-	private byte getColourType(boolean hasAlpha, boolean isGrayscale)
-	{
+	private byte getColourType(boolean hasAlpha, boolean isGrayscale) {
 		byte result;
 
 		boolean index = false; // charles
 
 		if (index)
 			result = COLOR_TYPE_INDEXED_COLOR;
-		else if (isGrayscale)
-		{
+		else if (isGrayscale) {
 			if (hasAlpha)
 				result = COLOR_TYPE_GREYSCALE_WITH_ALPHA;
 			else
 				result = COLOR_TYPE_GREYSCALE;
-		}
-		else if (hasAlpha)
+		} else if (hasAlpha)
 			result = COLOR_TYPE_TRUE_COLOR_WITH_ALPHA;
 		else
 			result = COLOR_TYPE_TRUE_COLOR;
@@ -208,37 +184,33 @@
 		return result;
 	}
 
-	private byte getBitDepth(final byte colorType, Map params)
-	{
+	private byte getBitDepth(final byte colorType, Map params) {
 		byte result = 8;
 
 		Object o = params.get(PARAM_KEY_PNG_BIT_DEPTH);
-		if (o != null && o instanceof Number)
-		{
+		if (o != null && o instanceof Number) {
 			int value = ((Number) o).intValue();
-			switch (value)
-			{
-				case 1 :
-				case 2 :
-				case 4 :
-				case 8 :
-				case 16 :
-					result = (byte) value;
-				default :
+			switch (value) {
+			case 1:
+			case 2:
+			case 4:
+			case 8:
+			case 16:
+				result = (byte) value;
+			default:
 			}
-			switch (colorType)
-			{
-				case COLOR_TYPE_GREYSCALE :
-					break;
-				case COLOR_TYPE_INDEXED_COLOR :
-					result = (byte) Math.min(8, result);
-					break;
-				case COLOR_TYPE_GREYSCALE_WITH_ALPHA :
-				case COLOR_TYPE_TRUE_COLOR :
-				case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA :
-					result = (byte) Math.max(8, result);
-					break;
-				default :
+			switch (colorType) {
+			case COLOR_TYPE_GREYSCALE:
+				break;
+			case COLOR_TYPE_INDEXED_COLOR:
+				result = (byte) Math.min(8, result);
+				break;
+			case COLOR_TYPE_GREYSCALE_WITH_ALPHA:
+			case COLOR_TYPE_TRUE_COLOR:
+			case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA:
+				result = (byte) Math.max(8, result);
+				break;
+			default:
 			}
 		}
 
@@ -246,36 +218,23 @@
 	}
 
 	/*
-	 between two chunk types indicates alternatives.
-	 Table 5.3 — Chunk ordering rules Critical chunks
-	 (shall appear in this order, except PLTE is optional)
-	 Chunk name 	Multiple allowed 	Ordering constraints
-	 IHDR 	No 	Shall be first
-	 PLTE 	No 	Before first IDAT
-	 IDAT 	Yes 	Multiple IDAT chunks shall be consecutive
-	 IEND 	No 	Shall be last
-	 Ancillary chunks
-	 (need not appear in this order)
-	 Chunk name 	Multiple allowed 	Ordering constraints
-	 cHRM 	No 	Before PLTE and IDAT
-	 gAMA 	No 	Before PLTE and IDAT
-	 iCCP 	No 	Before PLTE and IDAT. If the iCCP chunk is present, the sRGB chunk should not be present.
-	 sBIT 	No 	Before PLTE and IDAT
-	 sRGB 	No 	Before PLTE and IDAT. If the sRGB chunk is present, the iCCP chunk should not be present.
-	 bKGD 	No 	After PLTE; before IDAT
-	 hIST 	No 	After PLTE; before IDAT
-	 tRNS 	No 	After PLTE; before IDAT
-	 pHYs 	No 	Before IDAT
-	 sPLT 	Yes 	Before IDAT
-	 tIME 	No 	None
-	 iTXt 	Yes 	None
-	 tEXt 	Yes 	None
-	 zTXt 	Yes 	None
+	 * between two chunk types indicates alternatives. Table 5.3 — Chunk
+	 * ordering rules Critical chunks (shall appear in this order, except PLTE
+	 * is optional) Chunk name Multiple allowed Ordering constraints IHDR No
+	 * Shall be first PLTE No Before first IDAT IDAT Yes Multiple IDAT chunks
+	 * shall be consecutive IEND No Shall be last Ancillary chunks (need not
+	 * appear in this order) Chunk name Multiple allowed Ordering constraints
+	 * cHRM No Before PLTE and IDAT gAMA No Before PLTE and IDAT iCCP No Before
+	 * PLTE and IDAT. If the iCCP chunk is present, the sRGB chunk should not be
+	 * present. sBIT No Before PLTE and IDAT sRGB No Before PLTE and IDAT. If
+	 * the sRGB chunk is present, the iCCP chunk should not be present. bKGD No
+	 * After PLTE; before IDAT hIST No After PLTE; before IDAT tRNS No After
+	 * PLTE; before IDAT pHYs No Before IDAT sPLT Yes Before IDAT tIME No None
+	 * iTXt Yes None tEXt Yes None zTXt Yes None
 	 */
 
 	public void writeImage(BufferedImage src, OutputStream os, Map params)
-			throws ImageWriteException, IOException
-	{
+			throws ImageWriteException, IOException {
 		// make copy of params; we'll clear keys as we consume them.
 		params = new HashMap(params);
 
@@ -293,8 +252,7 @@
 			params.remove(PARAM_KEY_PNG_FORCE_INDEXED_COLOR);
 		if (params.containsKey(PARAM_KEY_PNG_BIT_DEPTH))
 			params.remove(PARAM_KEY_PNG_BIT_DEPTH);
-		if (params.size() > 0)
-		{
+		if (params.size() > 0) {
 			Object firstKey = params.keySet().iterator().next();
 			throw new ImageWriteException("Unknown parameter: " + firstKey);
 		}
@@ -306,7 +264,7 @@
 		boolean hasAlpha = new PaletteFactory().hasTransparency(src);
 		if (verbose)
 			Debug.debug("hasAlpha", hasAlpha);
-		//			int transparency = new PaletteFactory().getTransparency(src);
+		// int transparency = new PaletteFactory().getTransparency(src);
 
 		boolean isGrayscale = new PaletteFactory().isGrayscale(src);
 		if (verbose)
@@ -314,25 +272,20 @@
 
 		byte colorType;
 		{
-			boolean force_indexed_color = getParamBoolean(params,
+			boolean force_indexed_color = ParamMap.getParamBoolean(params,
 					PARAM_KEY_PNG_FORCE_INDEXED_COLOR, false);
-			boolean force_true_color = getParamBoolean(params,
+			boolean force_true_color = ParamMap.getParamBoolean(params,
 					PARAM_KEY_PNG_FORCE_TRUE_COLOR, false);
 
 			if (force_indexed_color && force_true_color)
 				throw new ImageWriteException(
 						"Params: Cannot force both indexed and true color modes");
-			else if (force_indexed_color)
-			{
+			else if (force_indexed_color) {
 				colorType = COLOR_TYPE_INDEXED_COLOR;
-			}
-			else if (force_true_color)
-			{
-				colorType = (byte) (hasAlpha
-						? COLOR_TYPE_TRUE_COLOR_WITH_ALPHA
+			} else if (force_true_color) {
+				colorType = (byte) (hasAlpha ? COLOR_TYPE_TRUE_COLOR_WITH_ALPHA
 						: COLOR_TYPE_TRUE_COLOR);
-			}
-			else
+			} else
 				colorType = getColourType(hasAlpha, isGrayscale);
 			if (verbose)
 				Debug.debug("colorType", colorType);
@@ -354,7 +307,7 @@
 			os.write(PNG_Signature);
 		}
 		{
-			// IHDR  	Shall be first
+			// IHDR Shall be first
 
 			byte compression_method = COMPRESSION_TYPE_INFLATE_DEFLATE;
 			byte filter_method = FILTER_METHOD_ADAPTIVE;
@@ -368,32 +321,32 @@
 		}
 
 		{
-			// sRGB 	No 	Before PLTE and IDAT. If the sRGB chunk is present, the iCCP chunk should not be present.
+			// sRGB No Before PLTE and IDAT. If the sRGB chunk is present, the
+			// iCCP chunk should not be present.
 
 			// charles
 		}
 
 		Palette palette = null;
-		if (colorType == COLOR_TYPE_INDEXED_COLOR)
-		{
-			// PLTE 	No 	Before first IDAT
+		if (colorType == COLOR_TYPE_INDEXED_COLOR) {
+			// PLTE No Before first IDAT
 
 			int max_colors = hasAlpha ? 255 : 256;
 
 			palette = new MedianCutQuantizer(true).process(src, max_colors,
 					verbose);
-			//			Palette palette2 = new PaletteFactory().makePaletteSimple(src,
-			//					max_colors);
+			// Palette palette2 = new PaletteFactory().makePaletteSimple(src,
+			// max_colors);
 
-			//			palette.dump();
+			// palette.dump();
 
 			writeChunkPLTE(os, palette);
 		}
 
 		{
-			//						Debug.debug("writing IDAT");
+			// Debug.debug("writing IDAT");
 
-			// IDAT 	Yes 	Multiple IDAT chunks shall be consecutive
+			// IDAT Yes Multiple IDAT chunks shall be consecutive
 
 			byte uncompressed[];
 			{
@@ -403,44 +356,38 @@
 						|| colorType == COLOR_TYPE_TRUE_COLOR_WITH_ALPHA;
 
 				int row[] = new int[width];
-				for (int y = 0; y < height; y++)
-				{
-					//					Debug.debug("y", y + "/" + height);
+				for (int y = 0; y < height; y++) {
+					// Debug.debug("y", y + "/" + height);
 					src.getRGB(0, y, width, 1, row, 0, width);
 
 					byte filter_type = FILTER_TYPE_NONE;
 					baos.write(filter_type);
-					for (int x = 0; x < width; x++)
-					{
+					for (int x = 0; x < width; x++) {
 						int argb = row[x];
 
-						if (palette != null)
-						{
+						if (palette != null) {
 							int index = palette.getPaletteIndex(argb);
 							baos.write(0xff & index);
-						}
-						else
-						{
+						} else {
 							int alpha = 0xff & (argb >> 24);
 							int red = 0xff & (argb >> 16);
 							int green = 0xff & (argb >> 8);
 							int blue = 0xff & (argb >> 0);
 
-							if (isGrayscale)
-							{
+							if (isGrayscale) {
 								int gray = (red + green + blue) / 3;
-								//								if(y==0)
-								//								{
-								//									Debug.debug(x + ", " + y + " argb", Integer.toHexString(argb));
-								////									Debug.debug(x + ", " + y + " gray", gray);
-								////									Debug.debug(x + ", " + y + " gray", gray);
-								//									Debug.debug(x + ", " + y + " gray", gray + " " + Integer.toHexString(gray));
-								//									Debug.debug();
-								//								}
+								// if(y==0)
+								// {
+								// Debug.debug(x + ", " + y + " argb",
+								// Integer.toHexString(argb));
+								// // Debug.debug(x + ", " + y + " gray", gray);
+								// // Debug.debug(x + ", " + y + " gray", gray);
+								// Debug.debug(x + ", " + y + " gray", gray +
+								// " " + Integer.toHexString(gray));
+								// Debug.debug();
+								// }
 								baos.write(gray);
-							}
-							else
-							{
+							} else {
 								baos.write(red);
 								baos.write(green);
 								baos.write(blue);
@@ -453,13 +400,12 @@
 				}
 				uncompressed = baos.toByteArray();
 			}
-			//			Debug.debug("uncompressed", uncompressed.length);
+			// Debug.debug("uncompressed", uncompressed.length);
 
 			ByteArrayOutputStream baos = new ByteArrayOutputStream();
 			DeflaterOutputStream dos = new DeflaterOutputStream(baos);
 			int chunk_size = 256 * 1024;
-			for (int index = 0; index < uncompressed.length; index += chunk_size)
-			{
+			for (int index = 0; index < uncompressed.length; index += chunk_size) {
 				int end = Math.min(uncompressed.length, index + chunk_size);
 				int length = end - index;
 
@@ -469,9 +415,8 @@
 
 				byte compressed[] = baos.toByteArray();
 				baos.reset();
-				if (compressed.length > 0)
-				{
-					//					Debug.debug("compressed", compressed.length);
+				if (compressed.length > 0) {
+					// Debug.debug("compressed", compressed.length);
 					writeChunkIDAT(os, compressed);
 				}
 
@@ -479,38 +424,29 @@
 			{
 				dos.finish();
 				byte compressed[] = baos.toByteArray();
-				if (compressed.length > 0)
-				{
-					//					Debug.debug("compressed final", compressed.length);
+				if (compressed.length > 0) {
+					// Debug.debug("compressed final", compressed.length);
 					writeChunkIDAT(os, compressed);
 				}
 			}
 		}
 
 		{
-			// IEND 	No 	Shall be last
+			// IEND No Shall be last
 
 			writeChunkIEND(os);
 		}
 
 		/*
-		 Ancillary chunks
-		 (need not appear in this order)
-		 Chunk name 	Multiple allowed 	Ordering constraints
-		 cHRM 	No 	Before PLTE and IDAT
-		 gAMA 	No 	Before PLTE and IDAT
-		 iCCP 	No 	Before PLTE and IDAT. If the iCCP chunk is present, the sRGB chunk should not be present.
-		 sBIT 	No 	Before PLTE and IDAT
-		 sRGB 	No 	Before PLTE and IDAT. If the sRGB chunk is present, the iCCP chunk should not be present.
-		 bKGD 	No 	After PLTE; before IDAT
-		 hIST 	No 	After PLTE; before IDAT
-		 tRNS 	No 	After PLTE; before IDAT
-		 pHYs 	No 	Before IDAT
-		 sPLT 	Yes 	Before IDAT
-		 tIME 	No 	None
-		 iTXt 	Yes 	None
-		 tEXt 	Yes 	None
-		 zTXt 	Yes 	None
+		 * Ancillary chunks (need not appear in this order) Chunk name Multiple
+		 * allowed Ordering constraints cHRM No Before PLTE and IDAT gAMA No
+		 * Before PLTE and IDAT iCCP No Before PLTE and IDAT. If the iCCP chunk
+		 * is present, the sRGB chunk should not be present. sBIT No Before PLTE
+		 * and IDAT sRGB No Before PLTE and IDAT. If the sRGB chunk is present,
+		 * the iCCP chunk should not be present. bKGD No After PLTE; before IDAT
+		 * hIST No After PLTE; before IDAT tRNS No After PLTE; before IDAT pHYs
+		 * No Before IDAT sPLT Yes Before IDAT tIME No None iTXt Yes None tEXt
+		 * Yes None zTXt Yes None
 		 */
 
 		os.close();