func decodeInfoHeader12(d *decoder, h []byte, configOnly bool) error {
	d.width = int(getWORD(h[4:6]))
	d.height = int(getWORD(h[6:8]))
	d.bitCount = int(getWORD(h[10:12]))
	d.srcPalBytesPerEntry = 3
	if d.bitCount >= 1 && d.bitCount <= 8 {
		d.srcPalNumEntries = 1 << uint(d.bitCount)
	}
	paletteStart := 14 + int(d.headerSize)
	paletteEnd := paletteStart + d.srcPalBytesPerEntry*d.srcPalNumEntries
	if int(d.bfOffBits) >= paletteStart+d.srcPalBytesPerEntry && int(d.bfOffBits) < paletteEnd {
		d.srcPalNumEntries = (int(d.bfOffBits) - paletteStart) / 3
	}
	return nil
}
Read a 12-byte BITMAPCOREHEADER.
package gobmp
import "image"
import "image/color"
import "io"
import "fmt"
const (
	bI_RGB       = 0
	bI_RLE8      = 1
	bI_RLE4      = 2
	bI_BITFIELDS = 3
)
type bitFieldsInfo struct {
	mask  uint32
	shift uint
	scale float64  
}
type decoder struct {
	r io.Reader
	img_Paletted *image.Paletted  
	img_NRGBA    *image.NRGBA     
	bfOffBits     uint32
	headerSize    uint32
	width         int
	height        int
	bitCount      int
	biCompression uint32
	isTopDown     bool
	srcPalNumEntries    int
	srcPalBytesPerEntry int
	srcPalSizeInBytes   int
	dstPalNumEntries    int
	dstHasPalette       bool
	dstPalette          color.Palette
	hasBitFieldsSegment  bool
	bitFieldsSegmentSize int
	bitFields            [4]bitFieldsInfo
}
type UnsupportedError string
func (e UnsupportedError) Error() string { return "bmp: unsupported feature: " + string(e) }
type FormatError string
func (e FormatError) Error() string { return "bmp: invalid format: " + string(e) }
func getWORD(b []byte) uint32 {
	return uint32(b[0]) | uint32(b[1])<<8
}
func getDWORD(b []byte) uint32 {
	return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
}
func decodeRow_paletted(d *decoder, buf []byte, j int) error {
	for i := 0; i < d.width; i++ {
		var v byte
		switch d.bitCount {
		case 8:
			v = buf[i]
		case 4:
			v = (buf[i/2] >> (4 * (1 - uint(i)%2))) & 0x0f
		case 2:
			v = (buf[i/4] >> (2 * (3 - uint(i)%4))) & 0x03
		case 1:
			v = (buf[i/8] >> (1 * (7 - uint(i)%8))) & 0x01
		}
		if int(v) >= d.dstPalNumEntries {
			v = 0
		}
		d.img_Paletted.Pix[j*d.img_Paletted.Stride+i] = v
	}
	return nil
}
func decodeRow_16or32(d *decoder, buf []byte, j int) error {
	for i := 0; i < d.width; i++ {
		var v uint32
		if d.bitCount == 16 {
			v = uint32(getWORD(buf[i*2 : i*2+2]))
		} else {  
			v = getDWORD(buf[i*4 : i*4+4])
		}
		for k := 0; k < 4; k++ {
			var sv uint8
			if d.bitFields[k].mask == 0 {
				if k == 3 {
					sv = 255
				} else {
					sv = 0
				}
			} else {
				sv = uint8(0.5 + float64((v&d.bitFields[k].mask)>>d.bitFields[k].shift)*
					d.bitFields[k].scale)
			}
			d.img_NRGBA.Pix[j*d.img_NRGBA.Stride+i*4+k] = sv
		}
	}
	return nil
}
func decodeRow_24(d *decoder, buf []byte, j int) error {
	for i := 0; i < d.width; i++ {
		for k := 0; k < 3; k++ {
			d.img_NRGBA.Pix[j*d.img_NRGBA.Stride+i*4+k] = buf[i*3+2-k]
		}
		d.img_NRGBA.Pix[j*d.img_NRGBA.Stride+i*4+3] = 255
	}
	return nil
}
type decodeRowFuncType func(d *decoder, buf []byte, j int) error
var rowDecoders = map[int]decodeRowFuncType{
	1:  decodeRow_paletted,
	2:  decodeRow_paletted,
	4:  decodeRow_paletted,
	8:  decodeRow_paletted,
	16: decodeRow_16or32,
	24: decodeRow_24,
	32: decodeRow_16or32,
}
func (d *decoder) readBitsUncompressed() error {
	var err error
	srcRowStride := ((d.width*d.bitCount + 31) / 32) * 4
	buf := make([]byte, srcRowStride)
	decodeRowFunc := rowDecoders[d.bitCount]
	if decodeRowFunc == nil {
		return nil
	}
	for srcRow := 0; srcRow < d.height; srcRow++ {
		var dstRow int
		if d.isTopDown {
			dstRow = srcRow
		} else {
			dstRow = d.height - srcRow - 1
		}
		_, err = io.ReadFull(d.r, buf)
		if err != nil {
			return err
		}
		err = decodeRowFunc(d, buf, dstRow)
		if err != nil {
			return err
		}
	}
	return nil
}
func (d *decoder) skipBytes(n int) error {
	var buf [1024]byte
	for n > 0 {
		bytesToRead := len(buf)
		if bytesToRead > n {
			bytesToRead = n
		}
		_, err := io.ReadFull(d.r, buf[:bytesToRead])
		if err != nil {
			return err
		}
		n -= bytesToRead
	}
	return nil
}
func (d *decoder) readGap() error {
	currentOffset := 14 + int(d.headerSize) + d.bitFieldsSegmentSize + d.srcPalSizeInBytes
	if currentOffset == int(d.bfOffBits) {
		return nil
	}
	if currentOffset > int(d.bfOffBits) {
		return FormatError("bad bfOffBits field")
	}
	gapSize := int(d.bfOffBits) - currentOffset
	return d.skipBytes(gapSize)
}