uncompress=-> bytes,verbose=false {
#p bytes
rbytes=[ ]
i=j=0
getb=-> {
b=bytes[ i] or raise "#{i},#{j}"
i+ =1
b
}
setb=-> b{
rbytes[ j] =b
j+ =1
}
copy=-> a,off{
( a+ 1 ) .times {
rbytes[ j] =rbytes[ j- off]
j+ =1
}
}
buf=0
sbits=0
fill=-> {
ibak=i
bl=getb[ ]
bh=getb[ ]
w=( bh<< 8 ) | bl
buf| =w<< ( 16 - sbits)
sbits+ =16
warn "fill @#{ibak}" if verbose
}
getbw=-> {
buf>> 16
}
discard=-> d{
return if d==0
buf=( buf<< d) & 0xffffffff
sbits- =d
if sbits< 16
fill[ ]
end
}
judge1=-> {
w=getbw[ ]
#p "j1: %04x" % w
case w
when 0 ...0x200
[ ( w>> 2 ) | 0x80, 13 ]
when 0x200...0x400
[ w>> 3 , 12 ]
when 0x400...0x800
[ w>> 5 , 10 ]
when 0x800...0x1000
[ w>> 7 , 8 ]
when 0x1000...0x2000
[ w>> 9 , 6 ]
when 0x2000...0x4000
[ w>> 11 , 4 ]
when 0x4000...0x8000
[ w>> 13 , 2 ]
else
[ 1 , 0 ]
end
}
judge2=-> {
w=getbw[ ] & 0x7fff
#p "j2: %04x" % w
w & = 0x7fff
case w
when 0 ...0x800
[ w>> 9 , 7 ]
when 0x800...0xc00
[ ( w>> 8 ) - 4 , 8 ]
when 0xc00...0x1800
[ ( w>> 7 ) - 0x10, 9 ]
when 0x1800...0x3000
[ ( w>> 6 ) - 0x40, 10 ]
else
sw=8 - ( w>> 12 )
[ ( w& 0xfff| 0x1000) >> sw, 16 - sw]
end
}
fill[ ]
begin
loop {
warn "getf @#{i}" if verbose
cb=getb[ ]
warn "flag byte: #{'%08b'%cb}" if verbose
7 .downto ( 0 ) { | k|
if cb[ k] > 0
warn "copyraw @#{i} -> @#{j}" if verbose
setb[ getb[ ] ]
else
p1,d1=judge1[ ]
if p1==0xff
warn "detect end mark (p1=0xff)"
break
end
discard[ d1]
p2,d2=judge2[ ]
discard[ d2]
if verbose
warn "repeat @#{j} from -#{p2} by #{p1+1}, consume #{d1+d2}"
bufs=( "%032b" % buf) [ 0 ...sbits ]
warn "pooled #{bufs} ( #{sbits} bits )"
end
copy[ p1,p2+ 1 ]
end
} or break
}
rescue => e
warn " * error #{e} in uncompression *"
end
rbytes
}
cbytes = $< .flat_map { | line| line.scan ( / \w\w/ ) .map { | t| t.to_i ( 16 ) } }
rbytes=uncompress[ cbytes,true ]
0 .step { | off|
bytes=[ ]
dobreak=false
16 .times { | i|
b=rbytes[ off* 16 + i] or break
bytes[ i] =b
} or dobreak=true
break if bytes.size ==0
bstrs=[ " " ] * 16
bytes.each_with_index { | b,i| bstrs[ i] ="%02x" % b}
puts ( " %02x0: %s" % [ off, bstrs.each_slice ( 2 ) .map { | ( s1,s2) | s1+ s2 } * " " ] )
break if dobreak
}
dW5jb21wcmVzcz0tPmJ5dGVzLHZlcmJvc2U9ZmFsc2V7CiAgI3AgYnl0ZXMKICByYnl0ZXM9W10KICBpPWo9MAogIGdldGI9LT57CiAgICBiPWJ5dGVzW2ldIG9yIHJhaXNlICIje2l9LCN7an0iCiAgICBpKz0xCiAgICBiCiAgfQogIHNldGI9LT5iewogICAgcmJ5dGVzW2pdPWIKICAgIGorPTEKICB9CiAgY29weT0tPmEsb2ZmewogICAgKGErMSkudGltZXN7CiAgICAgIHJieXRlc1tqXT1yYnl0ZXNbai1vZmZdCiAgICAgIGorPTEKICAgIH0KICB9CiAgYnVmPTAKICBzYml0cz0wCiAgZmlsbD0tPnsKICAgIGliYWs9aQogICAgYmw9Z2V0YltdCiAgICBiaD1nZXRiW10KICAgIHc9KGJoPDw4KXxibAogICAgYnVmfD13PDwoMTYtc2JpdHMpCiAgICBzYml0cys9MTYKICAgIHdhcm4gImZpbGwgQCN7aWJha30iIGlmIHZlcmJvc2UKICB9CiAgZ2V0Ync9LT57CiAgICBidWY+PjE2CiAgfQogIGRpc2NhcmQ9LT5kewogICAgcmV0dXJuIGlmIGQ9PTAKICAgIGJ1Zj0oYnVmPDxkKSYweGZmZmZmZmZmCiAgICBzYml0cy09ZAogICAgaWYgc2JpdHM8MTYKICAgICAgZmlsbFtdCiAgICBlbmQKICB9CiAganVkZ2UxPS0+ewogICAgdz1nZXRid1tdCiAgICAjcCAiajE6ICUwNHgiICUgdwogICAgY2FzZSB3CiAgICB3aGVuIDAuLi4weDIwMAogICAgICBbKHc+PjIpfDB4ODAsIDEzXQogICAgd2hlbiAweDIwMC4uLjB4NDAwCiAgICAgIFt3Pj4zLCAxMl0KICAgIHdoZW4gMHg0MDAuLi4weDgwMAogICAgICBbdz4+NSwgMTBdCiAgICB3aGVuIDB4ODAwLi4uMHgxMDAwCiAgICAgIFt3Pj43LCA4XQogICAgd2hlbiAweDEwMDAuLi4weDIwMDAKICAgICAgW3c+PjksIDZdCiAgICB3aGVuIDB4MjAwMC4uLjB4NDAwMAogICAgICBbdz4+MTEsIDRdCiAgICB3aGVuIDB4NDAwMC4uLjB4ODAwMAogICAgICBbdz4+MTMsIDJdCiAgICBlbHNlCiAgICAgIFsxLCAwXQogICAgZW5kCiAgfQogIGp1ZGdlMj0tPnsKICAgIHc9Z2V0YndbXSAmIDB4N2ZmZgogICAgI3AgImoyOiAlMDR4IiAlIHcKICAgIHcgJj0gMHg3ZmZmCiAgICBjYXNlIHcKICAgIHdoZW4gMC4uLjB4ODAwCiAgICAgIFt3Pj45LCA3XQogICAgd2hlbiAweDgwMC4uLjB4YzAwCiAgICAgIFsodz4+OCktNCwgOF0KICAgIHdoZW4gMHhjMDAuLi4weDE4MDAKICAgICAgWyh3Pj43KS0weDEwLCA5XQogICAgd2hlbiAweDE4MDAuLi4weDMwMDAKICAgICAgWyh3Pj42KS0weDQwLCAxMF0KICAgIGVsc2UKICAgICAgc3c9OC0odz4+MTIpCiAgICAgIFsodyYweGZmZnwweDEwMDApPj5zdywgMTYtc3ddCiAgICBlbmQKICB9CiAgZmlsbFtdCiAgYmVnaW4KICAgIGxvb3B7CiAgICAgIHdhcm4gImdldGYgQCN7aX0iIGlmIHZlcmJvc2UKICAgICAgY2I9Z2V0YltdCiAgICAgIHdhcm4gImZsYWcgYnl0ZTogI3snJTA4YiclY2J9IiBpZiB2ZXJib3NlCiAgICAgIDcuZG93bnRvKDApe3xrfAogICAgICAgIGlmIGNiW2tdPjAKICAgICAgICAgIHdhcm4gImNvcHlyYXcgQCN7aX0gLT4gQCN7an0iIGlmIHZlcmJvc2UKICAgICAgICAgIHNldGJbZ2V0YltdXQogICAgICAgIGVsc2UKICAgICAgICAgIHAxLGQxPWp1ZGdlMVtdCiAgICAgICAgICBpZiBwMT09MHhmZgogICAgICAgICAgICB3YXJuICJkZXRlY3QgZW5kIG1hcmsgKHAxPTB4ZmYpIgogICAgICAgICAgICBicmVhawogICAgICAgICAgZW5kCiAgICAgICAgICBkaXNjYXJkW2QxXQogICAgICAgICAgcDIsZDI9anVkZ2UyW10KICAgICAgICAgIGRpc2NhcmRbZDJdCiAgICAgICAgICBpZiB2ZXJib3NlCiAgICAgICAgICAgIHdhcm4gInJlcGVhdCBAI3tqfSBmcm9tIC0je3AyfSBieSAje3AxKzF9LCBjb25zdW1lICN7ZDErZDJ9IgogICAgICAgICAgICBidWZzPSgiJTAzMmIiJWJ1ZilbMC4uLnNiaXRzXQogICAgICAgICAgICB3YXJuICJwb29sZWQgI3tidWZzfSAoICN7c2JpdHN9IGJpdHMgKSIKICAgICAgICAgIGVuZAogICAgICAgICAgY29weVtwMSxwMisxXQogICAgICAgIGVuZAogICAgICB9IG9yIGJyZWFrCiAgICB9CiAgcmVzY3VlID0+IGUKICAgIHdhcm4gIiAgICogZXJyb3IgI3tlfSBpbiB1bmNvbXByZXNzaW9uICoiCiAgZW5kCiAgcmJ5dGVzCn0KY2J5dGVzID0gJDwuZmxhdF9tYXB7fGxpbmV8IGxpbmUuc2NhbigvXHdcdy8pLm1hcHt8dHwgdC50b19pKDE2KSB9IH0KcmJ5dGVzPXVuY29tcHJlc3NbY2J5dGVzLHRydWVdCgowLnN0ZXB7fG9mZnwKICBieXRlcz1bXQogIGRvYnJlYWs9ZmFsc2UKICAxNi50aW1lc3t8aXwKICAgIGI9cmJ5dGVzW29mZioxNitpXSBvciBicmVhawogICAgYnl0ZXNbaV09YgogIH0gb3IgZG9icmVhaz10cnVlCiAgYnJlYWsgaWYgYnl0ZXMuc2l6ZT09MAogIGJzdHJzPVsiICAiXSoxNgogIGJ5dGVzLmVhY2hfd2l0aF9pbmRleHt8YixpfCBic3Ryc1tpXT0iJTAyeCIgJSBifQogIHB1dHMgKCIgICAgJTAyeDA6ICVzIiAlIFtvZmYsIGJzdHJzLmVhY2hfc2xpY2UoMikubWFwe3woczEsczIpfCBzMStzMiB9KiIgIl0pCiAgYnJlYWsgaWYgZG9icmVhawp9
stdout
000: 0000 0000 ffff ffff 0000 0000 0000 0000
010: 0000 0000 0000 0000 0000 0000 0000 0000
020: 0000 0000 0000 0000 0000 0000 0000 0000
stderr
fill @0
getf @2
flag byte: 10100000
copyraw @3 -> @0
fill @4
repeat @1 from -0 by 3, consume 9
pooled 01000000001100010110000 ( 23 bits )
copyraw @6 -> @4
fill @7
repeat @5 from -0 by 3, consume 9
pooled 011000101100000100011000000000 ( 30 bits )
repeat @8 from -7 by 4, consume 10
pooled 00000100011000000000 ( 20 bits )
fill @9
repeat @12 from -0 by 36, consume 17
pooled 0000000111111100000 ( 19 bits )
detect end mark (p1=0xff)