Skip to content

Instantly share code, notes, and snippets.

@Arachnid
Created August 18, 2016 09:18
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Arachnid/4bf0dc27432e325505ca7b06f6366114 to your computer and use it in GitHub Desktop.
Save Arachnid/4bf0dc27432e325505ca7b06f6366114 to your computer and use it in GitHub Desktop.
library LZF {
function decompress(bytes memory compressed, bytes memory decompressed) internal {
uint ip;
uint in_end;
uint op;
assembly {
// OP points to the current output location in memory
op := add(decompressed, 32)
// IP actually points to 31 bytes before the desired location, so
// MLOADs work correctly
ip := add(compressed, 1)
in_end := add(ip, mload(compressed))
}
while(ip < in_end) {
uint ctrl;
assembly {
// ctrl = *ip;
ctrl := and(mload(ip), 0xff)
}
ip += 1;
if(ctrl < 0x20) {
ctrl++;
assembly {
// memcpy(op, ip + 31, ctrl);
call(1000, 4, 0, add(ip, 31), ctrl, op, ctrl)
pop
}
op += ctrl;
ip += ctrl;
} else {
uint len = ctrl / 0x20;
uint ref = op - ((ctrl & 0x1F) * 256) - 1;
if(len == 7) {
assembly {
// len += *ip;
len := add(len, and(mload(ip), 0xff))
}
ip += 1;
}
assembly {
// ref -= *ip;
ref := sub(ref, and(mload(ip), 0xff))
}
ip += 1;
len += 2;
if(op >= ref + len) {
// Disjoint; copy as a block
assembly {
// memcpy(op, ref, len);
call(1000, 4, 0, ref, len, op, len)
pop
}
op += len;
} else {
// Overlapping; copy byte-by-byte
while(len-- > 0) {
assembly {
mstore8(op, mload(sub(ref, 31)))
}
op += 1;
ref += 1;
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment