diff options
| author | Juan Manuel Tomás <jtomas1815@gmail.com> | 2025-11-04 17:53:41 -0300 |
|---|---|---|
| committer | Juan Manuel Tomás <jtomas1815@gmail.com> | 2025-11-04 17:53:41 -0300 |
| commit | 4e6aae19275dad2053adbc2ad34ab1330daf1b0f (patch) | |
| tree | 0f6d08e48b06be9ee48ca6848289068ea228112c /decode.lisp | |
| parent | d2a8d3a2171ebbc9934e3703a0f9b6fd4070a6b8 (diff) | |
| download | lempel-4e6aae19275dad2053adbc2ad34ab1330daf1b0f.tar.gz lempel-4e6aae19275dad2053adbc2ad34ab1330daf1b0f.zip | |
Working decoder on byte level
Diffstat (limited to 'decode.lisp')
| -rw-r--r-- | decode.lisp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/decode.lisp b/decode.lisp new file mode 100644 index 0000000..df578a7 --- /dev/null +++ b/decode.lisp @@ -0,0 +1,55 @@ +(in-package #:lempel) + +(declaim (ftype (function ((array (unsigned-byte 8)) (unsigned-byte 8)) (array (unsigned-byte 8))) prefix-decode)) +(defun prefix-decode (data prefix) + (let ((result (queue:new))) + (dotimes (i (length data)) + (cond ((= (elt data i) prefix) + (let ((point (byte-pair->point data i))) + (if (= (point-size point) 0) + (progn + (queue:push prefix result) + (incf i)) + (progn + (queue:push point result) + (incf i 2))))) + (t (queue:push (elt data i) result)))) + (decompress (queue:to-list result)))) + +(declaim (ftype (function (list) (array (unsigned-byte 8))) decompress)) +(defun decompress (data) + (declare (optimize (debug 3))) + (let ((result (make-array (get-uncompressed-size data) :element-type '(unsigned-byte 8))) + (fill-count 0)) + (dolist (point data) + (cond ((point-p point) + (let ((start (- fill-count (point-offset point)))) + (dotimes (j (point-size point)) + (setf (elt result (+ fill-count j)) (elt result (+ start j)))) + (incf fill-count (point-size point)))) + ((typep point '(unsigned-byte 8)) + (setf (elt result fill-count) point) + (incf fill-count)) + (t (error (format nil "cannot handle type ~a" (type-of point)))))) + (assert (= fill-count (length result))) + result)) + +(declaim (ftype (function ((array (unsigned-byte 8)) fixnum) point) byte-pair->point)) +(defun byte-pair->point (bytes index) + (let ((offset (elt bytes (+ (if reversed-byte-order 2 1) index))) + (size (elt bytes (+ (if reversed-byte-order 1 2) index))) + (max-word-length (1- (ash 1 (- 16 window-bits))))) + (make-point :offset (logior offset + (ash (logand size (logxor #xff max-word-length)) + (- window-bits 8))) + :size (logand size max-word-length)))) + +(declaim (ftype (function (list) fixnum) get-uncompressed-size)) +(defun get-uncompressed-size (data) + (let ((size 0)) + (dolist (point data) + (cond ((point-p point) + (incf size (point-size point))) + (t + (incf size)))) + size)) |
