mirror of
https://gitee.com/energye/energy.git
synced 2024-12-05 13:17:54 +08:00
A: GIF Play component
This commit is contained in:
parent
08fc3d01ca
commit
0264e7f7d5
@ -17,11 +17,10 @@ import (
|
||||
)
|
||||
|
||||
type TGIFImage struct {
|
||||
Bitmap *ext.TBitmap
|
||||
PosX uint16
|
||||
PosY uint16
|
||||
Delay uint16
|
||||
Method byte
|
||||
Bitmap *ext.TBitmap
|
||||
PosX, PosY uint16
|
||||
Delay uint16
|
||||
Method byte
|
||||
}
|
||||
|
||||
type TGIFImageDescriptor struct {
|
||||
@ -40,7 +39,7 @@ func (m *TGIFImageDescriptor) BytesToConvert(data []byte) {
|
||||
|
||||
type TGIFGraphicsControlExtension struct {
|
||||
BlockSize byte // 剩余字段的大小(始终为04h)
|
||||
Packedbit byte // 要使用的图形处理方法
|
||||
PackedBit byte // 要使用的图形处理方法
|
||||
DelayTime uint16 // 等待数十秒
|
||||
ColorIndex byte // 透明颜色索引
|
||||
Terminator byte // 块终止符(始终为0)
|
||||
|
@ -120,26 +120,24 @@ func (m *TGIFLoader) ReadPalette(stream *lcl.TMemoryStream, size int) {
|
||||
|
||||
func (m *TGIFLoader) ReadScanLine(stream *lcl.TMemoryStream) {
|
||||
var (
|
||||
unpackedSize, packedSize int64
|
||||
data, bits, code uint32
|
||||
sourcePtr PByte
|
||||
inCode uint32
|
||||
codeSize uint32
|
||||
codeMask uint32
|
||||
freeCode uint32
|
||||
oldCode uint32
|
||||
prefix [CODE_TABLE_SIZE]uint32
|
||||
suffix, stack = make([]byte, CODE_TABLE_SIZE), make([]byte, CODE_TABLE_SIZE)
|
||||
stackPointer PByte
|
||||
b, initialCodeSize, firstChar byte
|
||||
clearCode, eoiCode uint16
|
||||
unpackedSize, packedSize int64
|
||||
data, bits, code uint32
|
||||
inCode uint32
|
||||
codeSize uint32
|
||||
codeMask uint32
|
||||
freeCode uint32
|
||||
oldCode uint32
|
||||
prefix [CODE_TABLE_SIZE]uint32
|
||||
suffix, stack = make([]byte, CODE_TABLE_SIZE), make([]byte, CODE_TABLE_SIZE)
|
||||
b, initialCodeSize, firstChar byte
|
||||
clearCode, eoiCode uint16
|
||||
targetIdx, stackIdx, sourceDataIdx int
|
||||
)
|
||||
// 解压缩字典的初始化
|
||||
_, d := stream.Read(1)
|
||||
initialCodeSize = d[0]
|
||||
// 压缩尾部
|
||||
OldPos := stream.Position()
|
||||
packedSize = 0
|
||||
oldPos := stream.Position()
|
||||
for {
|
||||
_, d = stream.Read(1)
|
||||
b = d[0]
|
||||
@ -151,7 +149,7 @@ func (m *TGIFLoader) ReadScanLine(stream *lcl.TMemoryStream) {
|
||||
break
|
||||
}
|
||||
}
|
||||
stream.SetPosition(OldPos)
|
||||
stream.SetPosition(oldPos)
|
||||
var sourceBuf bytes.Buffer
|
||||
for {
|
||||
_, d = stream.Read(1)
|
||||
@ -166,8 +164,6 @@ func (m *TGIFLoader) ReadScanLine(stream *lcl.TMemoryStream) {
|
||||
}
|
||||
sourceData := sourceBuf.Bytes()
|
||||
sourceBuf.Reset()
|
||||
sourcePtr = PByte(unsafe.Pointer(&sourceData[0]))
|
||||
target := uintptr(unsafe.Pointer(&m.scanLine[0]))
|
||||
codeSize = uint32(initialCodeSize + 1)
|
||||
clearCode = 1 << initialCodeSize
|
||||
eoiCode = clearCode + 1
|
||||
@ -179,13 +175,12 @@ func (m *TGIFLoader) ReadScanLine(stream *lcl.TMemoryStream) {
|
||||
prefix[I] = CODE_TABLE_SIZE
|
||||
suffix[I] = byte(I)
|
||||
}
|
||||
stackPointer = uintptr(unsafe.Pointer(&stack[0]))
|
||||
firstChar = 0
|
||||
data = 0
|
||||
bits = 0
|
||||
//解压缩LZW gif
|
||||
for unpackedSize > 0 && packedSize > 0 {
|
||||
source := uint32(*(*byte)(unsafe.Pointer(sourcePtr)))
|
||||
source := uint32(sourceData[sourceDataIdx])
|
||||
data += source << bits
|
||||
bits += 8
|
||||
for bits >= codeSize {
|
||||
@ -207,26 +202,26 @@ func (m *TGIFLoader) ReadScanLine(stream *lcl.TMemoryStream) {
|
||||
}
|
||||
if oldCode == CODE_TABLE_SIZE {
|
||||
firstChar = suffix[code]
|
||||
*(*byte)(unsafe.Pointer(target)) = firstChar
|
||||
target++
|
||||
m.scanLine[targetIdx] = firstChar
|
||||
targetIdx++
|
||||
unpackedSize--
|
||||
oldCode = code
|
||||
continue
|
||||
}
|
||||
inCode = code
|
||||
if code == freeCode {
|
||||
*(*byte)(unsafe.Pointer(stackPointer)) = firstChar
|
||||
stackPointer++
|
||||
stack[stackIdx] = firstChar
|
||||
stackIdx++
|
||||
code = oldCode
|
||||
}
|
||||
for code > uint32(clearCode) {
|
||||
*(*byte)(unsafe.Pointer(stackPointer)) = suffix[code]
|
||||
stackPointer++
|
||||
stack[stackIdx] = suffix[code]
|
||||
stackIdx++
|
||||
code = prefix[code]
|
||||
}
|
||||
firstChar = suffix[code]
|
||||
*(*byte)(unsafe.Pointer(stackPointer)) = firstChar
|
||||
stackPointer++
|
||||
stack[stackIdx] = firstChar
|
||||
stackIdx++
|
||||
prefix[freeCode] = oldCode
|
||||
suffix[freeCode] = firstChar
|
||||
if freeCode == codeMask && codeSize < 12 {
|
||||
@ -238,16 +233,16 @@ func (m *TGIFLoader) ReadScanLine(stream *lcl.TMemoryStream) {
|
||||
}
|
||||
oldCode = inCode
|
||||
for {
|
||||
stackPointer--
|
||||
*(*byte)(unsafe.Pointer(target)) = *(*byte)(unsafe.Pointer(stackPointer))
|
||||
target++
|
||||
stackIdx--
|
||||
m.scanLine[targetIdx] = stack[stackIdx]
|
||||
targetIdx++
|
||||
unpackedSize--
|
||||
if stackPointer == uintptr(unsafe.Pointer(&stack[0])) {
|
||||
if stackIdx == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
sourcePtr++
|
||||
sourceDataIdx++
|
||||
packedSize--
|
||||
}
|
||||
}
|
||||
@ -274,8 +269,8 @@ func (m *TGIFLoader) ReadGlobalPalette(stream *lcl.TMemoryStream) {
|
||||
}
|
||||
|
||||
func (m *TGIFLoader) ReadGraphCtrlExt() {
|
||||
m.isTransparent = (m.gifGraphicsCtrlExt.Packedbit & ID_TRANSPARENT) != 0
|
||||
m.disposalMethod = (m.gifGraphicsCtrlExt.Packedbit & 0x1C) >> 2
|
||||
m.isTransparent = (m.gifGraphicsCtrlExt.PackedBit & ID_TRANSPARENT) != 0
|
||||
m.disposalMethod = (m.gifGraphicsCtrlExt.PackedBit & 0x1C) >> 2
|
||||
if m.isTransparent {
|
||||
// 如果透明位图更改alpha通道
|
||||
m.gifBackgroundColor = m.gifGraphicsCtrlExt.ColorIndex
|
||||
|
@ -42,14 +42,6 @@ const (
|
||||
AlphaOpaque uint16 = 0xFFFF
|
||||
)
|
||||
|
||||
const (
|
||||
SoFromBeginning = iota
|
||||
SoFromCurrent
|
||||
SoFromEnd
|
||||
)
|
||||
|
||||
type PByte = uintptr
|
||||
|
||||
type TRGB struct {
|
||||
Red, Green, Blue byte
|
||||
}
|
||||
@ -168,7 +160,7 @@ func (m *TGIFPlay) ResetImage() {
|
||||
m.currentImage = 0
|
||||
canvas := m.currentView.Canvas()
|
||||
canvas.Brush().SetColor(m.Color())
|
||||
canvas.FillRect(types.TRect{Left: 0, Top: 0, Right: m.Width(), Bottom: m.Height()})
|
||||
canvas.FillRect(types.Rect(0, 0, m.Width(), m.Height()))
|
||||
}
|
||||
|
||||
func (m *TGIFPlay) LoadFromFile(filePath string) {
|
||||
|
Loading…
Reference in New Issue
Block a user