mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-05-13 21:46:32 +02:00
Fix loadind BMP stored in ICO
This commit is contained in:
parent
74f2f157e2
commit
1d1caeb06a
@ -1,6 +1,8 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
### Fixed
|
||||||
|
- Fix loadind BMP stored in ICO.
|
||||||
|
|
||||||
## [2.10.0] - 2020-02-13
|
## [2.10.0] - 2020-02-13
|
||||||
### Added
|
### Added
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package imagemeta
|
package imagemeta
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
@ -83,3 +84,51 @@ func init() {
|
|||||||
func(r io.Reader) (Meta, error) { return DecodeIcoMeta(r) },
|
func(r io.Reader) (Meta, error) { return DecodeIcoMeta(r) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FixBmpHeader fixes an incomplete header of BMP stored in ICO
|
||||||
|
func FixBmpHeader(b []byte) ([]byte, error) {
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
|
fileSize := uint32(14 + len(b))
|
||||||
|
|
||||||
|
buf.Grow(int(fileSize))
|
||||||
|
|
||||||
|
buf.Write(bmpMagick)
|
||||||
|
|
||||||
|
if err := binary.Write(buf, binary.LittleEndian, &fileSize); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
reserved := uint32(0)
|
||||||
|
if err := binary.Write(buf, binary.LittleEndian, &reserved); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
colorUsed := binary.LittleEndian.Uint32(b[32:36])
|
||||||
|
bitCount := binary.LittleEndian.Uint16(b[14:16])
|
||||||
|
|
||||||
|
var pixOffset uint32
|
||||||
|
if colorUsed == 0 && bitCount <= 8 {
|
||||||
|
pixOffset = 14 + 40 + 4*(1<<bitCount)
|
||||||
|
} else {
|
||||||
|
pixOffset = 14 + 40 + 4*colorUsed
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := binary.Write(buf, binary.LittleEndian, &pixOffset); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write size and width
|
||||||
|
buf.Write(b[:8])
|
||||||
|
|
||||||
|
// For some reason ICO stores double height
|
||||||
|
height := binary.LittleEndian.Uint32(b[8:12]) / 2
|
||||||
|
if err := binary.Write(buf, binary.LittleEndian, &height); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the rest
|
||||||
|
buf.Write(b[12:])
|
||||||
|
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
14
process.go
14
process.go
@ -587,12 +587,22 @@ func getIcoData(imgdata *imageData) (*imageData, error) {
|
|||||||
|
|
||||||
data := imgdata.Data[offset : offset+size]
|
data := imgdata.Data[offset : offset+size]
|
||||||
|
|
||||||
|
var format string
|
||||||
|
|
||||||
meta, err := imagemeta.DecodeMeta(bytes.NewReader(data))
|
meta, err := imagemeta.DecodeMeta(bytes.NewReader(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
// Looks like it's BMP with an incomplete header
|
||||||
|
if d, err := imagemeta.FixBmpHeader(data); err == nil {
|
||||||
|
format = "bmp"
|
||||||
|
data = d
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
format = meta.Format()
|
||||||
}
|
}
|
||||||
|
|
||||||
if imgtype, ok := imageTypes[meta.Format()]; ok && vipsTypeSupportLoad[imgtype] {
|
if imgtype, ok := imageTypes[format]; ok && vipsTypeSupportLoad[imgtype] {
|
||||||
return &imageData{
|
return &imageData{
|
||||||
Data: data,
|
Data: data,
|
||||||
Type: imgtype,
|
Type: imgtype,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user