bmp: support to decode 8-bit format with up to 256 color palette

If colorUsed is 0, the number of palette is 2 to the power of bit per pixel.
testdata/colormap-251.{bmp,png} are added for testing 8-bit format with colorUsed less than 256.
testdata/colormap-0.{bmp,png} are added for testing 8-bit format with colorUsed 0.

Fixes golang/go#61240

Change-Id: I1a627a570f667874a91c517f4a771e9e97d2af6b
Reviewed-on: https://go-review.googlesource.com/c/image/+/508575
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
Reviewed-by: Nigel Tao (INACTIVE; USE @golang.org INSTEAD) <nigeltao@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Nigel Tao <nigeltao@golang.org>
diff --git a/bmp/reader.go b/bmp/reader.go
index e165c2e..1939c11 100644
--- a/bmp/reader.go
+++ b/bmp/reader.go
@@ -191,14 +191,22 @@
 	}
 	switch bpp {
 	case 8:
-		if offset != fileHeaderLen+infoLen+256*4 {
+		colorUsed := readUint32(b[46:50])
+		// If colorUsed is 0, it is set to the maximum number of colors for the given bpp, which is 2^bpp.
+		if colorUsed == 0 {
+			colorUsed = 256
+		} else if colorUsed > 256 {
 			return image.Config{}, 0, false, false, ErrUnsupported
 		}
-		_, err = io.ReadFull(r, b[:256*4])
+
+		if offset != fileHeaderLen+infoLen+colorUsed*4 {
+			return image.Config{}, 0, false, false, ErrUnsupported
+		}
+		_, err = io.ReadFull(r, b[:colorUsed*4])
 		if err != nil {
 			return image.Config{}, 0, false, false, err
 		}
-		pcm := make(color.Palette, 256)
+		pcm := make(color.Palette, colorUsed)
 		for i := range pcm {
 			// BMP images are stored in BGR order rather than RGB order.
 			// Every 4th byte is padding.
diff --git a/bmp/reader_test.go b/bmp/reader_test.go
index 8325f34..003d64f 100644
--- a/bmp/reader_test.go
+++ b/bmp/reader_test.go
@@ -41,6 +41,8 @@
 func TestDecode(t *testing.T) {
 	testCases := []string{
 		"colormap",
+		"colormap-0",
+		"colormap-251",
 		"video-001",
 		"yellow_rose-small",
 		"yellow_rose-small-v5",
diff --git a/testdata/colormap-0.bmp b/testdata/colormap-0.bmp
new file mode 100644
index 0000000..03a9a6a
--- /dev/null
+++ b/testdata/colormap-0.bmp
Binary files differ
diff --git a/testdata/colormap-0.png b/testdata/colormap-0.png
new file mode 100644
index 0000000..7a6b866
--- /dev/null
+++ b/testdata/colormap-0.png
Binary files differ
diff --git a/testdata/colormap-251.bmp b/testdata/colormap-251.bmp
new file mode 100644
index 0000000..6b8dad6
--- /dev/null
+++ b/testdata/colormap-251.bmp
Binary files differ
diff --git a/testdata/colormap-251.png b/testdata/colormap-251.png
new file mode 100644
index 0000000..81c489c
--- /dev/null
+++ b/testdata/colormap-251.png
Binary files differ