diff --git a/pom.xml b/pom.xml
index 9d73b1e..8491a8e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,12 +14,28 @@
2006
- 6
- 6
+ 8
+ 8
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
${basedir}/src
+ ${basedir}/test
+
+
+
+ ${basedir}/test-resources
+
+
diff --git a/src/net/sf/image4j/codec/bmp/BMPDecoder.java b/src/net/sf/image4j/codec/bmp/BMPDecoder.java
index db0f206..d9bcab4 100644
--- a/src/net/sf/image4j/codec/bmp/BMPDecoder.java
+++ b/src/net/sf/image4j/codec/bmp/BMPDecoder.java
@@ -47,7 +47,7 @@ public BMPDecoder(java.io.InputStream in) throws IOException {
//DataOffset [4] file offset to raster data
int dataOffset = lis.readIntLE();
- /* info header [40] */
+ /* info header */
infoHeader = readInfoHeader(lis);
@@ -264,7 +264,7 @@ public static BufferedImage read1(InfoHeader infoHeader,
int padBits = bitsPerLine - dataBitsPerLine;
int padBytes = padBits / 8;
- int bytesPerLine = (int) (bitsPerLine / 8);
+ int bytesPerLine = (infoHeader.iWidth + 31)/32 * 4;
int[] line = new int[bytesPerLine];
for (int y = infoHeader.iHeight - 1; y >= 0; y--) {
diff --git a/src/net/sf/image4j/codec/bmp/InfoHeader.java b/src/net/sf/image4j/codec/bmp/InfoHeader.java
index d77fffb..019731b 100644
--- a/src/net/sf/image4j/codec/bmp/InfoHeader.java
+++ b/src/net/sf/image4j/codec/bmp/InfoHeader.java
@@ -99,11 +99,14 @@ public InfoHeader(net.sf.image4j.io.LittleEndianInputStream in, int infoSize) th
protected void init(net.sf.image4j.io.LittleEndianInputStream in, int infoSize) throws IOException {
this.iSize = infoSize;
+ // Only 40-byte header is read. If actual header is longer, just skip the rest
+ int ntHeaderSize = 40;
+
//Width
iWidth = in.readIntLE();
//Height
iHeight = in.readIntLE();
- //Planes (=1)
+ //Planes
sPlanes = in.readShortLE();
//Bit count
sBitCount = in.readShortLE();
@@ -123,13 +126,18 @@ protected void init(net.sf.image4j.io.LittleEndianInputStream in, int infoSize)
iColorsUsed = in.readIntLE();
//Colors important - number of important colors 0 = all
iColorsImportant = in.readIntLE();
+
+ if(iSize > ntHeaderSize){
+ in.skipBytes(infoSize - ntHeaderSize);
+ }
+
}
/**
* Creates an InfoHeader with default values.
*/
public InfoHeader() {
- //Size of InfoHeader structure = 40
+ //Size of InfoHeader structure = 40 for Windows NT BITMAPINFOHEADER, see Wikipedia
iSize = 40;
//Width
iWidth = 0;
diff --git a/test-resources/monochrome.bmp b/test-resources/monochrome.bmp
new file mode 100644
index 0000000..222e819
Binary files /dev/null and b/test-resources/monochrome.bmp differ
diff --git a/test/net/sf/image4j/codec/bmp/BMPDecoderTest.java b/test/net/sf/image4j/codec/bmp/BMPDecoderTest.java
new file mode 100644
index 0000000..c608585
--- /dev/null
+++ b/test/net/sf/image4j/codec/bmp/BMPDecoderTest.java
@@ -0,0 +1,57 @@
+package net.sf.image4j.codec.bmp;
+
+import static org.junit.Assert.*;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
+import java.io.InputStream;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+@RunWith(BlockJUnit4ClassRunner.class)
+public class BMPDecoderTest {
+
+ InputStream is;
+
+ String filename = "/monochrome.bmp";
+
+ @Before
+ public void setUp() throws Exception {
+ is = getClass().getResourceAsStream(filename);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (is != null) {
+ is.close();
+ }
+ }
+
+ @Test
+ public void testMonochromeImage() throws Exception {
+ assertNotNull("Test file missing",
+ getClass().getResource(filename));
+ BufferedImage image = BMPDecoder.read(is);
+
+ assertEquals("Wrong width", 4, image.getWidth());
+ assertEquals("Wrong height", 8, image.getHeight());
+ assertEquals("Wrong image type", BufferedImage.TYPE_BYTE_BINARY, image.getType());
+
+ Raster raster = image.getRaster();
+ assertEquals("Wrong number of bands", 1, raster.getNumBands());
+ for (int x = 0; x < image.getWidth(); ++x) {
+ for (int y = 0; y < image.getHeight(); ++y) {
+ if (x == y) {
+ assertEquals("Wrong pixel on the main diagonal", 1, raster.getSample(x, y, 0));
+ } else {
+ assertEquals("Wrong pixel outside the main diagonal", 0, raster.getSample(x, y, 0));
+ }
+ }
+ }
+ }
+
+}