You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2010/09/10 03:35:52 UTC

svn commit: r995634 [2/6] - in /commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan: ./ common/ common/byteSources/ formats/bmp/ formats/gif/ formats/ico/ formats/jpeg/ formats/jpeg/exif/ formats/jpeg/iptc/ formats/jpeg/xmp/ formats/png/ fo...

Modified: commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/ico/IcoRoundtripTest.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/ico/IcoRoundtripTest.java?rev=995634&r1=995633&r2=995634&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/ico/IcoRoundtripTest.java (original)
+++ commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/ico/IcoRoundtripTest.java Fri Sep 10 01:35:50 2010
@@ -34,559 +34,559 @@ import org.apache.sanselan.util.IOUtils;
 
 public class IcoRoundtripTest extends IcoBaseTest
 {
-	// 16x16 test image
-	private static final int[][] image = {
-		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-		{0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,0},
-		{0,0,0,1,1,0,0,0,0,1,0,0,1,0,0,0},
-		{0,0,1,0,1,0,0,0,1,0,0,0,0,1,0,0},
-		{0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0},
-		{0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0},
-		{0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0},
-		{0,0,0,0,1,0,0,0,1,0,1,1,1,0,0,0},
-		{0,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0},
-		{0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0},
-		{0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0},
-		{0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0},
-		{0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,0},
-		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
-	};
-
-	private Map generatorMap = new HashMap();
-
-	public IcoRoundtripTest()
-	{
-		generatorMap.put(Integer.valueOf(1), new GeneratorFor1BitBitmaps());
-		generatorMap.put(Integer.valueOf(4), new GeneratorFor4BitBitmaps());
-		generatorMap.put(Integer.valueOf(8), new GeneratorFor8BitBitmaps());
-		generatorMap.put(Integer.valueOf(16), new GeneratorFor16BitBitmaps());
-		generatorMap.put(Integer.valueOf(24), new GeneratorFor24BitBitmaps());
-		generatorMap.put(Integer.valueOf(32), new GeneratorFor32BitBitmaps());
-	}
-
-	private static interface BitmapGenerator
-	{
-		byte[] generateBitmap(int foreground, int background, int paletteSize)
-				throws IOException, ImageWriteException;
-	}
-
-	private class GeneratorFor1BitBitmaps implements BitmapGenerator
-	{
-		public byte[] generateBitmap(int foreground, int background, int paletteSize)
-				throws IOException, ImageWriteException
-		{
-			ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
-			BinaryOutputStream bos = new BinaryOutputStream(byteArrayStream,
-					BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
-			// Palette
-			bos.write3Bytes(background);
-			bos.write(0);
-			bos.write3Bytes(foreground);
-			bos.write(0);
-			for (int i = 2; i < paletteSize; i++)
-				bos.write4Bytes(0);
-			// Image
-			for (int y = 15; y >= 0; y--)
-			{
-				for (int x = 0; x < 16; x += 8)
-				{
-					bos.write(
-						((0x1 & image[y][x]) << 7) |
-						((0x1 & image[y][x+1]) << 6) |
-						((0x1 & image[y][x+2]) << 5) |
-						((0x1 & image[y][x+3]) << 4) |
-						((0x1 & image[y][x+4]) << 3) |
-						((0x1 & image[y][x+5]) << 2) |
-						((0x1 & image[y][x+6]) << 1) |
-						((0x1 & image[y][x+7]) << 0));
-				}
-				// Pad to multiple of 32 bytes
-				bos.write(0);
-				bos.write(0);
-			}
-			// Mask
-			for (int y = image.length - 1; y >= 0; y--)
-			{
-				bos.write(0);
-				bos.write(0);
-				// Pad to 4 bytes:
-				bos.write(0);
-				bos.write(0);
-			}
-			bos.flush();
-			return byteArrayStream.toByteArray();
-		}
-	}
-
-	private class GeneratorFor4BitBitmaps implements BitmapGenerator
-	{
-		public byte[] generateBitmap(int foreground, int background, int paletteSize)
-				throws IOException, ImageWriteException
-		{
-			ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
-			BinaryOutputStream bos = new BinaryOutputStream(byteArrayStream,
-					BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
-			// Palette
-			bos.write3Bytes(background);
-			bos.write(0);
-			bos.write3Bytes(foreground);
-			bos.write(0);
-			for (int i = 2; i < paletteSize; i++)
-				bos.write4Bytes(0);
-			// Image
-			for (int y = 15; y >= 0; y--)
-			{
-				for (int x = 0; x < 16; x += 2)
-				{
-					bos.write(((0xf & image[y][x]) << 4) |
-						(0xf & image[y][x+1]));
-				}
-			}
-			// Mask
-			for (int y = image.length - 1; y >= 0; y--)
-			{
-				bos.write(0);
-				bos.write(0);
-				// Pad to 4 bytes:
-				bos.write(0);
-				bos.write(0);
-			}
-			bos.flush();
-			return byteArrayStream.toByteArray();
-		}
-	}
-
-	private class GeneratorFor8BitBitmaps implements BitmapGenerator
-	{
-		public byte[] generateBitmap(int foreground, int background, int paletteSize)
-				throws IOException, ImageWriteException
-		{
-			ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
-			BinaryOutputStream bos = new BinaryOutputStream(byteArrayStream,
-					BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
-			// Palette
-			bos.write3Bytes(background);
-			bos.write(0);
-			bos.write3Bytes(foreground);
-			bos.write(0);
-			for (int i = 2; i < paletteSize; i++)
-				bos.write4Bytes(0);
-			// Image
-			for (int y = 15; y >= 0; y--)
-			{
-				for (int x = 0; x < 16; x++)
-				{
-					bos.write(image[y][x]);
-				}
-			}
-			// Mask
-			for (int y = image.length - 1; y >= 0; y--)
-			{
-				bos.write(0);
-				bos.write(0);
-				// Pad to 4 bytes:
-				bos.write(0);
-				bos.write(0);
-			}
-			bos.flush();
-			return byteArrayStream.toByteArray();
-		}
-	}
-
-	private class GeneratorFor16BitBitmaps implements BitmapGenerator
-	{
-		public byte[] generateBitmap(int foreground, int background, int paletteSize)
-				throws IOException, ImageWriteException
-		{
-			ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
-			BinaryOutputStream bos = new BinaryOutputStream(byteArrayStream,
-					BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
-			// Palette
-			for (int i = 0; i < paletteSize; i++)
-				bos.write4Bytes(0);
-			// Image
-			for (int y = 15; y >= 0; y--)
-			{
-				for (int x = 0; x < 16; x++)
-				{
-					if (image[y][x] == 1)
-						bos.write2Bytes((0x1f & (foreground >> 3)) |
-								((0x1f & (foreground >> 11)) << 5) |
-								((0x1f & (foreground >> 19)) << 10));
-					else
-						bos.write2Bytes((0x1f & (background >> 3)) |
-								((0x1f & (background >> 11)) << 5) |
-								((0x1f & (background >> 19)) << 10));
-				}
-			}
-			// Mask
-			for (int y = image.length - 1; y >= 0; y--)
-			{
-				bos.write(0);
-				bos.write(0);
-				// Pad to 4 bytes:
-				bos.write(0);
-				bos.write(0);
-			}
-			bos.flush();
-			return byteArrayStream.toByteArray();
-		}
-	}
-
-	private class GeneratorFor24BitBitmaps implements BitmapGenerator
-	{
-		public byte[] generateBitmap(int foreground, int background, int paletteSize)
-				throws IOException, ImageWriteException
-		{
-			ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
-			BinaryOutputStream bos = new BinaryOutputStream(byteArrayStream,
-					BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
-			// Palette
-			for (int i = 0; i < paletteSize; i++)
-				bos.write4Bytes(0);
-			// Image
-			for (int y = 15; y >= 0; y--)
-			{
-				for (int x = 0; x < 16; x++)
-				{
-					if (image[y][x] == 1)
-						bos.write3Bytes(0xffffff & foreground);
-					else
-						bos.write3Bytes(0xffffff & background);
-				}
-			}
-			// Mask
-			for (int y = image.length - 1; y >= 0; y--)
-			{
-				bos.write(0);
-				bos.write(0);
-				// Pad to 4 bytes:
-				bos.write(0);
-				bos.write(0);
-			}
-			bos.flush();
-			return byteArrayStream.toByteArray();
-		}
-	}
-
-	private class GeneratorFor32BitBitmaps implements BitmapGenerator
-	{
-		public byte[] generateBitmap(int foreground, int background, int paletteSize)
-				throws IOException, ImageWriteException
-		{
-			return generate32bitRGBABitmap(foreground, background, paletteSize, true);
-		}
-
-		public byte[] generate32bitRGBABitmap(int foreground, int background,
-				int paletteSize, boolean writeMask) throws IOException,
-				ImageWriteException
-		{
-			ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
-			BinaryOutputStream bos = new BinaryOutputStream(byteArrayStream,
-					BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
-			// Palette
-			for (int i = 0; i < paletteSize; i++)
-				bos.write4Bytes(0);
-			// Image
-			for (int y = 15; y >= 0; y--)
-			{
-				for (int x = 0; x < 16; x++)
-				{
-					if (image[y][x] == 1)
-						bos.write4Bytes(foreground);
-					else
-						bos.write4Bytes(background);
-				}
-			}
-			// Mask
-			if (writeMask)
-			{
-				for (int y = image.length - 1; y >= 0; y--)
-				{
-					bos.write(0);
-					bos.write(0);
-					// Pad to 4 bytes:
-					bos.write(0);
-					bos.write(0);
-				}
-			}
-			bos.flush();
-			return byteArrayStream.toByteArray();
-		}
-	}
-
-	private void writeICONDIR(BinaryOutputStream bos, int reserved, int type, int count)
-			throws IOException, ImageWriteException
-	{
-		bos.write2Bytes(reserved);
-		bos.write2Bytes(type);
-		bos.write2Bytes(count);
-	}
-
-	private void writeICONDIRENTRY(BinaryOutputStream bos, int width, int height,
-			int colorCount, int reserved, int planes, int bitCount, int bytesInRes)
-			throws IOException, ImageWriteException
-	{
-		bos.write(width);
-		bos.write(height);
-		bos.write(colorCount);
-		bos.write(reserved);
-		bos.write2Bytes(planes);
-		bos.write2Bytes(bitCount);
-		bos.write4Bytes(bytesInRes);
-		bos.write4Bytes(22); // image comes immediately after this
-	}
-
-	private void writeBITMAPINFOHEADER(BinaryOutputStream bos, int width, int height,
-			int colorPlanes, int bitCount, int compression, int colorsUsed,
-			int colorsImportant) throws IOException, ImageWriteException
-	{
-		// BITMAPINFOHEADER
-		bos.write4Bytes(40); // biSize, always 40 for BITMAPINFOHEADER
-		bos.write4Bytes(width); // biWidth
-		bos.write4Bytes(height); // biHeight
-		bos.write2Bytes(colorPlanes); // biPlanes
-		bos.write2Bytes(bitCount); // bitCount
-		bos.write4Bytes(compression); // biCompression
-		bos.write4Bytes(0); // biSizeImage, can be 0 for uncompressed
-		bos.write4Bytes(0); // X pixels per metre
-		bos.write4Bytes(0); // Y pixels per metre
-		bos.write4Bytes(colorsUsed); // colors used, ignored
-		bos.write4Bytes(colorsImportant); // colors important
-	}
-
-	public void testNormalIcons() throws IOException, ImageWriteException, ImageReadException
-	{
-		final int foreground = 0xFFF000E0;
-		final int background = 0xFF102030;
-		for (Iterator it = generatorMap.entrySet().iterator(); it.hasNext(); )
-		{
-			Map.Entry entry = (Map.Entry) it.next();
-			int bitDepth = ((Integer)entry.getKey()).intValue();
-			BitmapGenerator bitmapGenerator = (BitmapGenerator) entry.getValue();
-
-			ByteArrayOutputStream baos = new ByteArrayOutputStream();
-			BinaryOutputStream bos = new BinaryOutputStream(baos,
-					BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
-			byte[] bitmap = bitmapGenerator.generateBitmap(foreground, background,
-					(bitDepth <= 8) ? (1 << bitDepth) : 0);
-			writeICONDIR(bos, 0, 1, 1);
-			writeICONDIRENTRY(bos, 16, 16, 0, 0, 1, bitDepth, 40 + bitmap.length);
-			writeBITMAPINFOHEADER(bos, 16, 2*16, 1, bitDepth, 0, 0, 0);
-			bos.write(bitmap);
-			bos.flush();
-			writeAndReadImageData("16x16x" + bitDepth, baos.toByteArray(), foreground, background);
-		}
-	}
-
-	public void testBadICONDIRENTRYIcons() throws IOException, ImageWriteException, ImageReadException
-	{
-		final int foreground = 0xFFF000E0;
-		final int background = 0xFF102030;
-		// Windows ignores the ICONDIRENTRY values when parsing the ICO file.
-		for (Iterator it = generatorMap.entrySet().iterator(); it.hasNext(); )
-		{
-			Map.Entry entry = (Map.Entry) it.next();
-			int bitDepth = ((Integer)entry.getKey()).intValue();
-			BitmapGenerator bitmapGenerator = (BitmapGenerator) entry.getValue();
-
-			ByteArrayOutputStream baos = new ByteArrayOutputStream();
-			BinaryOutputStream bos = new BinaryOutputStream(baos,
-					BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
-			byte[] bitmap = bitmapGenerator.generateBitmap(foreground, background,
-					(bitDepth <= 8) ? (1 << bitDepth) : 0);
-			writeICONDIR(bos, 0, 1, 1);
-			writeICONDIRENTRY(bos, 3 /* width, should be 16 */,
-					4 /* height, should be 16 */,
-					7 /* colorCount, should be 2 or 0 */,
-					20 /* reserved, should be 0 */,
-					11 /* planes, should be 1 or 0 */,
-					19 /* bitCount, should be bitDepth */,
-					40 + bitmap.length);
-			writeBITMAPINFOHEADER(bos, 16, 2*16, 1, bitDepth, 0, 0, 0);
-			bos.write(bitmap);
-			bos.flush();
-			writeAndReadImageData("16x16x" + bitDepth + "-corrupt-icondirentry",
-					baos.toByteArray(), foreground, background);
-		}
-	}
-
-	public void testColorsUsed() throws IOException, ImageWriteException, ImageReadException
-	{
-		final int foreground = 0xFFF000E0;
-		final int background = 0xFF102030;
-		for (Iterator it = generatorMap.entrySet().iterator(); it.hasNext(); )
-		{
-			Map.Entry entry = (Map.Entry) it.next();
-			int bitDepth = ((Integer)entry.getKey()).intValue();
-			BitmapGenerator bitmapGenerator = (BitmapGenerator) entry.getValue();
-
-			ByteArrayOutputStream baos = new ByteArrayOutputStream();
-			BinaryOutputStream bos = new BinaryOutputStream(baos,
-					BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
-			byte[] bitmap = bitmapGenerator.generateBitmap(foreground, background, 2);
-			writeICONDIR(bos, 0, 1, 1);
-			writeICONDIRENTRY(bos, 3, 4, 7, 20, 11, 19, 40 + bitmap.length);
-			writeBITMAPINFOHEADER(bos, 16, 2*16, 1, bitDepth, 0, 2, 0);
-			bos.write(bitmap);
-			bos.flush();
-			writeAndReadImageData("16x16x" + bitDepth + "-custom-palette",
-					baos.toByteArray(), foreground, background);
-		}
-	}
-
-	public void testZeroColorPlanes() throws IOException, ImageWriteException
-	{
-		final int foreground = 0xFFF000E0;
-		final int background = 0xFF102030;
-		for (Iterator it = generatorMap.entrySet().iterator(); it.hasNext(); )
-		{
-			Map.Entry entry = (Map.Entry) it.next();
-			int bitDepth = ((Integer)entry.getKey()).intValue();
-			BitmapGenerator bitmapGenerator = (BitmapGenerator) entry.getValue();
-
-			ByteArrayOutputStream baos = new ByteArrayOutputStream();
-			BinaryOutputStream bos = new BinaryOutputStream(baos,
-					BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
-			byte[] bitmap = bitmapGenerator.generateBitmap(foreground, background,
-					(bitDepth <= 8) ? (1 << bitDepth) : 0);
-			writeICONDIR(bos, 0, 1, 1);
-			writeICONDIRENTRY(bos, 16, 16, 0, 0, 1, bitDepth, 40 + bitmap.length);
-			writeBITMAPINFOHEADER(bos, 16, 2*16, 0 /* should be 1 */, bitDepth, 0, 0, 0);
-			bos.write(bitmap);
-			bos.flush();
-
-			boolean threw = false;
-			try
-			{
-				writeAndReadImageData("16x16x" + bitDepth + "-zero-colorPlanes",
-						baos.toByteArray(), foreground, background);
-			}
-			catch (ImageReadException imageReadException)
-			{
-				threw = true;
-			}
-			assertTrue(threw);
-		}
-	}
-
-	public void testBitfieldCompression() throws IOException, ImageWriteException, ImageReadException
-	{
-		ByteArrayOutputStream baos = new ByteArrayOutputStream();
-		BinaryOutputStream bos = new BinaryOutputStream(baos,
-				BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
-		byte[] bitmap = new GeneratorFor32BitBitmaps().generate32bitRGBABitmap(
-				0xFFFF0000, 0xFFFFFFFF, 0, true);
-		writeICONDIR(bos, 0, 1, 1);
-		writeICONDIRENTRY(bos, 16, 16, 0, 0, 1, 32, 40 + bitmap.length);
-		writeBITMAPINFOHEADER(bos, 16, 2*16, 1, 32, 3 /* BI_BITFIELDS */, 0, 0);
-		bos.write4Bytes(0x000000FF); // red mask
-		bos.write4Bytes(0x0000FF00); // green mask
-		bos.write4Bytes(0x00FF0000); // blue mask
-		bos.write(bitmap);
-		bos.flush();
-		writeAndReadImageData("16x16x32-bitfield-compressed", baos.toByteArray(),
-				0xFF0000FF, 0xFFFFFFFF);
-	}
-
-	public void test32bitMask() throws IOException, ImageWriteException, ImageReadException
-	{
-		final int foreground = 0xFFF000E0;
-		final int background = 0xFF102030;
-		ByteArrayOutputStream baos = new ByteArrayOutputStream();
-		BinaryOutputStream bos = new BinaryOutputStream(baos,
-				BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
-		// For 32 bit RGBA, the AND mask can be missing:
-		byte[] bitmap = new GeneratorFor32BitBitmaps().generate32bitRGBABitmap(
-				foreground, background, 0, false);
-		writeICONDIR(bos, 0, 1, 1);
-		writeICONDIRENTRY(bos, 16, 16, 0, 0, 1, 32, 40 + bitmap.length);
-		writeBITMAPINFOHEADER(bos, 16, 2*16, 1, 32, 0, 0, 0);
-		bos.write(bitmap);
-		bos.flush();
-		writeAndReadImageData("16x16x32-no-mask", baos.toByteArray(), foreground, background);
-	}
-
-	// FIXME: get the BMP decoder to support alpha, then uncomment below
-//	public void testAlphaVersusANDMask() throws IOException, ImageWriteException, ImageReadException
-//	{
-//		ByteArrayOutputStream baos = new ByteArrayOutputStream();
-//		BinaryOutputStream bos = new BinaryOutputStream(baos,
-//				BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
-//		byte[] bitmap = new GeneratorFor32BitBitmaps().generate32bitRGBABitmap(
-//				0xFF000000, 0x00000000, 0, true);
-//		writeICONDIR(bos, 0, 1, 1);
-//		writeICONDIRENTRY(bos, 16, 16, 0, 0, 1, 32, 40 + bitmap.length);
-//		writeBITMAPINFOHEADER(bos, 16, 2*16, 1, 32, 0, 0, 0);
-//		bos.write(bitmap);
-//		bos.flush();
-//		// The AND mask is fully opaque, yet the fully transparent alpha should win:
-//		writeAndReadImageData("16x16x32-alpha-vs-mask", baos.toByteArray(),
-//				0xFF000000, 0x00000000);
-//	}
-
-	public void testFullyTransparent32bitRGBA() throws IOException, ImageWriteException, ImageReadException
-	{
-		ByteArrayOutputStream baos = new ByteArrayOutputStream();
-		BinaryOutputStream bos = new BinaryOutputStream(baos,
-				BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
-		byte[] bitmap = new GeneratorFor32BitBitmaps().generate32bitRGBABitmap(
-				0x00000000, 0x00FFFFFF, 0, true);
-		writeICONDIR(bos, 0, 1, 1);
-		writeICONDIRENTRY(bos, 16, 16, 0, 0, 1, 32, 40 + bitmap.length);
-		writeBITMAPINFOHEADER(bos, 16, 2*16, 1, 32, 0, 0, 0);
-		bos.write(bitmap);
-		bos.flush();
-		// Because every pixel is fully trasparent, ***ALPHA GETS IGNORED***:
-		writeAndReadImageData("16x16x32-fully-transparent", baos.toByteArray(),
-				0xFF000000, 0xFFFFFFFF);
-	}
-
-	private void writeAndReadImageData(String description, byte[] rawData,
-			int foreground, int background) throws IOException,
-			ImageReadException
-	{
-		// Uncomment to generate ICO files that can be tested with Windows:
-		//File exportFile = new File("/tmp/" + description + ".ico");
-		//IOUtils.writeToFile(rawData, exportFile);
-
-		File tempFile = createTempFile("temp", ".ico");
-		IOUtils.writeToFile(rawData, tempFile);
-
-		BufferedImage dstImage = Sanselan.getBufferedImage(tempFile);
-
-		assertNotNull(dstImage);
-		assertTrue(dstImage.getWidth() == image[0].length);
-		assertTrue(dstImage.getHeight() == image.length);
-
-		verify(dstImage, foreground, background);
-	}
-
-	private void verify(BufferedImage data, int foreground, int background)
-	{
-		assertNotNull(data);
-		assertTrue(data.getHeight() == image.length);
-
-		for (int y = 0; y < data.getHeight(); y++)
-		{
-			assertTrue(data.getWidth() == image[y].length);
-			for (int x = 0; x < data.getWidth(); x++)
-			{
-				int imageARGB = (image[y][x] == 1) ? foreground : background;
-				int dataARGB = data.getRGB(x, y);
-
-				if (imageARGB != dataARGB)
-				{
-					Debug.debug("x: " + x + ", y: " + y + ", image: " + imageARGB
-							+ " (0x" + Integer.toHexString(imageARGB) + ")"
-							+ ", data: " + dataARGB + " (0x"
-							+ Integer.toHexString(dataARGB) + ")");
-				}
-				assertTrue(imageARGB == dataARGB);
-			}
-		}
-	}
+    // 16x16 test image
+    private static final int[][] image = {
+        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+        {0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,0},
+        {0,0,0,1,1,0,0,0,0,1,0,0,1,0,0,0},
+        {0,0,1,0,1,0,0,0,1,0,0,0,0,1,0,0},
+        {0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0},
+        {0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0},
+        {0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0},
+        {0,0,0,0,1,0,0,0,1,0,1,1,1,0,0,0},
+        {0,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0},
+        {0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0},
+        {0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0},
+        {0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0},
+        {0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,0},
+        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
+    };
+
+    private Map generatorMap = new HashMap();
+
+    public IcoRoundtripTest()
+    {
+        generatorMap.put(Integer.valueOf(1), new GeneratorFor1BitBitmaps());
+        generatorMap.put(Integer.valueOf(4), new GeneratorFor4BitBitmaps());
+        generatorMap.put(Integer.valueOf(8), new GeneratorFor8BitBitmaps());
+        generatorMap.put(Integer.valueOf(16), new GeneratorFor16BitBitmaps());
+        generatorMap.put(Integer.valueOf(24), new GeneratorFor24BitBitmaps());
+        generatorMap.put(Integer.valueOf(32), new GeneratorFor32BitBitmaps());
+    }
+
+    private static interface BitmapGenerator
+    {
+        byte[] generateBitmap(int foreground, int background, int paletteSize)
+                throws IOException, ImageWriteException;
+    }
+
+    private class GeneratorFor1BitBitmaps implements BitmapGenerator
+    {
+        public byte[] generateBitmap(int foreground, int background, int paletteSize)
+                throws IOException, ImageWriteException
+        {
+            ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
+            BinaryOutputStream bos = new BinaryOutputStream(byteArrayStream,
+                    BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
+            // Palette
+            bos.write3Bytes(background);
+            bos.write(0);
+            bos.write3Bytes(foreground);
+            bos.write(0);
+            for (int i = 2; i < paletteSize; i++)
+                bos.write4Bytes(0);
+            // Image
+            for (int y = 15; y >= 0; y--)
+            {
+                for (int x = 0; x < 16; x += 8)
+                {
+                    bos.write(
+                        ((0x1 & image[y][x]) << 7) |
+                        ((0x1 & image[y][x+1]) << 6) |
+                        ((0x1 & image[y][x+2]) << 5) |
+                        ((0x1 & image[y][x+3]) << 4) |
+                        ((0x1 & image[y][x+4]) << 3) |
+                        ((0x1 & image[y][x+5]) << 2) |
+                        ((0x1 & image[y][x+6]) << 1) |
+                        ((0x1 & image[y][x+7]) << 0));
+                }
+                // Pad to multiple of 32 bytes
+                bos.write(0);
+                bos.write(0);
+            }
+            // Mask
+            for (int y = image.length - 1; y >= 0; y--)
+            {
+                bos.write(0);
+                bos.write(0);
+                // Pad to 4 bytes:
+                bos.write(0);
+                bos.write(0);
+            }
+            bos.flush();
+            return byteArrayStream.toByteArray();
+        }
+    }
+
+    private class GeneratorFor4BitBitmaps implements BitmapGenerator
+    {
+        public byte[] generateBitmap(int foreground, int background, int paletteSize)
+                throws IOException, ImageWriteException
+        {
+            ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
+            BinaryOutputStream bos = new BinaryOutputStream(byteArrayStream,
+                    BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
+            // Palette
+            bos.write3Bytes(background);
+            bos.write(0);
+            bos.write3Bytes(foreground);
+            bos.write(0);
+            for (int i = 2; i < paletteSize; i++)
+                bos.write4Bytes(0);
+            // Image
+            for (int y = 15; y >= 0; y--)
+            {
+                for (int x = 0; x < 16; x += 2)
+                {
+                    bos.write(((0xf & image[y][x]) << 4) |
+                        (0xf & image[y][x+1]));
+                }
+            }
+            // Mask
+            for (int y = image.length - 1; y >= 0; y--)
+            {
+                bos.write(0);
+                bos.write(0);
+                // Pad to 4 bytes:
+                bos.write(0);
+                bos.write(0);
+            }
+            bos.flush();
+            return byteArrayStream.toByteArray();
+        }
+    }
+
+    private class GeneratorFor8BitBitmaps implements BitmapGenerator
+    {
+        public byte[] generateBitmap(int foreground, int background, int paletteSize)
+                throws IOException, ImageWriteException
+        {
+            ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
+            BinaryOutputStream bos = new BinaryOutputStream(byteArrayStream,
+                    BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
+            // Palette
+            bos.write3Bytes(background);
+            bos.write(0);
+            bos.write3Bytes(foreground);
+            bos.write(0);
+            for (int i = 2; i < paletteSize; i++)
+                bos.write4Bytes(0);
+            // Image
+            for (int y = 15; y >= 0; y--)
+            {
+                for (int x = 0; x < 16; x++)
+                {
+                    bos.write(image[y][x]);
+                }
+            }
+            // Mask
+            for (int y = image.length - 1; y >= 0; y--)
+            {
+                bos.write(0);
+                bos.write(0);
+                // Pad to 4 bytes:
+                bos.write(0);
+                bos.write(0);
+            }
+            bos.flush();
+            return byteArrayStream.toByteArray();
+        }
+    }
+
+    private class GeneratorFor16BitBitmaps implements BitmapGenerator
+    {
+        public byte[] generateBitmap(int foreground, int background, int paletteSize)
+                throws IOException, ImageWriteException
+        {
+            ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
+            BinaryOutputStream bos = new BinaryOutputStream(byteArrayStream,
+                    BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
+            // Palette
+            for (int i = 0; i < paletteSize; i++)
+                bos.write4Bytes(0);
+            // Image
+            for (int y = 15; y >= 0; y--)
+            {
+                for (int x = 0; x < 16; x++)
+                {
+                    if (image[y][x] == 1)
+                        bos.write2Bytes((0x1f & (foreground >> 3)) |
+                                ((0x1f & (foreground >> 11)) << 5) |
+                                ((0x1f & (foreground >> 19)) << 10));
+                    else
+                        bos.write2Bytes((0x1f & (background >> 3)) |
+                                ((0x1f & (background >> 11)) << 5) |
+                                ((0x1f & (background >> 19)) << 10));
+                }
+            }
+            // Mask
+            for (int y = image.length - 1; y >= 0; y--)
+            {
+                bos.write(0);
+                bos.write(0);
+                // Pad to 4 bytes:
+                bos.write(0);
+                bos.write(0);
+            }
+            bos.flush();
+            return byteArrayStream.toByteArray();
+        }
+    }
+
+    private class GeneratorFor24BitBitmaps implements BitmapGenerator
+    {
+        public byte[] generateBitmap(int foreground, int background, int paletteSize)
+                throws IOException, ImageWriteException
+        {
+            ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
+            BinaryOutputStream bos = new BinaryOutputStream(byteArrayStream,
+                    BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
+            // Palette
+            for (int i = 0; i < paletteSize; i++)
+                bos.write4Bytes(0);
+            // Image
+            for (int y = 15; y >= 0; y--)
+            {
+                for (int x = 0; x < 16; x++)
+                {
+                    if (image[y][x] == 1)
+                        bos.write3Bytes(0xffffff & foreground);
+                    else
+                        bos.write3Bytes(0xffffff & background);
+                }
+            }
+            // Mask
+            for (int y = image.length - 1; y >= 0; y--)
+            {
+                bos.write(0);
+                bos.write(0);
+                // Pad to 4 bytes:
+                bos.write(0);
+                bos.write(0);
+            }
+            bos.flush();
+            return byteArrayStream.toByteArray();
+        }
+    }
+
+    private class GeneratorFor32BitBitmaps implements BitmapGenerator
+    {
+        public byte[] generateBitmap(int foreground, int background, int paletteSize)
+                throws IOException, ImageWriteException
+        {
+            return generate32bitRGBABitmap(foreground, background, paletteSize, true);
+        }
+
+        public byte[] generate32bitRGBABitmap(int foreground, int background,
+                int paletteSize, boolean writeMask) throws IOException,
+                ImageWriteException
+        {
+            ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
+            BinaryOutputStream bos = new BinaryOutputStream(byteArrayStream,
+                    BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
+            // Palette
+            for (int i = 0; i < paletteSize; i++)
+                bos.write4Bytes(0);
+            // Image
+            for (int y = 15; y >= 0; y--)
+            {
+                for (int x = 0; x < 16; x++)
+                {
+                    if (image[y][x] == 1)
+                        bos.write4Bytes(foreground);
+                    else
+                        bos.write4Bytes(background);
+                }
+            }
+            // Mask
+            if (writeMask)
+            {
+                for (int y = image.length - 1; y >= 0; y--)
+                {
+                    bos.write(0);
+                    bos.write(0);
+                    // Pad to 4 bytes:
+                    bos.write(0);
+                    bos.write(0);
+                }
+            }
+            bos.flush();
+            return byteArrayStream.toByteArray();
+        }
+    }
+
+    private void writeICONDIR(BinaryOutputStream bos, int reserved, int type, int count)
+            throws IOException, ImageWriteException
+    {
+        bos.write2Bytes(reserved);
+        bos.write2Bytes(type);
+        bos.write2Bytes(count);
+    }
+
+    private void writeICONDIRENTRY(BinaryOutputStream bos, int width, int height,
+            int colorCount, int reserved, int planes, int bitCount, int bytesInRes)
+            throws IOException, ImageWriteException
+    {
+        bos.write(width);
+        bos.write(height);
+        bos.write(colorCount);
+        bos.write(reserved);
+        bos.write2Bytes(planes);
+        bos.write2Bytes(bitCount);
+        bos.write4Bytes(bytesInRes);
+        bos.write4Bytes(22); // image comes immediately after this
+    }
+
+    private void writeBITMAPINFOHEADER(BinaryOutputStream bos, int width, int height,
+            int colorPlanes, int bitCount, int compression, int colorsUsed,
+            int colorsImportant) throws IOException, ImageWriteException
+    {
+        // BITMAPINFOHEADER
+        bos.write4Bytes(40); // biSize, always 40 for BITMAPINFOHEADER
+        bos.write4Bytes(width); // biWidth
+        bos.write4Bytes(height); // biHeight
+        bos.write2Bytes(colorPlanes); // biPlanes
+        bos.write2Bytes(bitCount); // bitCount
+        bos.write4Bytes(compression); // biCompression
+        bos.write4Bytes(0); // biSizeImage, can be 0 for uncompressed
+        bos.write4Bytes(0); // X pixels per metre
+        bos.write4Bytes(0); // Y pixels per metre
+        bos.write4Bytes(colorsUsed); // colors used, ignored
+        bos.write4Bytes(colorsImportant); // colors important
+    }
+
+    public void testNormalIcons() throws IOException, ImageWriteException, ImageReadException
+    {
+        final int foreground = 0xFFF000E0;
+        final int background = 0xFF102030;
+        for (Iterator it = generatorMap.entrySet().iterator(); it.hasNext(); )
+        {
+            Map.Entry entry = (Map.Entry) it.next();
+            int bitDepth = ((Integer)entry.getKey()).intValue();
+            BitmapGenerator bitmapGenerator = (BitmapGenerator) entry.getValue();
+
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            BinaryOutputStream bos = new BinaryOutputStream(baos,
+                    BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
+            byte[] bitmap = bitmapGenerator.generateBitmap(foreground, background,
+                    (bitDepth <= 8) ? (1 << bitDepth) : 0);
+            writeICONDIR(bos, 0, 1, 1);
+            writeICONDIRENTRY(bos, 16, 16, 0, 0, 1, bitDepth, 40 + bitmap.length);
+            writeBITMAPINFOHEADER(bos, 16, 2*16, 1, bitDepth, 0, 0, 0);
+            bos.write(bitmap);
+            bos.flush();
+            writeAndReadImageData("16x16x" + bitDepth, baos.toByteArray(), foreground, background);
+        }
+    }
+
+    public void testBadICONDIRENTRYIcons() throws IOException, ImageWriteException, ImageReadException
+    {
+        final int foreground = 0xFFF000E0;
+        final int background = 0xFF102030;
+        // Windows ignores the ICONDIRENTRY values when parsing the ICO file.
+        for (Iterator it = generatorMap.entrySet().iterator(); it.hasNext(); )
+        {
+            Map.Entry entry = (Map.Entry) it.next();
+            int bitDepth = ((Integer)entry.getKey()).intValue();
+            BitmapGenerator bitmapGenerator = (BitmapGenerator) entry.getValue();
+
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            BinaryOutputStream bos = new BinaryOutputStream(baos,
+                    BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
+            byte[] bitmap = bitmapGenerator.generateBitmap(foreground, background,
+                    (bitDepth <= 8) ? (1 << bitDepth) : 0);
+            writeICONDIR(bos, 0, 1, 1);
+            writeICONDIRENTRY(bos, 3 /* width, should be 16 */,
+                    4 /* height, should be 16 */,
+                    7 /* colorCount, should be 2 or 0 */,
+                    20 /* reserved, should be 0 */,
+                    11 /* planes, should be 1 or 0 */,
+                    19 /* bitCount, should be bitDepth */,
+                    40 + bitmap.length);
+            writeBITMAPINFOHEADER(bos, 16, 2*16, 1, bitDepth, 0, 0, 0);
+            bos.write(bitmap);
+            bos.flush();
+            writeAndReadImageData("16x16x" + bitDepth + "-corrupt-icondirentry",
+                    baos.toByteArray(), foreground, background);
+        }
+    }
+
+    public void testColorsUsed() throws IOException, ImageWriteException, ImageReadException
+    {
+        final int foreground = 0xFFF000E0;
+        final int background = 0xFF102030;
+        for (Iterator it = generatorMap.entrySet().iterator(); it.hasNext(); )
+        {
+            Map.Entry entry = (Map.Entry) it.next();
+            int bitDepth = ((Integer)entry.getKey()).intValue();
+            BitmapGenerator bitmapGenerator = (BitmapGenerator) entry.getValue();
+
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            BinaryOutputStream bos = new BinaryOutputStream(baos,
+                    BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
+            byte[] bitmap = bitmapGenerator.generateBitmap(foreground, background, 2);
+            writeICONDIR(bos, 0, 1, 1);
+            writeICONDIRENTRY(bos, 3, 4, 7, 20, 11, 19, 40 + bitmap.length);
+            writeBITMAPINFOHEADER(bos, 16, 2*16, 1, bitDepth, 0, 2, 0);
+            bos.write(bitmap);
+            bos.flush();
+            writeAndReadImageData("16x16x" + bitDepth + "-custom-palette",
+                    baos.toByteArray(), foreground, background);
+        }
+    }
+
+    public void testZeroColorPlanes() throws IOException, ImageWriteException
+    {
+        final int foreground = 0xFFF000E0;
+        final int background = 0xFF102030;
+        for (Iterator it = generatorMap.entrySet().iterator(); it.hasNext(); )
+        {
+            Map.Entry entry = (Map.Entry) it.next();
+            int bitDepth = ((Integer)entry.getKey()).intValue();
+            BitmapGenerator bitmapGenerator = (BitmapGenerator) entry.getValue();
+
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            BinaryOutputStream bos = new BinaryOutputStream(baos,
+                    BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
+            byte[] bitmap = bitmapGenerator.generateBitmap(foreground, background,
+                    (bitDepth <= 8) ? (1 << bitDepth) : 0);
+            writeICONDIR(bos, 0, 1, 1);
+            writeICONDIRENTRY(bos, 16, 16, 0, 0, 1, bitDepth, 40 + bitmap.length);
+            writeBITMAPINFOHEADER(bos, 16, 2*16, 0 /* should be 1 */, bitDepth, 0, 0, 0);
+            bos.write(bitmap);
+            bos.flush();
+
+            boolean threw = false;
+            try
+            {
+                writeAndReadImageData("16x16x" + bitDepth + "-zero-colorPlanes",
+                        baos.toByteArray(), foreground, background);
+            }
+            catch (ImageReadException imageReadException)
+            {
+                threw = true;
+            }
+            assertTrue(threw);
+        }
+    }
+
+    public void testBitfieldCompression() throws IOException, ImageWriteException, ImageReadException
+    {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        BinaryOutputStream bos = new BinaryOutputStream(baos,
+                BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
+        byte[] bitmap = new GeneratorFor32BitBitmaps().generate32bitRGBABitmap(
+                0xFFFF0000, 0xFFFFFFFF, 0, true);
+        writeICONDIR(bos, 0, 1, 1);
+        writeICONDIRENTRY(bos, 16, 16, 0, 0, 1, 32, 40 + bitmap.length);
+        writeBITMAPINFOHEADER(bos, 16, 2*16, 1, 32, 3 /* BI_BITFIELDS */, 0, 0);
+        bos.write4Bytes(0x000000FF); // red mask
+        bos.write4Bytes(0x0000FF00); // green mask
+        bos.write4Bytes(0x00FF0000); // blue mask
+        bos.write(bitmap);
+        bos.flush();
+        writeAndReadImageData("16x16x32-bitfield-compressed", baos.toByteArray(),
+                0xFF0000FF, 0xFFFFFFFF);
+    }
+
+    public void test32bitMask() throws IOException, ImageWriteException, ImageReadException
+    {
+        final int foreground = 0xFFF000E0;
+        final int background = 0xFF102030;
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        BinaryOutputStream bos = new BinaryOutputStream(baos,
+                BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
+        // For 32 bit RGBA, the AND mask can be missing:
+        byte[] bitmap = new GeneratorFor32BitBitmaps().generate32bitRGBABitmap(
+                foreground, background, 0, false);
+        writeICONDIR(bos, 0, 1, 1);
+        writeICONDIRENTRY(bos, 16, 16, 0, 0, 1, 32, 40 + bitmap.length);
+        writeBITMAPINFOHEADER(bos, 16, 2*16, 1, 32, 0, 0, 0);
+        bos.write(bitmap);
+        bos.flush();
+        writeAndReadImageData("16x16x32-no-mask", baos.toByteArray(), foreground, background);
+    }
+
+    // FIXME: get the BMP decoder to support alpha, then uncomment below
+//    public void testAlphaVersusANDMask() throws IOException, ImageWriteException, ImageReadException
+//    {
+//        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+//        BinaryOutputStream bos = new BinaryOutputStream(baos,
+//                BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
+//        byte[] bitmap = new GeneratorFor32BitBitmaps().generate32bitRGBABitmap(
+//                0xFF000000, 0x00000000, 0, true);
+//        writeICONDIR(bos, 0, 1, 1);
+//        writeICONDIRENTRY(bos, 16, 16, 0, 0, 1, 32, 40 + bitmap.length);
+//        writeBITMAPINFOHEADER(bos, 16, 2*16, 1, 32, 0, 0, 0);
+//        bos.write(bitmap);
+//        bos.flush();
+//        // The AND mask is fully opaque, yet the fully transparent alpha should win:
+//        writeAndReadImageData("16x16x32-alpha-vs-mask", baos.toByteArray(),
+//                0xFF000000, 0x00000000);
+//    }
+
+    public void testFullyTransparent32bitRGBA() throws IOException, ImageWriteException, ImageReadException
+    {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        BinaryOutputStream bos = new BinaryOutputStream(baos,
+                BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);
+        byte[] bitmap = new GeneratorFor32BitBitmaps().generate32bitRGBABitmap(
+                0x00000000, 0x00FFFFFF, 0, true);
+        writeICONDIR(bos, 0, 1, 1);
+        writeICONDIRENTRY(bos, 16, 16, 0, 0, 1, 32, 40 + bitmap.length);
+        writeBITMAPINFOHEADER(bos, 16, 2*16, 1, 32, 0, 0, 0);
+        bos.write(bitmap);
+        bos.flush();
+        // Because every pixel is fully trasparent, ***ALPHA GETS IGNORED***:
+        writeAndReadImageData("16x16x32-fully-transparent", baos.toByteArray(),
+                0xFF000000, 0xFFFFFFFF);
+    }
+
+    private void writeAndReadImageData(String description, byte[] rawData,
+            int foreground, int background) throws IOException,
+            ImageReadException
+    {
+        // Uncomment to generate ICO files that can be tested with Windows:
+        //File exportFile = new File("/tmp/" + description + ".ico");
+        //IOUtils.writeToFile(rawData, exportFile);
+
+        File tempFile = createTempFile("temp", ".ico");
+        IOUtils.writeToFile(rawData, tempFile);
+
+        BufferedImage dstImage = Sanselan.getBufferedImage(tempFile);
+
+        assertNotNull(dstImage);
+        assertTrue(dstImage.getWidth() == image[0].length);
+        assertTrue(dstImage.getHeight() == image.length);
+
+        verify(dstImage, foreground, background);
+    }
+
+    private void verify(BufferedImage data, int foreground, int background)
+    {
+        assertNotNull(data);
+        assertTrue(data.getHeight() == image.length);
+
+        for (int y = 0; y < data.getHeight(); y++)
+        {
+            assertTrue(data.getWidth() == image[y].length);
+            for (int x = 0; x < data.getWidth(); x++)
+            {
+                int imageARGB = (image[y][x] == 1) ? foreground : background;
+                int dataARGB = data.getRGB(x, y);
+
+                if (imageARGB != dataARGB)
+                {
+                    Debug.debug("x: " + x + ", y: " + y + ", image: " + imageARGB
+                            + " (0x" + Integer.toHexString(imageARGB) + ")"
+                            + ", data: " + dataARGB + " (0x"
+                            + Integer.toHexString(dataARGB) + ")");
+                }
+                assertTrue(imageARGB == dataARGB);
+            }
+        }
+    }
 
 }

Modified: commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/JpegBaseTest.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/JpegBaseTest.java?rev=995634&r1=995633&r2=995634&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/JpegBaseTest.java (original)
+++ commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/JpegBaseTest.java Fri Sep 10 01:35:50 2010
@@ -29,26 +29,26 @@ import org.apache.sanselan.SanselanTest;
 public abstract class JpegBaseTest extends SanselanTest
 {
 
-	protected static boolean isJpeg(File file) throws IOException,
-			ImageReadException
-	{
-		ImageFormat format = Sanselan.guessFormat(file);
-		return format == ImageFormat.IMAGE_FORMAT_JPEG;
-	}
-
-	public static final ImageFilter imageFilter = new ImageFilter()
-	{
-		public boolean accept(File file) throws IOException, ImageReadException
-		{
-			return isJpeg(file);
-		}
-	};
+    protected static boolean isJpeg(File file) throws IOException,
+            ImageReadException
+    {
+        ImageFormat format = Sanselan.guessFormat(file);
+        return format == ImageFormat.IMAGE_FORMAT_JPEG;
+    }
+
+    public static final ImageFilter imageFilter = new ImageFilter()
+    {
+        public boolean accept(File file) throws IOException, ImageReadException
+        {
+            return isJpeg(file);
+        }
+    };
 
 
 
-	protected List getJpegImages() throws IOException, ImageReadException
-	{
-		return getTestImages(imageFilter);
-	}
+    protected List getJpegImages() throws IOException, ImageReadException
+    {
+        return getTestImages(imageFilter);
+    }
 
 }

Modified: commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/JpegReadTest.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/JpegReadTest.java?rev=995634&r1=995633&r2=995634&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/JpegReadTest.java (original)
+++ commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/JpegReadTest.java Fri Sep 10 01:35:50 2010
@@ -32,33 +32,33 @@ import org.apache.sanselan.util.Debug;
 public class JpegReadTest extends JpegBaseTest
 {
 
-	public void test() throws IOException, ImageReadException
-	{
-		List images = getJpegImages();
-		for (int i = 0; i < images.size(); i++)
-		{
-			if(i%10==0)
-			Debug.purgeMemory();
-
-			File imageFile = (File) images.get(i);
-			Debug.debug("imageFile", imageFile.getAbsoluteFile());
-
-			//			ByteSource byteSource = new ByteSourceFile(imageFile);
-			//			new JpegUtils().dumpJFIF(byteSource);
-
-			Map params = new HashMap();
-			boolean ignoreImageData = isPhilHarveyTestImage(imageFile);
-			params
-					.put(PARAM_KEY_READ_THUMBNAILS, new Boolean(
-							!ignoreImageData));
-
-			IImageMetadata metadata = Sanselan.getMetadata(imageFile, params);
-			//			assertNotNull(metadata);
-			Debug.debug("metadata", metadata);
-
-			ImageInfo imageInfo = Sanselan.getImageInfo(imageFile, params);
-			assertNotNull(imageInfo);
-		}
-	}
+    public void test() throws IOException, ImageReadException
+    {
+        List images = getJpegImages();
+        for (int i = 0; i < images.size(); i++)
+        {
+            if(i%10==0)
+            Debug.purgeMemory();
+
+            File imageFile = (File) images.get(i);
+            Debug.debug("imageFile", imageFile.getAbsoluteFile());
+
+            //            ByteSource byteSource = new ByteSourceFile(imageFile);
+            //            new JpegUtils().dumpJFIF(byteSource);
+
+            Map params = new HashMap();
+            boolean ignoreImageData = isPhilHarveyTestImage(imageFile);
+            params
+                    .put(PARAM_KEY_READ_THUMBNAILS, new Boolean(
+                            !ignoreImageData));
+
+            IImageMetadata metadata = Sanselan.getMetadata(imageFile, params);
+            //            assertNotNull(metadata);
+            Debug.debug("metadata", metadata);
+
+            ImageInfo imageInfo = Sanselan.getImageInfo(imageFile, params);
+            assertNotNull(imageInfo);
+        }
+    }
 
 }

Modified: commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/JpegWithJpegThumbnailTest.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/JpegWithJpegThumbnailTest.java?rev=995634&r1=995633&r2=995634&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/JpegWithJpegThumbnailTest.java (original)
+++ commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/JpegWithJpegThumbnailTest.java Fri Sep 10 01:35:50 2010
@@ -30,15 +30,15 @@ import org.apache.sanselan.common.IImage
 
 public class JpegWithJpegThumbnailTest extends SanselanTest {
 
-	public void testSingleImage() throws IOException, ImageReadException {
-		File imageFile = getTestImageByName("img_F028c_small.jpg");
+    public void testSingleImage() throws IOException, ImageReadException {
+        File imageFile = getTestImageByName("img_F028c_small.jpg");
 
-		Map params = new HashMap();
-		IImageMetadata metadata = Sanselan.getMetadata(imageFile, params);
-		assertNotNull(metadata);
-		JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
-		BufferedImage image = jpegMetadata.getEXIFThumbnail(); 
-		assertNotNull(image);
-	}
+        Map params = new HashMap();
+        IImageMetadata metadata = Sanselan.getMetadata(imageFile, params);
+        assertNotNull(metadata);
+        JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
+        BufferedImage image = jpegMetadata.getEXIFThumbnail();
+        assertNotNull(image);
+    }
 }
 

Modified: commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/exif/AsciiFieldTest.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/exif/AsciiFieldTest.java?rev=995634&r1=995633&r2=995634&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/exif/AsciiFieldTest.java (original)
+++ commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/exif/AsciiFieldTest.java Fri Sep 10 01:35:50 2010
@@ -35,44 +35,44 @@ import org.apache.sanselan.formats.tiff.
 
 public class AsciiFieldTest extends ExifBaseTest implements AllTagConstants {
 
-	public void testSingleImage() throws IOException, ImageReadException {
-		File imageFile = getTestImageByName("Canon Powershot SD750 - 2007.12.26.n.IMG_3704.JPG");
+    public void testSingleImage() throws IOException, ImageReadException {
+        File imageFile = getTestImageByName("Canon Powershot SD750 - 2007.12.26.n.IMG_3704.JPG");
 
-		Map params = new HashMap();
+        Map params = new HashMap();
 
-		IImageMetadata metadata = Sanselan.getMetadata(imageFile, params);
-		assertNotNull(metadata);
-		JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
-
-		// note that exif might be null if no Exif metadata is found.
-		TiffImageMetadata exif = jpegMetadata.getExif();
-		if (null == exif)
-			return;
-
-		List fields = exif.getAllFields();
-		Map fieldMap = new Hashtable();
-		// Build a simplified field tag -> field map, ignoring directory structures.
-		// Good enough for our purposes, since the image in question is known.
-		for (int i = 0; i < fields.size(); i++) {
-			TiffField field = (TiffField) fields.get(i);
-			fieldMap.put(new Integer(field.tag), field);
-		}
-		
-		Map expectedFieldValues = new Hashtable();
-		expectedFieldValues.put(new Integer(EXIF_TAG_MAKE.tag), "Canon");
-		expectedFieldValues.put(new Integer(EXIF_TAG_MODEL.tag), "Canon PowerShot SD750");
-		expectedFieldValues.put(new Integer(EXIF_TAG_MODIFY_DATE.tag), "2007:12:25 13:34:39");
-		Iterator expectedTags = expectedFieldValues.keySet().iterator();
-		while (expectedTags.hasNext()) {
-			Integer tag = (Integer) expectedTags.next();
-			Object expectedValue = expectedFieldValues.get(tag);
-
-			assertTrue(fieldMap.containsKey(tag));
-			TiffField field = (TiffField) fieldMap.get(tag);
-			assertNotNull(field);
-			Object value = field.getValue();
-			assertNotNull(value);
-			assertEquals(value, expectedValue);
-		}
-	}
+        IImageMetadata metadata = Sanselan.getMetadata(imageFile, params);
+        assertNotNull(metadata);
+        JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
+
+        // note that exif might be null if no Exif metadata is found.
+        TiffImageMetadata exif = jpegMetadata.getExif();
+        if (null == exif)
+            return;
+
+        List fields = exif.getAllFields();
+        Map fieldMap = new Hashtable();
+        // Build a simplified field tag -> field map, ignoring directory structures.
+        // Good enough for our purposes, since the image in question is known.
+        for (int i = 0; i < fields.size(); i++) {
+            TiffField field = (TiffField) fields.get(i);
+            fieldMap.put(new Integer(field.tag), field);
+        }
+
+        Map expectedFieldValues = new Hashtable();
+        expectedFieldValues.put(new Integer(EXIF_TAG_MAKE.tag), "Canon");
+        expectedFieldValues.put(new Integer(EXIF_TAG_MODEL.tag), "Canon PowerShot SD750");
+        expectedFieldValues.put(new Integer(EXIF_TAG_MODIFY_DATE.tag), "2007:12:25 13:34:39");
+        Iterator expectedTags = expectedFieldValues.keySet().iterator();
+        while (expectedTags.hasNext()) {
+            Integer tag = (Integer) expectedTags.next();
+            Object expectedValue = expectedFieldValues.get(tag);
+
+            assertTrue(fieldMap.containsKey(tag));
+            TiffField field = (TiffField) fieldMap.get(tag);
+            assertNotNull(field);
+            Object value = field.getValue();
+            assertNotNull(value);
+            assertEquals(value, expectedValue);
+        }
+    }
 }

Modified: commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/exif/ExifBaseTest.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/exif/ExifBaseTest.java?rev=995634&r1=995633&r2=995634&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/exif/ExifBaseTest.java (original)
+++ commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/exif/ExifBaseTest.java Fri Sep 10 01:35:50 2010
@@ -29,84 +29,84 @@ import org.apache.sanselan.formats.jpeg.
 
 public abstract class ExifBaseTest extends SanselanTest
 {
-	//	public ExifBaseTest(String name)
-	//	{
-	//		super(name);
-	//	}
-
-	protected static boolean hasExifData(File file)
-	{
-		//		Debug.debug("hasExifData file", file.getAbsoluteFile());
-
-		if (!file.getName().toLowerCase().endsWith(".jpg"))
-			return false;
-		//ImageFormat format = Sanselan.guessFormat(file);
-		//if (format != ImageFormat.IMAGE_FORMAT_JPEG)
-		//	return false;
-
-		//		Debug.debug("possible file", file);
-
-		try
-		{
-			ByteSource byteSource = new ByteSourceFile(file);
-			return new JpegImageParser().hasExifSegment(byteSource);
-		}
-		catch (Exception e)
-		{
-			//			Debug.debug("Error file", file.getAbsoluteFile());
-			//			Debug.debug(e, 4);
-			return false;
-		}
-	}
-
-	private static final ImageFilter HAS_EXIF_IMAGE_FILTER = new ImageFilter()
-	{
-		public boolean accept(File file) throws IOException, ImageReadException
-		{
-			return hasExifData(file);
-		}
-	};
-
-	private static final ImageFilter JPEG_IMAGE_FILTER = new ImageFilter()
-	{
-		public boolean accept(File file) throws IOException, ImageReadException
-		{
-			return file.getName().toLowerCase().endsWith(".jpg");
-		}
-	};
-
-	protected File getImageWithExifData() throws IOException,
-			ImageReadException
-	{
-		return getTestImage(HAS_EXIF_IMAGE_FILTER);
-	}
-
-	protected List getImagesWithExifData() throws IOException,
-			ImageReadException
-	{
-		return getTestImages(HAS_EXIF_IMAGE_FILTER);
-	}
-
-	protected List getImagesWithExifData(int max) throws IOException,
-			ImageReadException
-	{
-		return getTestImages(HAS_EXIF_IMAGE_FILTER, max);
-	}
-
-	protected File getJpegImage() throws IOException, ImageReadException
-	{
-		return getTestImage(JPEG_IMAGE_FILTER);
-	}
-
-	protected List getJpegImages() throws IOException, ImageReadException
-	{
-		return getTestImages(JPEG_IMAGE_FILTER);
-	}
-
-	protected List getJpegImages(int max) throws IOException,
-			ImageReadException
-	{
-		return getTestImages(JPEG_IMAGE_FILTER, max);
-	}
+    //    public ExifBaseTest(String name)
+    //    {
+    //        super(name);
+    //    }
+
+    protected static boolean hasExifData(File file)
+    {
+        //        Debug.debug("hasExifData file", file.getAbsoluteFile());
+
+        if (!file.getName().toLowerCase().endsWith(".jpg"))
+            return false;
+        //ImageFormat format = Sanselan.guessFormat(file);
+        //if (format != ImageFormat.IMAGE_FORMAT_JPEG)
+        //    return false;
+
+        //        Debug.debug("possible file", file);
+
+        try
+        {
+            ByteSource byteSource = new ByteSourceFile(file);
+            return new JpegImageParser().hasExifSegment(byteSource);
+        }
+        catch (Exception e)
+        {
+            //            Debug.debug("Error file", file.getAbsoluteFile());
+            //            Debug.debug(e, 4);
+            return false;
+        }
+    }
+
+    private static final ImageFilter HAS_EXIF_IMAGE_FILTER = new ImageFilter()
+    {
+        public boolean accept(File file) throws IOException, ImageReadException
+        {
+            return hasExifData(file);
+        }
+    };
+
+    private static final ImageFilter JPEG_IMAGE_FILTER = new ImageFilter()
+    {
+        public boolean accept(File file) throws IOException, ImageReadException
+        {
+            return file.getName().toLowerCase().endsWith(".jpg");
+        }
+    };
+
+    protected File getImageWithExifData() throws IOException,
+            ImageReadException
+    {
+        return getTestImage(HAS_EXIF_IMAGE_FILTER);
+    }
+
+    protected List getImagesWithExifData() throws IOException,
+            ImageReadException
+    {
+        return getTestImages(HAS_EXIF_IMAGE_FILTER);
+    }
+
+    protected List getImagesWithExifData(int max) throws IOException,
+            ImageReadException
+    {
+        return getTestImages(HAS_EXIF_IMAGE_FILTER, max);
+    }
+
+    protected File getJpegImage() throws IOException, ImageReadException
+    {
+        return getTestImage(JPEG_IMAGE_FILTER);
+    }
+
+    protected List getJpegImages() throws IOException, ImageReadException
+    {
+        return getTestImages(JPEG_IMAGE_FILTER);
+    }
+
+    protected List getJpegImages(int max) throws IOException,
+            ImageReadException
+    {
+        return getTestImages(JPEG_IMAGE_FILTER, max);
+    }
 
 }

Modified: commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/exif/ExifDumpTest.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/exif/ExifDumpTest.java?rev=995634&r1=995633&r2=995634&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/exif/ExifDumpTest.java (original)
+++ commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/formats/jpeg/exif/ExifDumpTest.java Fri Sep 10 01:35:50 2010
@@ -34,42 +34,42 @@ import org.apache.sanselan.util.Debug;
 
 public class ExifDumpTest extends ExifBaseTest
 {
-	//	public ExifDumpTest(String name)
-	//	{
-	//		super(name);
-	//	}
-
-	public void test() throws IOException, ImageReadException,
-			ImageWriteException
-	{
-		List images = getImagesWithExifData();
-		for (int i = 0; i < images.size(); i++)
-		{
-			if(i%10==0)
-			Debug.purgeMemory();
-
-			File imageFile = (File) images.get(i);
-			Debug.debug("imageFile", imageFile);
-			Debug.debug();
-
-			ByteSource byteSource = new ByteSourceFile(imageFile);
-			Debug.debug("Segments:");
-			new JpegUtils().dumpJFIF(byteSource);
-
-			Map params = new HashMap();
-			boolean ignoreImageData = isPhilHarveyTestImage(imageFile);
-			params
-					.put(PARAM_KEY_READ_THUMBNAILS, new Boolean(
-							!ignoreImageData));
-
-			JpegImageMetadata metadata = (JpegImageMetadata) Sanselan
-					.getMetadata(imageFile, params);
-			if (null == metadata)
-				continue;
-			//			assertNotNull(metadata.getExif());
-
-			metadata.dump();
-		}
-	}
+    //    public ExifDumpTest(String name)
+    //    {
+    //        super(name);
+    //    }
+
+    public void test() throws IOException, ImageReadException,
+            ImageWriteException
+    {
+        List images = getImagesWithExifData();
+        for (int i = 0; i < images.size(); i++)
+        {
+            if(i%10==0)
+            Debug.purgeMemory();
+
+            File imageFile = (File) images.get(i);
+            Debug.debug("imageFile", imageFile);
+            Debug.debug();
+
+            ByteSource byteSource = new ByteSourceFile(imageFile);
+            Debug.debug("Segments:");
+            new JpegUtils().dumpJFIF(byteSource);
+
+            Map params = new HashMap();
+            boolean ignoreImageData = isPhilHarveyTestImage(imageFile);
+            params
+                    .put(PARAM_KEY_READ_THUMBNAILS, new Boolean(
+                            !ignoreImageData));
+
+            JpegImageMetadata metadata = (JpegImageMetadata) Sanselan
+                    .getMetadata(imageFile, params);
+            if (null == metadata)
+                continue;
+            //            assertNotNull(metadata.getExif());
+
+            metadata.dump();
+        }
+    }
 
 }