Skip to content

Instantly share code, notes, and snippets.

@yhirose
Created April 7, 2014 02:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yhirose/10014108 to your computer and use it in GitHub Desktop.
Save yhirose/10014108 to your computer and use it in GitHub Desktop.
Decompress LZ4 data
def lz4_decompress(path)
def read_value(data, pos, size)
case size
when 1; type = 'C'
when 2; type = 'S'
when 4; type = 'L'
end
[pos + size, data[pos, size].unpack(type)[0]]
end
def read_literal(data, pos, size)
[pos + size, data[pos, size]]
end
data = File.open(path, "rb:ascii-8bit").read
out = ''
pos, content_size = read_value(data, 0, 4)
while true
pos, token = read_value(data, pos, 1)
literal_length = token >> 4
match_length = token & 0xf
if literal_length == 15
s = 255
while s == 255
pos, s = read_value(data, pos, 1)
literal_length += s
end
end
if literal_length > 0
pos, literal = read_literal(data, pos, literal_length)
out += literal
end
break if pos == data.size
pos, offset = read_value(data, pos, 2)
if match_length == 15
s = 255
while s == 255
pos, s = read_value(data, pos, 1)
match_length += s
end
end
match_length += 4
if match_length > offset
repeat_literal = out[offset * -1, offset]
match_literal = repeat_literal
while match_literal.size < match_length
match_literal += repeat_literal[0, match_length - match_literal.size]
end
else
match_literal = out[offset * -1, match_length]
end
out += match_literal
end
out
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment