U: Add TGIFHeader, To verify the legality of GIF images

This commit is contained in:
杨红岩 2024-04-22 15:06:53 +08:00
parent 0b79017dfe
commit 8e4568acf2
3 changed files with 71 additions and 25 deletions

View File

@ -14,12 +14,13 @@ package gifanim
import (
"bytes"
"encoding/binary"
"github.com/energye/energy/v2/pkgs/ext"
"github.com/energye/golcl/lcl"
"github.com/energye/golcl/lcl/types"
"image"
"image/gif"
"image/png"
"os"
"io/ioutil"
)
const (
@ -76,7 +77,7 @@ func (m *TGIFAnimate) onTimer(sender lcl.IObject) {
} else {
m.index++
}
nextDelay := m.nextDelay()
nextDelay := m.frames[m.index].delay
if nextDelay != m.delay {
m.delay = nextDelay
m.task.SetEnabled(false)
@ -134,13 +135,19 @@ func (m *TGIFAnimate) load() {
m.reset()
m.count = len(m.gif.Image)
m.frames = make([]*Frame, m.count)
for i, frame := range m.gif.Image {
bounds := frame.Bounds()
var pngBuf bytes.Buffer
err := png.Encode(&pngBuf, frame)
var frameToBytes = func(frame *image.Paletted) (result []byte) {
var buf bytes.Buffer
//err := png.Encode(&buf, frame)
err := gif.Encode(&buf, frame, nil)
if err != nil {
panic(err)
}
result = buf.Bytes()
buf.Reset()
return
}
for i, frame := range m.gif.Image {
bounds := frame.Bounds()
m.frames[i] = &Frame{
index: i,
method: m.gif.Disposal[i],
@ -149,9 +156,8 @@ func (m *TGIFAnimate) load() {
w: int32(bounds.Dx()),
h: int32(bounds.Dy()),
delay: uint32(m.gif.Delay[i] * 10),
data: pngBuf.Bytes(),
data: frameToBytes(frame),
}
pngBuf.Reset()
}
m.initialed()
m.gif = nil
@ -183,10 +189,6 @@ func (m *TGIFAnimate) reset() {
m.count = 0
}
func (m *TGIFAnimate) nextDelay() uint32 {
return m.frames[m.index].delay
}
func (m *TGIFAnimate) currentFrame() *Frame {
return m.frames[m.index]
}
@ -290,20 +292,18 @@ func (m *TGIFAnimate) LoadFromFile(filePath string) {
if m.filePath == filePath {
return
}
file, err := os.Open(filePath)
data, err := ioutil.ReadFile(filePath)
if err != nil {
panic(err)
}
defer file.Close()
g, err := gif.DecodeAll(file)
if err != nil {
panic(err)
}
m.gif = g
m.load()
m.LoadFromBytes(data)
}
func (m *TGIFAnimate) LoadFromBytes(data []byte) {
header := m.ReadHeader(data)
if header == nil || !header.IsGIF() || !header.Is89a() {
return
}
g, err := gif.DecodeAll(bytes.NewReader(data))
if err != nil {
panic(err)
@ -312,6 +312,17 @@ func (m *TGIFAnimate) LoadFromBytes(data []byte) {
m.load()
}
func (m *TGIFAnimate) ReadHeader(data []byte) *TGIFHeader {
if data != nil && len(data) > 13 {
header := new(TGIFHeader)
var buf bytes.Buffer
buf.Write(data[:13])
binary.Read(&buf, binary.LittleEndian, header)
return header
}
return nil
}
func Rect(left, top, right, bottom int32) types.TRect {
return types.TRect{Left: left, Top: top, Right: right, Bottom: bottom}
}

View File

@ -22,8 +22,8 @@ type Frame struct {
delay uint32
data []byte
//background lcl.IBitmap
//image *lcl.TGIFImage
image *lcl.TPngImage
image *lcl.TGIFImage
//image *lcl.TPngImage
}
func (m *Frame) Index() int {
@ -70,8 +70,8 @@ func (m *Frame) SetData(data []byte) {
func (m *Frame) scan() {
if m.image == nil {
//m.image = lcl.NewGIFImage()
m.image = lcl.NewPngImage()
m.image = lcl.NewGIFImage()
//m.image = lcl.NewPngImage()
m.image.SetSize(m.w, m.h)
m.image.LoadFromBytes(m.data)
}

35
cef/gifanim/header.go Normal file
View File

@ -0,0 +1,35 @@
//----------------------------------------
//
// Copyright © yanghy. All Rights Reserved.
//
// Licensed under Apache License Version 2.0, January 2004
//
// https://www.apache.org/licenses/LICENSE-2.0
//
//----------------------------------------
package gifanim
type TGIFHeader struct {
Signature [3]byte // 页眉签名始终为“GIF”
Version [3]byte // GIF格式版本“89a”
ScreenWidth uint16 // 以像素为单位的显示屏宽度
ScreenHeight uint16 // 以像素为单位的显示屏高度
Packedbit byte // 屏幕和彩色地图信息
BackgroundColor byte // 背景色索引
AspectRatio byte // 像素纵横比
}
func (m *TGIFHeader) Is89a() bool {
if m == nil {
return false
}
return m.Version[0] == '8' && m.Version[1] == '9' && m.Version[2] == 'a'
}
func (m *TGIFHeader) IsGIF() bool {
if m == nil {
return false
}
return m.Signature[0] == 'G' && m.Signature[1] == 'I' && m.Signature[2] == 'F'
}