From 175cb8c41b41d720593b0f67e0e7b23899c0275c Mon Sep 17 00:00:00 2001 From: DarthSim Date: Mon, 14 Mar 2022 18:29:40 +0600 Subject: [PATCH] Fix transparrency in loaded ICO --- imagemeta/ico.go | 49 ---------------------------------------- vips/bmp.go | 3 +-- vips/ico.go | 59 +++++++++++++++++++++++++++++++++++++++++++----- vips/vips.go | 2 +- 4 files changed, 55 insertions(+), 58 deletions(-) diff --git a/imagemeta/ico.go b/imagemeta/ico.go index af6170d7..7d27c09f 100644 --- a/imagemeta/ico.go +++ b/imagemeta/ico.go @@ -1,7 +1,6 @@ package imagemeta import ( - "bytes" "encoding/binary" "io" @@ -86,51 +85,3 @@ 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<= 70 { // Alpha mask is empty, so no alpha here noAlpha = readUint32(b[66:70]) == 0 diff --git a/vips/ico.go b/vips/ico.go index 09c73466..5ef822bc 100644 --- a/vips/ico.go +++ b/vips/ico.go @@ -32,16 +32,16 @@ func (img *Image) loadIco(data []byte, shrink int, scale float64, pages int) err meta, err := imagemeta.DecodeMeta(bytes.NewReader(internalData)) if err != nil { // Looks like it's BMP with an incomplete header - if d, err := imagemeta.FixBmpHeader(internalData); err == nil { - internalType = imagetype.BMP - internalData = d - } else { + d, err := icoFixBmpHeader(internalData) + if err != nil { return err } - } else { - internalType = meta.Format() + + return img.loadBmp(d, false) } + internalType = meta.Format() + if internalType == imagetype.ICO || !SupportsLoad(internalType) { return fmt.Errorf("Can't load %s from ICO", internalType) } @@ -129,3 +129,50 @@ func (img *Image) saveAsIco() (*imagedata.ImageData, error) { return &imgdata, nil } + +func icoFixBmpHeader(b []byte) ([]byte, error) { + buf := new(bytes.Buffer) + + fileSize := uint32(14 + len(b)) + + buf.Grow(int(fileSize)) + + buf.WriteString("BM") + + 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<