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/12/22 02:46:41 UTC

svn commit: r728572 - in /incubator/sanselan/trunk: ./ src/main/java/org/apache/sanselan/common/ src/main/java/org/apache/sanselan/formats/bmp/ src/main/java/org/apache/sanselan/formats/bmp/writers/ src/main/java/org/apache/sanselan/formats/jpeg/ src/t...

Author: cmchen
Date: Sun Dec 21 18:46:41 2008
New Revision: 728572

URL: http://svn.apache.org/viewvc?rev=728572&view=rev
Log:
* Added more unit tests around BMP.
 * Added more images to the test image suite.
 * Fixed a bug where errors were being wrongly logged to System.out.

Added:
    incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/
    incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpBaseTest.java   (with props)
    incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpReadTest.java   (with props)
    incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpRoundtripTest.java   (with props)
Modified:
    incubator/sanselan/trunk/RELEASE_NOTES
    incubator/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileFunctions.java
    incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/bmp/BmpHeaderInfo.java
    incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/bmp/BmpImageParser.java
    incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/bmp/writers/BMPWriterPalette.java
    incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/jpeg/JpegImageParser.java
    incubator/sanselan/trunk/src/test/java/org/apache/sanselan/SanselanTest.java
    incubator/sanselan/trunk/src/test/java/org/apache/sanselan/common/byteSources/ByteSourceImageTest.java

Modified: incubator/sanselan/trunk/RELEASE_NOTES
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/RELEASE_NOTES?rev=728572&r1=728571&r2=728572&view=diff
==============================================================================
--- incubator/sanselan/trunk/RELEASE_NOTES (original)
+++ incubator/sanselan/trunk/RELEASE_NOTES Sun Dec 21 18:46:41 2008
@@ -15,6 +15,9 @@
 Release 0.95
 ------------
 
+ * Added more unit tests around BMP.
+ * Added more images to the test image suite.
+ * Fixed a bug where errors were being wrongly logged to System.out.
  * Moved the example code into the test source directory, to comply with Maven's standard project layout.
  * Added a couple of images to the sample image library that demonstrate a couple variations on Photoshop/IPTC data.  
  * Fixed a small bug in the IPTC constants introduced while cleaning up the constants.

Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileFunctions.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileFunctions.java?rev=728572&r1=728571&r2=728572&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileFunctions.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileFunctions.java Sun Dec 21 18:46:41 2008
@@ -77,7 +77,7 @@
 		for (int i = 0; i < bytes; i++)
 		{
 			if (i > 0)
-				System.out.print(",");
+				pw.print(",");
 			int singleByte = 0xff & byteData;
 			pw.print((char) singleByte + " [" + singleByte + "]");
 			byteData >>= 8;

Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/bmp/BmpHeaderInfo.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/bmp/BmpHeaderInfo.java?rev=728572&r1=728571&r2=728572&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/bmp/BmpHeaderInfo.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/bmp/BmpHeaderInfo.java Sun Dec 21 18:46:41 2008
@@ -43,31 +43,30 @@
 	public final int colorsUsed;
 	public final int colorsImportant;
 
-	public BmpHeaderInfo(byte Identifier1, byte Identifier2, int FileSize,
-			int Reserved, int BitmapDataOffset,
-
-			int BitmapHeaderSize, int Width, int Height, int Planes,
-			int BitsPerPixel, int Compression, int BitmapDataSize,
-			int HResolution, int VResolution, int ColorsUsed,
-			int ColorsImportant)
+	public BmpHeaderInfo(byte identifier1, byte identifier2, int fileSize,
+			int reserved, int bitmapDataOffset,
+			int bitmapHeaderSize, int width, int height, int planes,
+			int bitsPerPixel, int compression, int bitmapDataSize,
+			int hResolution, int vResolution, int colorsUsed,
+			int colorsImportant)
 	{
-		this.identifier1 = Identifier1;
-		this.identifier2 = Identifier2;
-		this.fileSize = FileSize;
-		this.reserved = Reserved;
-		this.bitmapDataOffset = BitmapDataOffset;
+		this.identifier1 = identifier1;
+		this.identifier2 = identifier2;
+		this.fileSize = fileSize;
+		this.reserved = reserved;
+		this.bitmapDataOffset = bitmapDataOffset;
 
-		this.bitmapHeaderSize = BitmapHeaderSize;
-		this.width = Width;
-		this.height = Height;
-		this.planes = Planes;
-		this.bitsPerPixel = BitsPerPixel;
-		this.compression = Compression;
-		this.bitmapDataSize = BitmapDataSize;
-		this.hResolution = HResolution;
-		this.vResolution = VResolution;
-		this.colorsUsed = ColorsUsed;
-		this.colorsImportant = ColorsImportant;
+		this.bitmapHeaderSize = bitmapHeaderSize;
+		this.width = width;
+		this.height = height;
+		this.planes = planes;
+		this.bitsPerPixel = bitsPerPixel;
+		this.compression = compression;
+		this.bitmapDataSize = bitmapDataSize;
+		this.hResolution = hResolution;
+		this.vResolution = vResolution;
+		this.colorsUsed = colorsUsed;
+		this.colorsImportant = colorsImportant;
 	}
 
 }
\ No newline at end of file

Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/bmp/BmpImageParser.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/bmp/BmpImageParser.java?rev=728572&r1=728571&r2=728572&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/bmp/BmpImageParser.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/bmp/BmpImageParser.java Sun Dec 21 18:46:41 2008
@@ -47,6 +47,7 @@
 import org.apache.sanselan.palette.PaletteFactory;
 import org.apache.sanselan.palette.SimplePalette;
 import org.apache.sanselan.util.Debug;
+import org.apache.sanselan.util.ParamMap;
 
 public class BmpImageParser extends ImageParser
 {
@@ -84,43 +85,63 @@
 	private static final byte BMP_HEADER_SIGNATURE[] = { 0x42, 0x4d, };
 
 	private BmpHeaderInfo readBmpHeaderInfo(InputStream is,
-			FormatCompliance formatCompliance) throws ImageReadException,
-			IOException
+			FormatCompliance formatCompliance, boolean verbose)
+			throws ImageReadException, IOException
 	{
-		byte Identifier1 = readByte("Identifier1", is, "Not a Valid BMP File");
-		byte Identifier2 = readByte("Identifier2", is, "Not a Valid BMP File");
+		byte identifier1 = readByte("Identifier1", is, "Not a Valid BMP File");
+		byte identifier2 = readByte("Identifier2", is, "Not a Valid BMP File");
 
 		if (formatCompliance != null)
 		{
 			formatCompliance.compare_bytes("Signature", BMP_HEADER_SIGNATURE,
-					new byte[] { Identifier1, Identifier2, });
+					new byte[] { identifier1, identifier2, });
 		}
 
-		int FileSize = read4Bytes("File Size", is, "Not a Valid BMP File");
-		int Reserved = read4Bytes("Reserved", is, "Not a Valid BMP File");
-		int BitmapDataOffset = read4Bytes("Bitmap Data Offset", is,
+		int fileSize = read4Bytes("File Size", is, "Not a Valid BMP File");
+		int reserved = read4Bytes("Reserved", is, "Not a Valid BMP File");
+		int bitmapDataOffset = read4Bytes("Bitmap Data Offset", is,
 				"Not a Valid BMP File");
 
-		int BitmapHeaderSize = read4Bytes("Bitmap Header Size", is,
+		int bitmapHeaderSize = read4Bytes("Bitmap Header Size", is,
 				"Not a Valid BMP File");
-		int Width = read4Bytes("Width", is, "Not a Valid BMP File");
-		int Height = read4Bytes("Height", is, "Not a Valid BMP File");
-		int Planes = read2Bytes("Planes", is, "Not a Valid BMP File");
-		int BitsPerPixel = read2Bytes("Bits Per Pixel", is,
+		int width = read4Bytes("Width", is, "Not a Valid BMP File");
+		int height = read4Bytes("Height", is, "Not a Valid BMP File");
+		int planes = read2Bytes("Planes", is, "Not a Valid BMP File");
+		int bitsPerPixel = read2Bytes("Bits Per Pixel", is,
 				"Not a Valid BMP File");
-		int Compression = read4Bytes("Compression", is, "Not a Valid BMP File");
-		int BitmapDataSize = read4Bytes("Bitmap Data Size", is,
+		int compression = read4Bytes("Compression", is, "Not a Valid BMP File");
+		int bitmapDataSize = read4Bytes("Bitmap Data Size", is,
 				"Not a Valid BMP File");
-		int HResolution = read4Bytes("HResolution", is, "Not a Valid BMP File");
-		int VResolution = read4Bytes("VResolution", is, "Not a Valid BMP File");
-		int ColorsUsed = read4Bytes("ColorsUsed", is, "Not a Valid BMP File");
-		int ColorsImportant = read4Bytes("ColorsImportant", is,
+		int hResolution = read4Bytes("HResolution", is, "Not a Valid BMP File");
+		int vResolution = read4Bytes("VResolution", is, "Not a Valid BMP File");
+		int colorsUsed = read4Bytes("ColorsUsed", is, "Not a Valid BMP File");
+		int colorsImportant = read4Bytes("ColorsImportant", is,
 				"Not a Valid BMP File");
 
-		BmpHeaderInfo result = new BmpHeaderInfo(Identifier1, Identifier2,
-				FileSize, Reserved, BitmapDataOffset, BitmapHeaderSize, Width,
-				Height, Planes, BitsPerPixel, Compression, BitmapDataSize,
-				HResolution, VResolution, ColorsUsed, ColorsImportant);
+		if (verbose)
+		{
+			this.debugNumber("identifier1", identifier1, 1);
+			this.debugNumber("identifier2", identifier2, 1);
+			this.debugNumber("fileSize", fileSize, 4);
+			this.debugNumber("reserved", reserved, 4);
+			this.debugNumber("bitmapDataOffset", bitmapDataOffset, 4);
+			this.debugNumber("bitmapHeaderSize", bitmapHeaderSize, 4);
+			this.debugNumber("width", width, 4);
+			this.debugNumber("height", height, 4);
+			this.debugNumber("planes", planes, 2);
+			this.debugNumber("bitsPerPixel", bitsPerPixel, 2);
+			this.debugNumber("compression", compression, 4);
+			this.debugNumber("bitmapDataSize", bitmapDataSize, 4);
+			this.debugNumber("hResolution", hResolution, 4);
+			this.debugNumber("vResolution", vResolution, 4);
+			this.debugNumber("colorsUsed", colorsUsed, 4);
+			this.debugNumber("colorsImportant", colorsImportant, 4);
+		}
+
+		BmpHeaderInfo result = new BmpHeaderInfo(identifier1, identifier2,
+				fileSize, reserved, bitmapDataOffset, bitmapHeaderSize, width,
+				height, planes, bitsPerPixel, compression, bitmapDataSize,
+				hResolution, vResolution, colorsUsed, colorsImportant);
 		return result;
 	}
 
@@ -151,12 +172,12 @@
 				case 0: // EOL
 					break;
 				case 1: // EOF
-					//System.out.println("xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+					// System.out.println("xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
 					// );
 					done = true;
 					break;
 				case 2: {
-					//System.out.println("xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+					// System.out.println("xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
 					// );
 					int c = 0xff & this.readByte("RLE c", is, "BMP: Bad RLE");
 					baos.write(c);
@@ -176,7 +197,7 @@
 					// System.out.println("size: " + size);
 					// System.out.println("RLESamplesPerByte: " +
 					// RLESamplesPerByte);
-					//System.out.println("xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+					// System.out.println("xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
 					// );
 					byte bytes[] = this.readByteArray("bytes", size, is,
 							"RLE: Absolute Mode");
@@ -191,20 +212,21 @@
 	}
 
 	private ImageContents readImageContents(InputStream is,
-			FormatCompliance formatCompliance) throws ImageReadException,
-			IOException
+			FormatCompliance formatCompliance, boolean verbose)
+			throws ImageReadException, IOException
 	{
-		BmpHeaderInfo bhi = readBmpHeaderInfo(is, formatCompliance);
+		BmpHeaderInfo bhi = readBmpHeaderInfo(is, formatCompliance, verbose);
 
 		int colorTableSize = bhi.colorsUsed;
 		if (colorTableSize == 0)
 			colorTableSize = (1 << bhi.bitsPerPixel);
 
-		if (debug)
+		if (verbose)
 		{
 			this.debugNumber("ColorsUsed", bhi.colorsUsed, 4);
 			this.debugNumber("BitsPerPixel", bhi.bitsPerPixel, 4);
 			this.debugNumber("ColorTableSize", colorTableSize, 4);
+			this.debugNumber("bhi.colorsUsed", bhi.colorsUsed, 4);
 			this.debugNumber("Compression", bhi.compression, 4);
 		}
 
@@ -215,7 +237,7 @@
 		switch (bhi.compression)
 		{
 		case BI_RGB:
-			if (debug)
+			if (verbose)
 				System.out.println("Compression: BI_RGB");
 			if (bhi.bitsPerPixel <= 8)
 				paletteLength = 4 * colorTableSize;
@@ -228,7 +250,7 @@
 			break;
 
 		case BI_RLE4:
-			if (debug)
+			if (verbose)
 				System.out.println("Compression: BI_RLE4");
 			paletteLength = 4 * colorTableSize;
 			rleSamplesPerByte = 2;
@@ -239,7 +261,7 @@
 			break;
 		//
 		case BI_RLE8:
-			if (debug)
+			if (verbose)
 				System.out.println("Compression: BI_RLE8");
 			paletteLength = 4 * colorTableSize;
 			rleSamplesPerByte = 1;
@@ -250,7 +272,7 @@
 			break;
 		//
 		case BI_BITFIELDS:
-			if (debug)
+			if (verbose)
 				System.out.println("Compression: BI_BITFIELDS");
 			paletteLength = 3 * 4; // TODO: is this right? are the masks always
 			// LONGs?
@@ -268,7 +290,7 @@
 			colorTable = this.readByteArray("ColorTable", paletteLength, is,
 					"Not a Valid BMP File");
 
-		if (debug)
+		if (verbose)
 		{
 			this.debugNumber("paletteLength", paletteLength, 4);
 			System.out.println("ColorTable: "
@@ -279,7 +301,7 @@
 
 		int imageLineLength = ((((bhi.bitsPerPixel) * bhi.width) + 7) / 8);
 
-		if (debug)
+		if (verbose)
 		{
 			// this.debugNumber("Total BitsPerPixel",
 			// (ExtraBitsPerPixel + bhi.BitsPerPixel), 4);
@@ -296,10 +318,11 @@
 		while ((imageLineLength % 4) != 0)
 			imageLineLength++;
 
-		final int headerSize = 54;
+		final int headerSize = BITMAP_FILE_HEADER_SIZE
+				+ BITMAP_INFO_HEADER_SIZE;
 		int expectedDataOffset = headerSize + paletteLength;
 
-		if (debug)
+		if (verbose)
 		{
 			this.debugNumber("bhi.BitmapDataOffset", bhi.bitmapDataOffset, 4);
 			this.debugNumber("expectedDataOffset", expectedDataOffset, 4);
@@ -316,7 +339,7 @@
 
 		int imageDataSize = bhi.height * imageLineLength;
 
-		if (debug)
+		if (verbose)
 			this.debugNumber("imageDataSize", imageDataSize, 4);
 
 		byte imageData[];
@@ -326,7 +349,7 @@
 			imageData = this.readByteArray("ImageData", imageDataSize, is,
 					"Not a Valid BMP File");
 
-		if (debug)
+		if (verbose)
 			this.debugNumber("ImageData.length", imageData.length, 4);
 
 		PixelParser pixelParser;
@@ -351,8 +374,8 @@
 		return new ImageContents(bhi, colorTable, imageData, pixelParser);
 	}
 
-	private BmpHeaderInfo readBmpHeaderInfo(ByteSource byteSource)
-			throws ImageReadException, IOException
+	private BmpHeaderInfo readBmpHeaderInfo(ByteSource byteSource,
+			boolean verbose) throws ImageReadException, IOException
 	{
 		InputStream is = null;
 		try
@@ -360,7 +383,7 @@
 			is = byteSource.getInputStream();
 
 			// readSignature(is);
-			return readBmpHeaderInfo(is, null);
+			return readBmpHeaderInfo(is, null, verbose);
 		} finally
 		{
 			try
@@ -383,7 +406,22 @@
 	public Dimension getImageSize(ByteSource byteSource, Map params)
 			throws ImageReadException, IOException
 	{
-		BmpHeaderInfo bhi = readBmpHeaderInfo(byteSource);
+		// make copy of params; we'll clear keys as we consume them.
+		params = (params == null) ? new HashMap() : new HashMap(params);
+
+		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 ImageReadException("Unknown parameter: " + firstKey);
+		}
+
+		BmpHeaderInfo bhi = readBmpHeaderInfo(byteSource, verbose);
 
 		if (bhi == null)
 			throw new ImageReadException("BMP: couldn't read header");
@@ -429,29 +467,42 @@
 	public ImageInfo getImageInfo(ByteSource byteSource, Map params)
 			throws ImageReadException, IOException
 	{
+		// make copy of params; we'll clear keys as we consume them.
+		params = (params == null) ? new HashMap() : new HashMap(params);
+
+		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 ImageReadException("Unknown parameter: " + firstKey);
+		}
+
 		ImageContents ic = readImageContents(byteSource.getInputStream(),
-				FormatCompliance.getDefault());
+				FormatCompliance.getDefault(), verbose);
 
 		if (ic == null)
 			throw new ImageReadException("Couldn't read BMP Data");
 
 		BmpHeaderInfo bhi = ic.bhi;
 		byte colorTable[] = ic.colorTable;
-		// byte ImageData[] = ic.ImageData;
 
-		// BmpHeaderInfo bhi = readBmpHeaderInfo(byteSource);
 		if (bhi == null)
 			throw new ImageReadException("BMP: couldn't read header");
 
-		int Height = bhi.height;
-		int Width = bhi.width;
+		int height = bhi.height;
+		int width = bhi.width;
 
-		ArrayList Comments = new ArrayList();
+		ArrayList comments = new ArrayList();
 		// TODO: comments...
 
 		int bitsPerPixel = bhi.bitsPerPixel;
 		ImageFormat format = ImageFormat.IMAGE_FORMAT_BMP;
-		String fName = "BMP Windows Bitmap";
+		String name = "BMP Windows Bitmap";
 		String mimeType = "image/x-ms-bmp";
 		// we ought to count images, but don't yet.
 		int numberOfImages = -1;
@@ -461,10 +512,10 @@
 		//
 		// pixels per meter
 		int physicalWidthDpi = (int) ((double) bhi.hResolution * 1000.0 / 2.54);
-		float physicalWidthInch = (float) ((double) Width / (double) physicalWidthDpi);
+		float physicalWidthInch = (float) ((double) width / (double) physicalWidthDpi);
 		// int physicalHeightDpi = 72;
 		int physicalHeightDpi = (int) ((double) bhi.vResolution * 1000.0 / 2.54);
-		float physicalHeightInch = (float) ((double) Height / (double) physicalHeightDpi);
+		float physicalHeightInch = (float) ((double) height / (double) physicalHeightDpi);
 
 		String formatDetails = "Bmp (" + (char) bhi.identifier1
 				+ (char) bhi.identifier2 + ": "
@@ -473,14 +524,14 @@
 		boolean isTransparent = false;
 
 		boolean usesPalette = colorTable != null;
-		int ColorType = ImageInfo.COLOR_TYPE_RGB;
+		int colorType = ImageInfo.COLOR_TYPE_RGB;
 		String compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_RLE;
 
-		ImageInfo result = new ImageInfo(formatDetails, bitsPerPixel, Comments,
-				format, fName, Height, mimeType, numberOfImages,
+		ImageInfo result = new ImageInfo(formatDetails, bitsPerPixel, comments,
+				format, name, height, mimeType, numberOfImages,
 				physicalHeightDpi, physicalHeightInch, physicalWidthDpi,
-				physicalWidthInch, Width, isProgressive, isTransparent,
-				usesPalette, ColorType, compressionAlgorithm);
+				physicalWidthInch, width, isProgressive, isTransparent,
+				usesPalette, colorType, compressionAlgorithm);
 
 		return result;
 	}
@@ -504,10 +555,12 @@
 	public FormatCompliance getFormatCompliance(ByteSource byteSource)
 			throws ImageReadException, IOException
 	{
+		boolean verbose = false;
+
 		FormatCompliance result = new FormatCompliance(byteSource
 				.getDescription());
 
-		readImageContents(byteSource.getInputStream(), result);
+		readImageContents(byteSource.getInputStream(), result, verbose);
 
 		return result;
 	}
@@ -515,8 +568,25 @@
 	public BufferedImage getBufferedImage(ByteSource byteSource, Map params)
 			throws ImageReadException, IOException
 	{
+		// make copy of params; we'll clear keys as we consume them.
+		params = (params == null) ? new HashMap() : new HashMap(params);
+
+		boolean verbose = ParamMap.getParamBoolean(params, PARAM_KEY_VERBOSE,
+				false);
+
+		if (params.containsKey(PARAM_KEY_VERBOSE))
+			params.remove(PARAM_KEY_VERBOSE);
+		if (params.containsKey(BUFFERED_IMAGE_FACTORY))
+			params.remove(BUFFERED_IMAGE_FACTORY);
+
+		if (params.size() > 0)
+		{
+			Object firstKey = params.keySet().iterator().next();
+			throw new ImageReadException("Unknown parameter: " + firstKey);
+		}
+
 		ImageContents ic = readImageContents(byteSource.getInputStream(),
-				FormatCompliance.getDefault());
+				FormatCompliance.getDefault(), verbose);
 		if (ic == null)
 			throw new ImageReadException("Couldn't read BMP Data");
 
@@ -531,7 +601,7 @@
 		BufferedImage result = getBufferedImageFactory(params)
 				.getColorBufferedImage(width, height, hasAlpha);
 
-		if (debug)
+		if (verbose)
 		{
 			System.out.println("width: " + width);
 			System.out.println("height: " + height);
@@ -554,7 +624,7 @@
 			throws ImageWriteException, IOException
 	{
 		// make copy of params; we'll clear keys as we consume them.
-		params = new HashMap(params);
+		params = (params == null) ? new HashMap() : new HashMap(params);
 
 		// clear format key.
 		if (params.containsKey(PARAM_KEY_FORMAT))
@@ -566,8 +636,8 @@
 			throw new ImageWriteException("Unknown parameter: " + firstKey);
 		}
 
-		SimplePalette palette = new PaletteFactory()
-				.makePaletteSimple(src, 256);
+		final SimplePalette palette = new PaletteFactory().makePaletteSimple(
+				src, 256);
 
 		BMPWriter writer = null;
 		if (palette == null)
@@ -604,7 +674,7 @@
 			bos.write2Bytes(1); // Number of Planes
 			bos.write2Bytes(writer.getBitsPerPixel()); // Bits Per Pixel
 
-			bos.write4Bytes(0); // Compression
+			bos.write4Bytes(BI_RGB); // Compression
 			bos.write4Bytes(imagedata.length); // Bitmap Data Size
 			bos.write4Bytes(0); // HResolution
 			bos.write4Bytes(0); // VResolution

Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/bmp/writers/BMPWriterPalette.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/bmp/writers/BMPWriterPalette.java?rev=728572&r1=728571&r2=728572&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/bmp/writers/BMPWriterPalette.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/bmp/writers/BMPWriterPalette.java Sun Dec 21 18:46:41 2008
@@ -26,18 +26,18 @@
 public class BMPWriterPalette extends BMPWriter
 {
 	private final SimplePalette palette;
-	private final int bits_per_sample;
+	private final int bitsPerSample;
 
 	public BMPWriterPalette(SimplePalette palette)
 	{
 		this.palette = palette;
 
 		if (palette.length() <= 2)
-			bits_per_sample = 1;
+			bitsPerSample = 1;
 		else if (palette.length() <= 16)
-			bits_per_sample = 4;
+			bitsPerSample = 4;
 		else
-			bits_per_sample = 8;
+			bitsPerSample = 8;
 	}
 
 	public int getPaletteSize()
@@ -47,7 +47,7 @@
 
 	public int getBitsPerPixel()
 	{
-		return bits_per_sample;
+		return bitsPerSample;
 	}
 
 	public void writePalette(BinaryOutputStream bos) throws IOException
@@ -87,15 +87,15 @@
 
 				int index = palette.getPaletteIndex(rgb);
 
-				if (bits_per_sample == 8)
+				if (bitsPerSample == 8)
 				{
 					baos.write(0xff & index);
 					bytecount++;
 				} else
 				// 4 or 1
 				{
-					bit_cache = (bit_cache << bits_per_sample) | index;
-					bits_in_cache += bits_per_sample;
+					bit_cache = (bit_cache << bitsPerSample) | index;
+					bits_in_cache += bitsPerSample;
 					if (bits_in_cache >= 8)
 					{
 						baos.write(0xff & bit_cache);

Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/jpeg/JpegImageParser.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/jpeg/JpegImageParser.java?rev=728572&r1=728571&r2=728572&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/jpeg/JpegImageParser.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/jpeg/JpegImageParser.java Sun Dec 21 18:46:41 2008
@@ -363,10 +363,6 @@
 		if (!params.containsKey(PARAM_KEY_READ_THUMBNAILS))
 			params.put(PARAM_KEY_READ_THUMBNAILS, Boolean.TRUE);
 
-		// Debug.debug("read thumbs?", params.get(PARAM_KEY_READ_THUMBNAILS));
-
-		// Debug.debug("exif bytes", bytes.length);
-
 		return (TiffImageMetadata) new TiffImageParser().getMetadata(bytes,
 				params);
 	}

Modified: incubator/sanselan/trunk/src/test/java/org/apache/sanselan/SanselanTest.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/test/java/org/apache/sanselan/SanselanTest.java?rev=728572&r1=728571&r2=728572&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/test/java/org/apache/sanselan/SanselanTest.java (original)
+++ incubator/sanselan/trunk/src/test/java/org/apache/sanselan/SanselanTest.java Sun Dec 21 18:46:41 2008
@@ -108,25 +108,17 @@
 		return getTestImages(filter, -1);
 	}
 
-	protected List getTestImages(final ImageFilter filter, final int max)
-			throws IOException, ImageReadException
-	{
+	private static final List ALL_IMAGES = new ArrayList();
 
+	static
+	{
 		File srcFolder = new File("src");
 		File testFolder = new File(srcFolder, "test");
 		File dataFolder = new File(testFolder, "data");
 		File imagesFolder = new File(dataFolder, "images");
 
 		// imagesFolder = new File(
-		// "C:\\work\\personal\\apache\\sanselan\\src\\test\\data\\images\\exif\\drewNoakes\\007_Canon EOS D60.jpg"
-		// );
-		// imagesFolder = new File(
-		// "C:\\work\\personal\\apache\\sanselan\\src\\test\\data\\images\\exif\\drewNoakes\\007_FujiFilm FinePixS1Pro (1).jpg"
-		// );
-		// imagesFolder = new File(
-		// "C:\\work\\personal\\apache\\sanselan\\src\\test\\data\\images\\exif\\philHarvey\\Nikon\\NikonCoolpixS7.jpg"
-		// );
-//		imagesFolder = new File("C:\\work\\personal\\apache\\sanselan\\src\\test\\data\\images\\exif\\philHarvey\\UMAX\\UmaxAstraCam.jpg");
+		// "C:\\personal\\apache\\sanselan\\src\\test\\data\\images\\bmp\\2");
 
 		imagesFolder = imagesFolder.getAbsoluteFile();
 
@@ -134,57 +126,50 @@
 
 		Debug.debug("imagesFolder", imagesFolder);
 
-		final List images = new ArrayList();
-
 		FSTraversal.Visitor visitor = new FSTraversal.Visitor() {
-			long counter = 0;
 
 			public boolean visit(File file, double progressEstimate)
 			{
-
 				if (!Sanselan.hasImageFileExtension(file))
 					return true;
-
-				if (counter++ % 10 == 0)
-					Debug.purgeMemory();
-
-				try
-				{
-					if (filter != null && !filter.accept(file))
-						return true;
-				} catch (Exception e)
-				{
-					Debug.debug(e);
-					return false;
-				}
-
-				images.add(file);
-
-				if (max < 1)
-					return true;
-				return images.size() < max;
+				ALL_IMAGES.add(file);
+				return true;
 			}
 		};
 		new FSTraversal().traverseFiles(imagesFolder, visitor);
+	}
 
-		List filtered = new ArrayList();
-		// long last = System.currentTimeMillis();
-		for (int i = 0; i < images.size(); i++)
+	protected List getTestImages(final ImageFilter filter, final int max)
+			throws IOException, ImageReadException
+	{
+		final List images = new ArrayList();
+		int counter = 0;
+		
+		for (int i = 0; i < ALL_IMAGES.size(); i++)
 		{
-			// if (i % 10 == 0)
-			// Debug.purgeMemory();
+			File file = (File) ALL_IMAGES.get(i);
 
-			File file = (File) images.get(i);
-			// Debug.debug("considering file", file.getAbsoluteFile());
+			if (!Sanselan.hasImageFileExtension(file))
+				continue;
+
+			if (counter++ % 10 == 0)
+				Debug.purgeMemory();
 
 			if (file.getParentFile().getName().toLowerCase().equals("@broken"))
 				continue;
-			filtered.add(file);
+
+			if (filter != null && !filter.accept(file))
+				continue;
+
+			images.add(file);
+
+			if (max > 0 && images.size() >= max)
+				break;
 		}
 
-		assertTrue(filtered.size() > 0);
+		assertTrue(images.size() > 0);
 
-		return filtered;
+		return images;
 	}
 
 	protected boolean isInvalidPNGTestFile(File file)

Modified: incubator/sanselan/trunk/src/test/java/org/apache/sanselan/common/byteSources/ByteSourceImageTest.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/test/java/org/apache/sanselan/common/byteSources/ByteSourceImageTest.java?rev=728572&r1=728571&r2=728572&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/test/java/org/apache/sanselan/common/byteSources/ByteSourceImageTest.java (original)
+++ incubator/sanselan/trunk/src/test/java/org/apache/sanselan/common/byteSources/ByteSourceImageTest.java Sun Dec 21 18:46:41 2008
@@ -38,7 +38,8 @@
 import org.apache.sanselan.util.Debug;
 import org.apache.sanselan.util.IOUtils;
 
-public class ByteSourceImageTest extends ByteSourceTest {
+public class ByteSourceImageTest extends ByteSourceTest
+{
 	// public ByteSourceImageTest()
 	// {
 	// super(ByteSourceImageTest.class.getName());
@@ -47,15 +48,18 @@
 	/**
 	 * @return the suite of tests being tested
 	 */
-	public static Test suite() {
+	public static Test suite()
+	{
 		return new TestSuite(ByteSourceImageTest.class);
 	}
 
 	public void test() throws IOException, ImageReadException,
 			IllegalAccessException, IllegalArgumentException,
-			InvocationTargetException {
+			InvocationTargetException
+	{
 		List imageFiles = getTestImages();
-		for (int i = 0; i < imageFiles.size(); i++) {
+		for (int i = 0; i < imageFiles.size(); i++)
+		{
 			if (i % 10 == 0)
 				Debug.purgeMemory();
 
@@ -103,7 +107,8 @@
 	}
 
 	public void checkGetBufferedImage(File file, byte[] bytes)
-			throws IOException, ImageReadException {
+			throws IOException, ImageReadException
+	{
 		BufferedImage imageFile = Sanselan.getBufferedImage(file);
 		assertTrue(imageFile != null);
 		assertTrue(imageFile.getWidth() > 0);
@@ -116,7 +121,8 @@
 	}
 
 	public void checkGetImageSize(File imageFile, byte[] imageFileBytes)
-			throws IOException, ImageReadException {
+			throws IOException, ImageReadException
+	{
 		Dimension imageSizeFile = Sanselan.getImageSize(imageFile);
 		assertTrue(imageSizeFile != null);
 		assertTrue(imageSizeFile.width > 0);
@@ -129,7 +135,8 @@
 	}
 
 	public void checkGuessFormat(File imageFile, byte[] imageFileBytes)
-			throws IOException, ImageReadException {
+			throws IOException, ImageReadException
+	{
 		// check guessFormat()
 		ImageFormat imageFormatFile = Sanselan.guessFormat(imageFile);
 		assertTrue(imageFormatFile != null);
@@ -145,7 +152,8 @@
 	}
 
 	public void checkGetICCProfileBytes(File imageFile, byte[] imageFileBytes)
-			throws IOException, ImageReadException {
+			throws IOException, ImageReadException
+	{
 		// check guessFormat()
 		byte iccBytesFile[] = Sanselan.getICCProfileBytes(imageFile);
 
@@ -161,12 +169,16 @@
 
 	public void checkGetImageInfo(File imageFile, byte[] imageFileBytes)
 			throws IOException, ImageReadException, IllegalAccessException,
-			IllegalArgumentException, InvocationTargetException {
-		// check guessFormat()
-
+			IllegalArgumentException, InvocationTargetException
+	{
 		Map params = new HashMap();
 		boolean ignoreImageData = isPhilHarveyTestImage(imageFile);
-		params.put(PARAM_KEY_READ_THUMBNAILS, new Boolean(!ignoreImageData));
+		ImageFormat imageFormat = Sanselan.guessFormat(imageFile);
+		if (imageFormat.equals(ImageFormat.IMAGE_FORMAT_TIFF)
+				|| imageFormat.equals(ImageFormat.IMAGE_FORMAT_JPEG))
+			params
+					.put(PARAM_KEY_READ_THUMBNAILS, new Boolean(
+							!ignoreImageData));
 
 		ImageInfo imageInfoFile = Sanselan.getImageInfo(imageFile, params);
 
@@ -177,7 +189,8 @@
 		assertTrue(imageInfoBytes != null);
 
 		Method methods[] = ImageInfo.class.getMethods();
-		for (int i = 0; i < methods.length; i++) {
+		for (int i = 0; i < methods.length; i++)
+		{
 			Method method = methods[i];
 			method.getModifiers();
 			if (!Modifier.isPublic(method.getModifiers()))

Added: incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpBaseTest.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpBaseTest.java?rev=728572&view=auto
==============================================================================
--- incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpBaseTest.java (added)
+++ incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpBaseTest.java Sun Dec 21 18:46:41 2008
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.sanselan.formats.bmp;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.sanselan.ImageFormat;
+import org.apache.sanselan.ImageInfo;
+import org.apache.sanselan.ImageReadException;
+import org.apache.sanselan.ImageWriteException;
+import org.apache.sanselan.Sanselan;
+import org.apache.sanselan.SanselanTest;
+import org.apache.sanselan.common.IImageMetadata;
+import org.apache.sanselan.util.Debug;
+
+public abstract class BmpBaseTest extends SanselanTest
+{
+
+	private static boolean isBmp(File file) throws IOException,
+			ImageReadException
+	{
+		ImageFormat format = Sanselan.guessFormat(file);
+		return format == ImageFormat.IMAGE_FORMAT_BMP;
+	}
+
+	private static final ImageFilter IMAGE_FILTER = new ImageFilter() {
+		public boolean accept(File file) throws IOException, ImageReadException
+		{
+			return isBmp(file);
+		}
+	};
+
+	protected List getBmpImages() throws IOException, ImageReadException
+	{
+		return getTestImages(IMAGE_FILTER);
+	}
+
+
+}

Propchange: incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpBaseTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpReadTest.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpReadTest.java?rev=728572&view=auto
==============================================================================
--- incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpReadTest.java (added)
+++ incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpReadTest.java Sun Dec 21 18:46:41 2008
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.sanselan.formats.bmp;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.sanselan.ImageInfo;
+import org.apache.sanselan.ImageReadException;
+import org.apache.sanselan.ImageWriteException;
+import org.apache.sanselan.Sanselan;
+import org.apache.sanselan.common.IImageMetadata;
+import org.apache.sanselan.util.Debug;
+
+public class BmpReadTest extends BmpBaseTest
+{
+
+	public void test() throws IOException, ImageReadException,
+			ImageWriteException
+	{
+		Debug.debug("start");
+
+		List images = getBmpImages();
+		for (int i = 0; i < images.size(); i++)
+		{
+			if (i % 10 == 0)
+				Debug.purgeMemory();
+
+			File imageFile = (File) images.get(i);
+			Debug.debug("imageFile", imageFile);
+
+			IImageMetadata metadata = Sanselan.getMetadata(imageFile);
+			// assertNotNull(metadata);
+
+			Map params = new HashMap();
+//			params.put(PARAM_KEY_VERBOSE, Boolean.TRUE);
+			ImageInfo imageInfo = Sanselan.getImageInfo(imageFile, params);
+			assertNotNull(imageInfo);
+
+			BufferedImage image = Sanselan.getBufferedImage(imageFile);
+			assertNotNull(image);
+		}
+	}
+
+}

Propchange: incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpReadTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpRoundtripTest.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpRoundtripTest.java?rev=728572&view=auto
==============================================================================
--- incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpRoundtripTest.java (added)
+++ incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpRoundtripTest.java Sun Dec 21 18:46:41 2008
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.sanselan.formats.bmp;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+import org.apache.sanselan.ImageFormat;
+import org.apache.sanselan.ImageReadException;
+import org.apache.sanselan.ImageWriteException;
+import org.apache.sanselan.Sanselan;
+import org.apache.sanselan.util.Debug;
+import org.apache.sanselan.util.IOUtils;
+
+public class BmpRoundtripTest extends BmpBaseTest
+{
+
+	private int[][] getSimpleRawData(int width, int height, int value)
+	{
+		int[][] result = new int[height][width];
+		for (int y = 0; y < height; y++)
+			for (int x = 0; x < width; x++)
+				result[y][x] = value;
+		return result;
+	}
+
+	private int[][] getAscendingRawData(int width, int height)
+	{
+		int[][] result = new int[height][width];
+		for (int y = 0; y < height; y++)
+			for (int x = 0; x < width; x++)
+			{
+				int alpha = (x + y) % 256;
+				int value = (x + y) % 256;
+				int argb = (0xff & alpha) << 24 | (0xff & value) << 16
+						| (0xff & value) << 8 | (0xff & value) << 0;
+
+				result[y][x] = argb;
+			}
+		return result;
+	}
+
+	private int[][] randomRawData(int width, int height)
+	{
+		Random random = new Random();
+		int[][] result = new int[height][width];
+		for (int y = 0; y < height; y++)
+			for (int x = 0; x < width; x++)
+			{
+				int argb = random.nextInt();
+				result[y][x] = argb;
+			}
+		return result;
+	}
+
+	 public void testSmallBlackPixels() throws IOException,
+	 ImageReadException,
+	 ImageWriteException
+	 {
+	 int[][] smallBlackPixels = getSimpleRawData(256, 256, 0);
+	 writeAndReadImageData(smallBlackPixels);
+	 }
+	
+	public void testSingleBlackPixel() throws IOException, ImageReadException,
+			ImageWriteException
+	{
+		int[][] singleBlackPixel = getSimpleRawData(1, 1, 0);
+		writeAndReadImageData(singleBlackPixel);
+	}
+
+	
+	 public void testSmallRedPixels() throws IOException, ImageReadException,
+	 ImageWriteException
+	 {
+	 int[][] smallRedPixels = getSimpleRawData(256, 256, 0xffff0000);
+	 writeAndReadImageData(smallRedPixels);
+	 }
+	
+	 public void testSingleRedPixel() throws IOException, ImageReadException,
+	 ImageWriteException
+	 {
+	 int[][] singleRedPixel = getSimpleRawData(1, 1, 0xffff0000);
+	 writeAndReadImageData(singleRedPixel);
+	 }
+	
+	 public void testSmallAscendingPixels() throws IOException,
+	 ImageReadException, ImageWriteException
+	 {
+	 int[][] smallAscendingPixels = getAscendingRawData(256, 256);
+	 writeAndReadImageData(smallAscendingPixels);
+	 }
+	
+	 public void testSmallRandomPixels() throws IOException,
+	 ImageReadException,
+	 ImageWriteException
+	 {
+	 int[][] smallRandomPixels = randomRawData(256, 256);
+	 writeAndReadImageData(smallRandomPixels);
+	 }
+
+	private BufferedImage imageDataToBufferedImage(int[][] rawData)
+	{
+		int width = rawData[0].length;
+		int height = rawData.length;
+		BufferedImage image = new BufferedImage(width, height,
+				BufferedImage.TYPE_INT_ARGB);
+		for (int y = 0; y < height; y++)
+			for (int x = 0; x < width; x++)
+			{
+				image.setRGB(x, y, rawData[y][x]);
+			}
+		return image;
+	}
+
+	private int[][] bufferedImageToImageData(BufferedImage image)
+	{
+		int width = image.getWidth();
+		int height = image.getHeight();
+		int[][] result = new int[height][width];
+
+		for (int y = 0; y < height; y++)
+			for (int x = 0; x < width; x++)
+			{
+				result[y][x] = image.getRGB(x, y);
+			}
+		return result;
+	}
+
+	private void writeAndReadImageData(int[][] rawData) throws IOException,
+			ImageReadException, ImageWriteException
+	{
+		BufferedImage srcImage = imageDataToBufferedImage(rawData);
+
+		Map writeParams = new HashMap();
+		// writeParams.put(SanselanConstants.PARAM_KEY_FORMAT,
+		// ImageFormat.IMAGE_FORMAT_BMP);
+		// writeParams.put(PngConstants.PARAM_KEY_BMP_FORCE_TRUE_COLOR,
+		// Boolean.TRUE);
+
+		byte bytes[] = Sanselan.writeImageToBytes(srcImage,
+				ImageFormat.IMAGE_FORMAT_BMP, writeParams);
+
+		// Debug.debug("bytes", bytes);
+
+		File tempFile = createTempFile("temp", ".bmp");
+		IOUtils.writeToFile(bytes, tempFile);
+
+		BufferedImage dstImage = Sanselan.getBufferedImage(bytes);
+
+		assertTrue(null != dstImage);
+		assertTrue(srcImage.getWidth() == dstImage.getWidth());
+		assertTrue(srcImage.getHeight() == dstImage.getHeight());
+
+		int dstData[][] = bufferedImageToImageData(dstImage);
+		compare(rawData, dstData);
+	}
+
+	private void compare(int[][] a, int[][] b)
+	{
+		assertTrue(null != a);
+		assertTrue(null != b);
+		assertTrue(a.length == b.length);
+
+		for (int y = 0; y < a.length; y++)
+		{
+			assertTrue(a[y].length == b[y].length);
+			// make sure row lengths consistent.
+			assertTrue(a[0].length == b[y].length);
+			for (int x = 0; x < a[y].length; x++)
+			{
+				// ignore alpha channel - BMP has no transparency.
+				int rgbA = 0xffffff & a[y][x];
+				int rgbB = 0xffffff & b[y][x];
+
+				if (rgbA != rgbB)
+				{
+					Debug.debug("x: " + x + ", y: " + y + ", rgbA: " + rgbA
+							+ " (0x" + Integer.toHexString(rgbA) + ")"
+							+ ", rgbB: " + rgbB + " (0x"
+							+ Integer.toHexString(rgbB) + ")");
+				}
+				assertTrue(rgbA == rgbB);
+			}
+		}
+	}
+
+}

Propchange: incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/bmp/BmpRoundtripTest.java
------------------------------------------------------------------------------
    svn:eol-style = native