bmp.go 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. package imagemeta
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "io"
  6. )
  7. var bmpMagick = []byte("BM")
  8. type BmpFormatError string
  9. func (e BmpFormatError) Error() string { return "invalid BMP format: " + string(e) }
  10. func DecodeBmpMeta(r io.Reader) (Meta, error) {
  11. var tmp [26]byte
  12. if _, err := io.ReadFull(r, tmp[:]); err != nil {
  13. return nil, err
  14. }
  15. if !bytes.Equal(tmp[:2], bmpMagick) {
  16. return nil, BmpFormatError("malformed header")
  17. }
  18. infoSize := binary.LittleEndian.Uint32(tmp[14:18])
  19. var width, height int
  20. if infoSize >= 40 {
  21. width = int(binary.LittleEndian.Uint32(tmp[18:22]))
  22. height = int(int32(binary.LittleEndian.Uint32(tmp[22:26])))
  23. } else {
  24. // CORE
  25. width = int(binary.LittleEndian.Uint16(tmp[18:20]))
  26. height = int(int16(binary.LittleEndian.Uint16(tmp[20:22])))
  27. }
  28. // height can be negative in Windows bitmaps
  29. if height < 0 {
  30. height = -height
  31. }
  32. return &meta{
  33. format: "bmp",
  34. width: width,
  35. height: height,
  36. }, nil
  37. }
  38. func init() {
  39. RegisterFormat(string(bmpMagick), DecodeBmpMeta)
  40. }