mirror of
https://github.com/dschmenk/PLASMA.git
synced 2024-06-10 02:29:30 +00:00
108 lines
2.3 KiB
Plaintext
108 lines
2.3 KiB
Plaintext
include "inc/cmdsys.plh"
|
|
include "inc/args.plh"
|
|
include "inc/fileio.plh"
|
|
include "inc/lz4.plh"
|
|
|
|
struc t_header
|
|
word magic[2]
|
|
byte FLG
|
|
byte BD
|
|
end
|
|
word arg
|
|
byte ref
|
|
|
|
def lz4ReadBlock(flags)#2
|
|
word size[2], block, data, len
|
|
|
|
len = fileio:read(ref, @size, 4)
|
|
if len <> 4 or size[0] == 0 or size[1] & $7FFF
|
|
return NULL, 0
|
|
fin
|
|
block = heapalloc(size[0])
|
|
if block
|
|
len = fileio:read(ref, block, size[0])
|
|
if len <> size[0]
|
|
heaprelease(block)
|
|
return NULL, 0
|
|
fin
|
|
else
|
|
return NULL, 0
|
|
fin
|
|
if size[1] & $8000
|
|
//
|
|
// Uncompressed block
|
|
//
|
|
data = block
|
|
else
|
|
//
|
|
// Decompress block
|
|
//
|
|
len = heapavail - 256 // Allocate almost entire heap to decompress into
|
|
data = heapalloc(len)
|
|
if data
|
|
len = lz4Unpack(block, block + size[0], data, data + len)
|
|
memcpy(block, data, len)
|
|
data = block
|
|
else
|
|
len = 0
|
|
fin
|
|
heaprelease(block + len)
|
|
fin
|
|
if flags & $10 // Block Checksum
|
|
fileio:read(ref, @size, 4)
|
|
fin
|
|
return data, len
|
|
end
|
|
def lz4ReadFrame#0
|
|
word data, len
|
|
byte header[t_header], opt
|
|
|
|
fileio:read(ref, @header, t_header)
|
|
if header:magic[1] <> $184D or header:magic[0] <> $2204
|
|
puts("Not LZ4 file.\n")
|
|
return
|
|
fin
|
|
if header.FLG & $C0 <> $40
|
|
puts("Wrong LZ4 version.\n")
|
|
return
|
|
fin
|
|
if header.BD & $70 <> $40
|
|
puts("Not 64K block size.\n")
|
|
return
|
|
fin
|
|
opt = 1
|
|
if header.FLG & $08 // Content Size
|
|
opt = opt + 8
|
|
fin
|
|
if header.FLG & $01 // Dictionary ID
|
|
opt = opt + 4
|
|
fin
|
|
fileio:read(ref, heapmark, opt) // Read rest of header and throw away
|
|
repeat
|
|
data, len = lz4ReadBlock(header.FLG)
|
|
if len
|
|
while len
|
|
putc(^data <> $0A ?? ^data :: $0D)
|
|
data++
|
|
len--
|
|
loop
|
|
heaprelease(data)
|
|
fin
|
|
until not data
|
|
if header.FLG & $04 // Content Checksun
|
|
fileio:read(ref, heapmark, 4)
|
|
fin
|
|
end
|
|
arg = argNext(argFirst)
|
|
if ^arg
|
|
ref = fileio:open(arg)
|
|
if ref
|
|
lz4ReadFrame
|
|
fileio:close(ref)
|
|
else
|
|
puts("File not found.\n")
|
|
fin
|
|
fin
|
|
|
|
done
|