lz77/lib/encoder.ml

39 lines
1.3 KiB
OCaml

let min_match_len = 3
let max_match_len = 255
let lookahead_size = 256
let window_size = 32768
let compress input =
let len = Bytes.length input in
let window = Window.create () in
let finder = Finder.create () in
let writer = Writer.create () in
let rec loop pos =
if pos >= len then () else
let la_len = min (len - pos) lookahead_size in
if la_len < min_match_len then (
for i = pos to len - 1 do
let byte = Char.code (Bytes.get input i) in
Writer.write_literal writer byte;
Window.add_byte window byte;
Finder.add_bytes finder window input i 1
done
) else (
match Finder.find_longest finder window input pos la_len with
| Some (distance, match_len) ->
let match_len = min match_len max_match_len in
Writer.write_match writer distance match_len;
Window.add_bytes window input pos match_len;
Finder.add_bytes finder window input pos match_len;
loop (pos + match_len)
| None ->
let byte = Char.code (Bytes.get input pos) in
Writer.write_literal writer byte;
Window.add_byte window byte;
Finder.add_bytes finder window input pos 1;
loop (pos + 1)
)
in
loop 0;
Writer.to_bytes writer