Fix off-by-one error in LZ77 implementation rarely resulting in truncated files on inflate.
This commit is contained in:
parent
a5966a6382
commit
42c3362a3c
@ -258,7 +258,7 @@ class Lz77Compress:
|
|||||||
# byte and then 8 instructions.
|
# byte and then 8 instructions.
|
||||||
flags = 0x0
|
flags = 0x0
|
||||||
flagpos = -1
|
flagpos = -1
|
||||||
data: List[bytes] = [b"\x00"] * 8
|
data: List[bytes] = [b""] * 8
|
||||||
|
|
||||||
for _ in range(8):
|
for _ in range(8):
|
||||||
# Track what flag we're generating data for
|
# Track what flag we're generating data for
|
||||||
@ -289,7 +289,7 @@ class Lz77Compress:
|
|||||||
backref_amount = min(self.left, 18)
|
backref_amount = min(self.left, 18)
|
||||||
|
|
||||||
# Iterate over all spots where the first byte equals, and is in range.
|
# Iterate over all spots where the first byte equals, and is in range.
|
||||||
earliest = max(0, self.bytes_written - self.ringlength)
|
earliest = max(0, self.bytes_written - (self.ringlength - 1))
|
||||||
possible_backref_locations: List[int] = [
|
possible_backref_locations: List[int] = [
|
||||||
absolute_pos for absolute_pos in self.starts[self.data[self.read_pos:(self.read_pos + 3)]]
|
absolute_pos for absolute_pos in self.starts[self.data[self.read_pos:(self.read_pos + 3)]]
|
||||||
if absolute_pos >= earliest
|
if absolute_pos >= earliest
|
||||||
@ -344,7 +344,7 @@ class Lz77Compress:
|
|||||||
self.read_pos += copy_amount
|
self.read_pos += copy_amount
|
||||||
self.left -= copy_amount
|
self.left -= copy_amount
|
||||||
|
|
||||||
yield bytes([flags]) + b"".join(data[:(flagpos + 1)])
|
yield bytes([flags]) + b"".join(data)
|
||||||
|
|
||||||
|
|
||||||
class Lz77:
|
class Lz77:
|
||||||
|
BIN
bemani/tests/rawdata
Normal file
BIN
bemani/tests/rawdata
Normal file
Binary file not shown.
@ -75,6 +75,17 @@ class TestLz77RealCompressor(unittest.TestCase):
|
|||||||
decompresseddata = lz77.decompress(compresseddata)
|
decompresseddata = lz77.decompress(compresseddata)
|
||||||
self.assertEqual(data, decompresseddata)
|
self.assertEqual(data, decompresseddata)
|
||||||
|
|
||||||
|
def test_texture(self) -> None:
|
||||||
|
lz77 = Lz77()
|
||||||
|
data = get_fixture("rawdata")
|
||||||
|
|
||||||
|
compresseddata = lz77.compress(data)
|
||||||
|
self.assertNotEqual(data, compresseddata)
|
||||||
|
self.assertTrue(len(compresseddata) < len(data))
|
||||||
|
|
||||||
|
decompresseddata = lz77.decompress(compresseddata)
|
||||||
|
self.assertEqual(data, decompresseddata)
|
||||||
|
|
||||||
def test_known_compression(self) -> None:
|
def test_known_compression(self) -> None:
|
||||||
"""
|
"""
|
||||||
Specifically tests for ability to compress an overlap,
|
Specifically tests for ability to compress an overlap,
|
||||||
|
Loading…
Reference in New Issue
Block a user