Skip to content
Permalink
Browse files

Fix loadind BMP stored in ICO

  • Loading branch information
DarthSim committed Feb 14, 2020
1 parent 74f2f15 commit 1d1caeb06ab651635aaefa1140a495d2c1ac39c9
Showing with 63 additions and 2 deletions.
  1. +2 −0 CHANGELOG.md
  2. +49 −0 imagemeta/ico.go
  3. +12 −2 process.go
@@ -1,6 +1,8 @@
# Changelog

## [Unreleased]
### Fixed
- Fix loadind BMP stored in ICO.

## [2.10.0] - 2020-02-13
### Added
@@ -1,6 +1,7 @@
package imagemeta

import (
"bytes"
"encoding/binary"
"io"
)
@@ -83,3 +84,51 @@ func init() {
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
}
@@ -587,12 +587,22 @@ func getIcoData(imgdata *imageData) (*imageData, error) {

data := imgdata.Data[offset : offset+size]

var format string

meta, err := imagemeta.DecodeMeta(bytes.NewReader(data))
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{
Data: data,
Type: imgtype,

0 comments on commit 1d1caeb

Please sign in to comment.
You can’t perform that action at this time.