ico.go 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package imagesize
  2. import (
  3. "encoding/binary"
  4. "io"
  5. )
  6. func icoBestSize(r io.Reader) (width, height byte, offset uint32, size uint32, err error) {
  7. var tmp [16]byte
  8. if _, err = io.ReadFull(r, tmp[:6]); err != nil {
  9. return
  10. }
  11. count := binary.LittleEndian.Uint16(tmp[4:6])
  12. for i := uint16(0); i < count; i++ {
  13. if _, err = io.ReadFull(r, tmp[:]); err != nil {
  14. return
  15. }
  16. if tmp[0] > width || tmp[1] > height || tmp[0] == 0 || tmp[1] == 0 {
  17. width = tmp[0]
  18. height = tmp[1]
  19. size = binary.LittleEndian.Uint32(tmp[8:12])
  20. offset = binary.LittleEndian.Uint32(tmp[12:16])
  21. }
  22. }
  23. return
  24. }
  25. func BestIcoPage(r io.Reader) (int, int, error) {
  26. _, _, offset, size, err := icoBestSize(r)
  27. return int(offset), int(size), err
  28. }
  29. func DecodeIcoMeta(r io.Reader) (*Meta, error) {
  30. bwidth, bheight, _, _, err := icoBestSize(r)
  31. if err != nil {
  32. return nil, err
  33. }
  34. width := int(bwidth)
  35. height := int(bheight)
  36. if width == 0 {
  37. width = 256
  38. }
  39. if height == 0 {
  40. height = 256
  41. }
  42. return &Meta{
  43. Format: "ico",
  44. Width: width,
  45. Height: height,
  46. }, nil
  47. }
  48. func init() {
  49. RegisterFormat("\x00\x00\x01\x00", DecodeIcoMeta)
  50. }