Advertisement
Zoinkity

8:8 LZSS

Jun 28th, 2018
335
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.69 KB | None | 0 0
  1. accepts: A0=p->src, A1=p->target, A2=sz
  2. 8C860004 LW A2,0004 (A0)
  3. 24840008 ADDIU A0,A0,0008
  4. 00C53021 ADDU A2,A2,A1
  5. @fill
  6. 24090080 ADDIU T1,R0,0080
  7. 90880000 LBU T0,0000 (A0)
  8. 24840001 ADDIU A0,A0,0001
  9. @dec
  10. 1120FFFC BEQ T1,R0,fill
  11. 01280824 AND AT,T1,T0
  12. 10200005 BEQ AT,R0,run
  13. 00094842 SRL T1,T1,0x1
  14. 90810000 LBU AT,0000 (A0)
  15. 24A50001 ADDIU A1,A1,0001
  16. 10000009 BEQ R0,R0,loop
  17. 24840001 ADDIU A0,A0,0001
  18. @run
  19. 90830000 LBU V1,0000 (A0)
  20. 90820001 LBU V0,0001 (A0)
  21. 24840002 ADDIU A0,A0,0002
  22. 00A23823 SUBU A3,A1,V0
  23. 2463FFFF ADDIU V1,V1,FFFF
  24. 90E1FFFF LBU AT,FFFF (A3)
  25. 24A50001 ADDIU A1,A1,0001
  26. 0461FFFB BGEZ V1,-5
  27. @loop
  28. A0A1FFFF SB AT,FFFF (A1)
  29. 14A6FFEE BNE A1,A2,dec
  30. 00000000 NOP
  31. 03E00008 JR RA
  32. 00000000 NOP
  33.  
  34.  
  35.  
  36. #!/usr/bin/env python3
  37. # -*- coding: utf-8 -*-
  38.  
  39. def _search(data, pos, sz, cap = 0x100):
  40. ml = min(cap, sz - pos)
  41. if ml < 3:
  42. return 0, 0
  43. mp = max(0, pos - 0x100)
  44. hitp, hitl = 0, 3
  45. if mp < pos:
  46. ## hl = _seqfind(data[mp:pos+hitl], hitl)
  47. hl = data[mp:pos+hitl].index(data[pos:pos+hitl])
  48. while hl < (pos - mp):
  49. while (hitl < ml) and (data[pos + hitl] == data[mp + hl + hitl]):
  50. hitl += 1
  51. mp += hl
  52. hitp = mp
  53. if hitl == ml:
  54. return hitp, hitl
  55. mp += 1
  56. hitl += 1
  57. if mp >= pos:
  58. break
  59. ## hl = _seqfind(data[mp:pos+hitl], hitl)
  60. hl = data[mp:pos+hitl].index(data[pos:pos+hitl])
  61. # If length less than 4, return miss.
  62. if hitl < 4:
  63. hitl = 1
  64. return hitp, hitl-1
  65.  
  66. def encode(data:(bytes, bytearray)) -> bytes:
  67. """Encodes a bytes-like object as a bytes object.
  68. """
  69. from struct import Struct
  70. pat = Struct(">2L")
  71.  
  72. cap = 0x100
  73. sz = len(data)
  74. itr = bytearray()
  75. cmds = itr
  76. ctrl = itr
  77. raws = itr
  78. # Keep current cmd position so stream mode trick works.
  79. cmdpos = 0
  80. cmds.append(0)
  81. pos, flag = 0, 0x80
  82. while pos < sz:
  83. hitp, hitl = _search(data, pos, sz, cap)
  84. if hitl < 3:
  85. # Push a raw if copying isn't possible.
  86. raws.append(data[pos])
  87. pos += 1
  88. else:
  89. tstp, tstl = _search(data, pos+1, sz, cap)
  90. if (hitl + 1) < tstl:
  91. raws.append(data[pos])
  92. pos += 1
  93. flag >>= 1
  94. if not flag:
  95. flag = 0x80
  96. cmdpos = len(cmds)
  97. cmds.append(0)
  98. hitl = tstl
  99. hitp = tstp
  100. cmds[cmdpos] |= flag
  101. e = pos - hitp - 1
  102. pos += hitl
  103. # Handle MIx first, then Yax conditions.
  104. hitl -= 1
  105. ctrl.append(hitl)
  106. ctrl.append(e)
  107. # Advance the flag and refill if required.
  108. flag >>= 1
  109. if not flag:
  110. flag = 0x80
  111. cmdpos = len(cmds)
  112. cmds.append(0)
  113. # If no cmds in final word, del it.
  114. if flag == 0x80:
  115. del cmds[cmdpos]
  116. # All three thingies should return the full bytearray.
  117. return b''.join((pat.pack(len(cmds) + 8, sz), cmds))
  118.  
  119. def decode(data: (bytes, bytearray)) -> bytes:
  120. import struct
  121. cmp_sz, dec_sz = struct.unpack_from(">LL", data)
  122. src = iter(data[8:])
  123. f, c = 0, 0
  124. out = bytearray()
  125. while len(out) < dec_sz:
  126. if not f:
  127. f = 0x80
  128. c = next(src)
  129. if c & f:
  130. l = next(src) + 1
  131. p = next(src) + 1
  132. for i in range(l):
  133. out.append(out[-p])
  134. else:
  135. out.append(next(src))
  136. f >>= 1
  137. return bytes(out)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement