bmp.go 1.1 KB

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