1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2025-07-26 11:24:38 -04:00

HuffmanDecompress: use d2datautils.BitMuncher instead of d2datautils.BitStream; delete d2datautils/bitstream*

This commit is contained in:
gucio321 2021-05-16 12:08:20 +02:00
parent a688d660a0
commit 3260022ffb
3 changed files with 26 additions and 135 deletions

View File

@ -128,7 +128,8 @@ func getPrimes() [][]byte {
0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B,
}, {
},
{
// Compression type 2 //nolint:dupl // it doesnt matter here
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -138,7 +139,8 @@ func getPrimes() [][]byte {
0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01,
0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A,
0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01,
}, { //nolint:dupl // it doesnt matter here
},
{ //nolint:dupl // it doesnt matter here
// Compression type 3 //nolint:dupl // it doesnt matter here
0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03,
0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
@ -156,14 +158,17 @@ func getPrimes() [][]byte {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11,
}, { // Compression type 4 //nolint:dupl // it doesnt matter here
},
{ // Compression type 4 //nolint:dupl // it doesnt matter here
0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17,
}, { // Compression type 5 //nolint:dupl // it doesnt matter here
},
{ // Compression type 5 //nolint:dupl // it doesnt matter here
0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82,
0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37,
0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D,
0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18,
}, { //nolint:dupl // it doesnt matter here
},
{ //nolint:dupl // it doesnt matter here
// Compression type 6
0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -174,7 +179,8 @@ func getPrimes() [][]byte {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7A, 0x46,
}, { //nolint:dupl // it doesnt matter here
},
{ //nolint:dupl // it doesnt matter here
// Compression type 7
0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -185,7 +191,8 @@ func getPrimes() [][]byte {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x70, 0x6C,
}, { // Compression type 8
},
{ // Compression type 8
0xBA, 0xC5, 0xDA, 0x33, 0xE3, 0x6D, 0xD8, 0x18, 0xE5, 0x94, 0xDA, 0x23, 0xDF, 0x4A, 0xD1, 0x10,
0xEE, 0xAF, 0xE4, 0x2C, 0xEA, 0x5A, 0xDE, 0x15, 0xF4, 0x87, 0xE9, 0x21, 0xF6, 0x43, 0xFC, 0x12,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -199,15 +206,17 @@ func getPrimes() [][]byte {
}
}
func decode(input *d2datautils.BitStream, head *linkedNode) *linkedNode {
func decode(input *d2datautils.BitMuncher, head *linkedNode) *linkedNode {
node := head
for node.child0 != nil {
bit := input.ReadBits(1)
if bit == -1 {
log.Fatal("unexpected end of file")
}
// checks if GetBit causes panic (End of file)
defer func() {
if r := recover(); r != nil {
log.Fatal("HuffmanDecompress: Unexpected end of file")
}
}()
bit := input.GetBit()
if bit == 0 {
node = node.child0
continue
@ -387,7 +396,7 @@ func HuffmanDecompress(data []byte) []byte {
head := buildTree(tail)
outputstream := d2datautils.CreateStreamWriter()
bitstream := d2datautils.CreateBitStream(data[1:])
bitstream := d2datautils.CreateBitMuncher(data[1:], 0)
var decoded int
@ -399,10 +408,10 @@ Loop:
case 256:
break Loop
case 257:
newvalue := bitstream.ReadBits(8)
newvalue := bitstream.GetByte()
outputstream.PushBytes(byte(newvalue))
tail = insertNode(tail, newvalue)
outputstream.PushBytes(newvalue)
tail = insertNode(tail, int(newvalue))
default:
outputstream.PushBytes(byte(decoded))
}

View File

@ -1,82 +0,0 @@
package d2datautils
import (
"log"
)
const (
maxBits = 16
bitsPerByte = 8
)
// BitStream is a utility class for reading groups of bits from a stream
type BitStream struct {
data []byte
dataPosition int
current int
bitCount int
}
// CreateBitStream creates a new BitStream
func CreateBitStream(newData []byte) *BitStream {
result := &BitStream{
data: newData,
dataPosition: 0,
current: 0,
bitCount: 0,
}
return result
}
// ReadBits reads the specified number of bits and returns the value
func (v *BitStream) ReadBits(bitCount int) int {
if bitCount > maxBits {
log.Panic("Maximum BitCount is 16")
}
if !v.EnsureBits(bitCount) {
return -1
}
// nolint:gomnd // byte expresion
result := v.current & (0xffff >> uint(maxBits-bitCount))
v.WasteBits(bitCount)
return result
}
// PeekByte returns the current byte without adjusting the position
func (v *BitStream) PeekByte() int {
if !v.EnsureBits(bitsPerByte) {
return -1
}
// nolint:gomnd // byte
return v.current & 0xff
}
// EnsureBits ensures that the specified number of bits are available
func (v *BitStream) EnsureBits(bitCount int) bool {
if bitCount <= v.bitCount {
return true
}
if v.dataPosition >= len(v.data) {
return false
}
nextValue := v.data[v.dataPosition]
v.dataPosition++
v.current |= int(nextValue) << uint(v.bitCount)
v.bitCount += 8
return true
}
// WasteBits dry-reads the specified number of bits
func (v *BitStream) WasteBits(bitCount int) {
// noinspection GoRedundantConversion
v.current >>= uint(bitCount)
v.bitCount -= bitCount
}

View File

@ -1,36 +0,0 @@
package d2datautils
import (
"testing"
)
func TestBitStreamBits(t *testing.T) {
data := []byte{0xAA}
bitStream := CreateBitStream(data)
shouldBeOne := 0
for i := 0; i < 8; i++ {
bit := bitStream.ReadBits(1)
if bit != shouldBeOne {
t.Fatalf("Expected %d but got %d on iteration %d", shouldBeOne, bit, i)
}
if shouldBeOne == 1 {
shouldBeOne = 0
} else {
shouldBeOne = 1
}
}
}
func TestBitStreamBytes(t *testing.T) {
data := []byte{0xAA, 0xBB, 0xCC, 0xDD, 0x12, 0x34, 0x56, 0x78}
bitStream := CreateBitStream(data)
for i := 0; i < 8; i++ {
b := byte(bitStream.ReadBits(8))
if b != data[i] {
t.Fatalf("Expected %d but got %d on iteration %d", data[i], b, i)
}
}
}