• Source
    1. uncompress=->bytes,verbose=false{
    2. #p bytes
    3. rbytes=[]
    4. i=j=0
    5. getb=->{
    6. b=bytes[i] or raise "#{i},#{j}"
    7. i+=1
    8. b
    9. }
    10. setb=->b{
    11. rbytes[j]=b
    12. j+=1
    13. }
    14. copy=->a,off{
    15. (a+1).times{
    16. rbytes[j]=rbytes[j-off]
    17. j+=1
    18. }
    19. }
    20. buf=0
    21. sbits=0
    22. fill=->{
    23. ibak=i
    24. bl=getb[]
    25. bh=getb[]
    26. w=(bh<<8)|bl
    27. buf|=w<<(16-sbits)
    28. sbits+=16
    29. warn "fill @#{ibak}" if verbose
    30. }
    31. getbw=->{
    32. buf>>16
    33. }
    34. discard=->d{
    35. return if d==0
    36. buf=(buf<<d)&0xffffffff
    37. sbits-=d
    38. if sbits<16
    39. fill[]
    40. end
    41. }
    42. judge1=->{
    43. w=getbw[]
    44. #p "j1: %04x" % w
    45. case w
    46. when 0...0x200
    47. [(w>>2)|0x80, 13]
    48. when 0x200...0x400
    49. [w>>3, 12]
    50. when 0x400...0x800
    51. [w>>5, 10]
    52. when 0x800...0x1000
    53. [w>>7, 8]
    54. when 0x1000...0x2000
    55. [w>>9, 6]
    56. when 0x2000...0x4000
    57. [w>>11, 4]
    58. when 0x4000...0x8000
    59. [w>>13, 2]
    60. else
    61. [1, 0]
    62. end
    63. }
    64. judge2=->{
    65. w=getbw[] & 0x7fff
    66. #p "j2: %04x" % w
    67. w &= 0x7fff
    68. case w
    69. when 0...0x800
    70. [w>>9, 7]
    71. when 0x800...0xc00
    72. [(w>>8)-4, 8]
    73. when 0xc00...0x1800
    74. [(w>>7)-0x10, 9]
    75. when 0x1800...0x3000
    76. [(w>>6)-0x40, 10]
    77. else
    78. sw=8-(w>>12)
    79. [(w&0xfff|0x1000)>>sw, 16-sw]
    80. end
    81. }
    82. fill[]
    83. begin
    84. loop{
    85. warn "getf @#{i}" if verbose
    86. cb=getb[]
    87. warn "flag byte: #{'%08b'%cb}" if verbose
    88. 7.downto(0){|k|
    89. if cb[k]>0
    90. warn "copyraw @#{i} -> @#{j}" if verbose
    91. setb[getb[]]
    92. else
    93. p1,d1=judge1[]
    94. if p1==0xff
    95. warn "detect end mark (p1=0xff)"
    96. break
    97. end
    98. discard[d1]
    99. p2,d2=judge2[]
    100. discard[d2]
    101. if verbose
    102. warn "repeat @#{j} from -#{p2} by #{p1+1}, consume #{d1+d2}"
    103. bufs=("%032b"%buf)[0...sbits]
    104. warn "pooled #{bufs} ( #{sbits} bits )"
    105. end
    106. copy[p1,p2+1]
    107. end
    108. } or break
    109. }
    110. rescue => e
    111. warn " * error #{e} in uncompression *"
    112. end
    113. rbytes
    114. }
    115. cbytes = $<.flat_map{|line| line.scan(/\w\w/).map{|t| t.to_i(16) } }
    116. rbytes=uncompress[cbytes,true]
    117.  
    118. 0.step{|off|
    119. bytes=[]
    120. dobreak=false
    121. 16.times{|i|
    122. b=rbytes[off*16+i] or break
    123. bytes[i]=b
    124. } or dobreak=true
    125. break if bytes.size==0
    126. bstrs=[" "]*16
    127. bytes.each_with_index{|b,i| bstrs[i]="%02x" % b}
    128. puts (" %02x0: %s" % [off, bstrs.each_slice(2).map{|(s1,s2)| s1+s2 }*" "])
    129. break if dobreak
    130. }