| 1 |
;;; cl-pdf copyright 2002-2005 Marc Battyani see license.txt for the details |
|---|
| 2 |
;;; You can reach me at marc.battyani@fractalconcept.com or marc@battyani.net |
|---|
| 3 |
;;; The homepage of cl-pdf is here: http://www.fractalconcept.com/asp/html/cl-pdf.html |
|---|
| 4 |
|
|---|
| 5 |
(in-package #:pdf) |
|---|
| 6 |
|
|---|
| 7 |
;;; UFFI zlib |
|---|
| 8 |
|
|---|
| 9 |
#+use-uffi-zlib |
|---|
| 10 |
(defun load-zlib (&optional force) |
|---|
| 11 |
(when force (setf *zlib-loaded* nil)) |
|---|
| 12 |
(unless *zlib-loaded* |
|---|
| 13 |
(let ((zlib-path (find-zlib-path))) |
|---|
| 14 |
(if zlib-path |
|---|
| 15 |
(progn |
|---|
| 16 |
(format t "~&;;; Loading ~s" zlib-path) |
|---|
| 17 |
(uffi:load-foreign-library zlib-path |
|---|
| 18 |
:module "zlib" |
|---|
| 19 |
:supporting-libraries '("c")) |
|---|
| 20 |
(uffi:def-function ("compress" c-compress) |
|---|
| 21 |
((dest (* :unsigned-char)) |
|---|
| 22 |
(destlen (* :long)) |
|---|
| 23 |
(source :cstring) |
|---|
| 24 |
(source-len :long)) |
|---|
| 25 |
:returning :int |
|---|
| 26 |
:module "zlib") |
|---|
| 27 |
(setf *zlib-loaded* t *compress-streams* t)) |
|---|
| 28 |
(progn |
|---|
| 29 |
(warn "Unable to load zlib. Disabling compression.") |
|---|
| 30 |
(setf *compress-streams* nil)))))) |
|---|
| 31 |
|
|---|
| 32 |
#+use-uffi-zlib |
|---|
| 33 |
(defun compress-string (source) |
|---|
| 34 |
"Returns two values: array of bytes containing the compressed data |
|---|
| 35 |
and the numbe of compressed bytes" |
|---|
| 36 |
(let* ((sourcelen (length source)) |
|---|
| 37 |
(destsize (+ 12 (ceiling (* sourcelen 1.01)))) |
|---|
| 38 |
(dest (uffi:allocate-foreign-string destsize :unsigned t)) |
|---|
| 39 |
(destlen (uffi:allocate-foreign-object :long))) |
|---|
| 40 |
(setf (uffi:deref-pointer destlen :long) destsize) |
|---|
| 41 |
(uffi:with-cstring (source-native source) |
|---|
| 42 |
(let ((result (c-compress dest destlen source-native sourcelen)) |
|---|
| 43 |
(newdestlen (uffi:deref-pointer destlen :long))) |
|---|
| 44 |
(unwind-protect |
|---|
| 45 |
(if (zerop result) |
|---|
| 46 |
(values (uffi:convert-from-foreign-string |
|---|
| 47 |
dest |
|---|
| 48 |
; :external-format '(:latin-1 :eol-style :lf) |
|---|
| 49 |
:length newdestlen |
|---|
| 50 |
:null-terminated-p nil) |
|---|
| 51 |
newdestlen) |
|---|
| 52 |
(error "zlib error, code ~D" result)) |
|---|
| 53 |
(progn |
|---|
| 54 |
(uffi:free-foreign-object destlen) |
|---|
| 55 |
(uffi:free-foreign-object dest))))))) |
|---|
| 56 |
|
|---|
| 57 |
;;; ABCL zlib |
|---|
| 58 |
|
|---|
| 59 |
#+use-abcl-zlib |
|---|
| 60 |
(defun load-zlib (&optional force) |
|---|
| 61 |
(declare (ignore force)) |
|---|
| 62 |
(setf *compress-streams* t)) |
|---|
| 63 |
|
|---|
| 64 |
#+use-abcl-zlib |
|---|
| 65 |
(defun compress-string (string) |
|---|
| 66 |
(let* ((string-bytes |
|---|
| 67 |
(java:jcall |
|---|
| 68 |
(java:jmethod "java.lang.String" "getBytes" "java.lang.String") string "UTF-8")) |
|---|
| 69 |
(out-array (java:jnew (java:jconstructor "java.io.ByteArrayOutputStream"))) |
|---|
| 70 |
(compresser (java:jnew (java:jconstructor "java.util.zip.Deflater" "int") |
|---|
| 71 |
(java:jfield "java.util.zip.Deflater" "BEST_COMPRESSION"))) |
|---|
| 72 |
(defl-out-stream |
|---|
| 73 |
(java:jnew |
|---|
| 74 |
(java:jconstructor |
|---|
| 75 |
"java.util.zip.DeflaterOutputStream" "java.io.OutputStream" "java.util.zip.Deflater") |
|---|
| 76 |
out-array compresser))) |
|---|
| 77 |
(java:jcall (java:jmethod "java.util.zip.Deflater" "setInput" "[B") compresser string-bytes) |
|---|
| 78 |
(java:jcall (java:jmethod "java.util.zip.DeflaterOutputStream" "close") defl-out-stream) |
|---|
| 79 |
(java:jcall (java:jmethod "java.io.ByteArrayOutputStream" "toString") out-array))) |
|---|
| 80 |
|
|---|
| 81 |
;;; salza zlib |
|---|
| 82 |
|
|---|
| 83 |
#+use-salza-zlib |
|---|
| 84 |
(defun load-zlib (&optional force) |
|---|
| 85 |
(declare (ignore force)) |
|---|
| 86 |
(setf *compress-streams* t)) |
|---|
| 87 |
|
|---|
| 88 |
#+use-salza-zlib |
|---|
| 89 |
(defun compress-string (string) |
|---|
| 90 |
(let* ((input (if (stringp string) |
|---|
| 91 |
(babel::string-to-octets string :encoding :iso-8859-1) |
|---|
| 92 |
string)) |
|---|
| 93 |
(buffer-size (min 8192 (* 2 (length string)))) |
|---|
| 94 |
(zlib-buffer (make-array buffer-size :element-type 'salza::octet)) |
|---|
| 95 |
(chunks ())) |
|---|
| 96 |
(flet ((zlib-callback (zlib-stream) |
|---|
| 97 |
(push (subseq (salza::zlib-stream-buffer zlib-stream) |
|---|
| 98 |
0 (salza::zlib-stream-position zlib-stream)) chunks) |
|---|
| 99 |
(setf (salza::zlib-stream-position zlib-stream) 0))) |
|---|
| 100 |
(let ((zlib-stream (salza::make-zlib-stream zlib-buffer :callback #'zlib-callback))) |
|---|
| 101 |
(salza::zlib-write-sequence input zlib-stream) |
|---|
| 102 |
(salza::finish-zlib-stream zlib-stream) |
|---|
| 103 |
(nreverse chunks))))) |
|---|
| 104 |
|
|---|
| 105 |
;;; no-zlib |
|---|
| 106 |
#+use-no-zlib |
|---|
| 107 |
(defun load-zlib (&optional force) |
|---|
| 108 |
(declare (ignore force)) |
|---|
| 109 |
(setf *compress-streams* nil)) |
|---|
| 110 |
|
|---|
| 111 |
#+use-no-zlib |
|---|
| 112 |
(defun compress-string (string) |
|---|
| 113 |
string) |
|---|
| 114 |
|
|---|
| 115 |
;;; load it! |
|---|
| 116 |
|
|---|
| 117 |
(load-zlib) |
|---|
| 118 |
|
|---|