Advertisement
Guest User

Falcom Compress v1

a guest
May 22nd, 2016
495
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.13 KB | None | 0 0
  1. import struct
  2. import io
  3.  
  4. outfilename = 'test.cmp'
  5. infilename = 'skill.unc'
  6. def _updateflags(out):
  7. ###"Writes" a flag
  8. ###Writes data if the flag buffer is full, then flushes
  9.     global comp_buffer
  10.     global flag_pos     #Other functions need read access so it has to be global (or passed back and forth)
  11.     flags = 0
  12.     flag_write = 0x8000
  13.     flag_pos = 8
  14.     b = (yield)         #At this point ready to pass in first flag bit
  15.     while True:
  16.         if b:   #Write a "1" (otherwise write 0)
  17.             flags |= flag_write     #Writes a "1"
  18.         flag_pos -= 1
  19.         if flag_pos == 0:
  20.             out.write(struct.pack('<H', flags))
  21.             out.write(comp_buffer)
  22.             comp_buffer = bytearray(0)
  23.             flag_pos = 16
  24.             flags = 0
  25.         else:
  26.             flags >>= 1
  27.         b = (yield)
  28.  
  29. def compress_FALCOM3(filedata):
  30.     out = io.BytesIO()
  31.     data = compress_FALCOM2(filedata)
  32.     #Format is compressed size + 11, decompressed size, chunks, 1st chunk size
  33.     out.write(struct.pack('<IIIH',  len(data) + 11,     #Extra IIHB
  34.                                     len(filedata),
  35.                                     1, len(data)))
  36.     out.write(data)
  37.     out.write(b'\x00')                                  #Stop flag
  38.     out.seek(0)
  39.     return out.read()
  40.  
  41. def compress_FALCOM2(filedata):
  42.     global comp_buffer                  #Other functions need write access
  43.     global out
  44.     file_size = len(filedata)
  45.     file_pos = 0
  46.     comp_buffer = bytearray(0)
  47.     out = io.BytesIO()
  48.     updateflags = _updateflags(out) #Initalize generator
  49.     next(updateflags)               #More initialize generator
  50.     while file_pos < file_size:
  51. ##        print(hex(file_pos))
  52.         match_size = 0
  53.         match_pos = 0
  54.         if file_pos < 0xFF:
  55.             buffer_start = 0
  56.         else:
  57.             buffer_start = file_pos - 255
  58.         for i, byte in enumerate(filedata[buffer_start:file_pos]):
  59.             i += buffer_start
  60.             if byte == filedata[file_pos]:
  61.                 j = 1
  62.                 while True:
  63.                     if i + j == file_pos:
  64.                         break
  65.                     if file_pos + j == file_size:
  66.                         break
  67.                     if filedata[i+j] != filedata[file_pos+j]:
  68.                         break
  69.                     j += 1
  70.                 if j >= match_size:
  71.                     match_size = j
  72.                     match_pos = file_pos - i
  73.         if match_size > 2:
  74. ##            print(match_size)
  75.             if match_size <= 0xFF and match_pos <= 0xFF:
  76.                 updateflags.send(True)
  77.                 comp_buffer.append(match_pos)
  78.                 updateflags.send(False)
  79.                 file_pos += match_size
  80.                 for i in range(2, 5):
  81.                     if i >= match_size:
  82.                         break
  83.                     updateflags.send(False)
  84.                 if match_size >= 6:
  85.                     updateflags.send(False)
  86.                     if match_size >= 0xE:
  87.                         match_size -= 0xE
  88.                         comp_buffer.append(match_size)
  89.                         updateflags.send(False)
  90.                     else:
  91.                         updateflags.send(True)
  92.                         match_size -= 0x6
  93.                         for i in reversed(range(3)):
  94.                             updateflags.send((match_size >> i) & 1)
  95.                 else:
  96.                     updateflags.send(True)
  97.             else:
  98.                 comp_buffer.append(filedata[file_pos])
  99.                 file_pos += 1
  100.                 updateflags.send(False)
  101.         else:
  102.             comp_buffer.append(filedata[file_pos])
  103.             file_pos += 1
  104.             updateflags.send(False)
  105.     for x in range(2):
  106.         updateflags.send(True)
  107.     for x in range(5):
  108.         updateflags.send(False)
  109.     for x in range(0x10 - flag_pos):
  110.         updateflags.send(False)
  111.     out.write(b'\x00')
  112.     out.seek(0)
  113.     return out.read()
  114. if __name__ == '__main__':
  115.     pass
  116.     ##with open('skill.unc', 'rb') as f:
  117.     ##    with open('test.cmp', 'wb') as g:
  118.     ##        g.write(compress_FALCOM3(f.read()))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement