[cl-pdf-devel] lww 4.3.7. version of cl-pdf can't handle big pdf file
Chisheng Huang
cph at chi-square-works.com
Tue Nov 2 06:58:21 UTC 2004
Hi,
While generating a PDF scatterplot of ~20000 circles, my LWW 4.3.7 went
belly up:
Error: An error of type CONDITIONS::SIGNAL-HANDLER-ERROR occured, arguments : (:
SIGNAL-CONDITION #<SIMPLE-ERROR 2A6F52FC> :REAL-CONDITION #<SIMPLE-ERROR 2A6F52D
C>)
1 (continue) Return from callback function
2 Re-invoke callback function
3 Return from callback function
4 Re-invoke callback function
5 (abort) Quit process.
Type :b for backtrace, :c <option number> to proceed, or :? for other options
CL-USER 1 : 1 > :b
Call to DBG::GET-CALL-FRAME
Call to DBG::DEBUG1
Call to INVOKE-DEBUGGER
Call to FLI:REPLACE-FOREIGN-OBJECT
Call to FLI::LISP-TO-C-STRING1
Call to PDF::COMPRESS-STRING
Call to (METHOD PDF::WRITE-OBJECT (PDF::PDF-STREAM))
I'm using cl-pdf-2.1 and the PDF::COMPRESS-STRING defined in
contrib/zlib-lw.lisp. According to the backtrace, it looks like I hit an
internal upper limit in LWW 4.3.7. To get around the problem, I hacked
WRITE-OBJECT in pdf.lisp a bit:
(defmethod write-object ((obj pdf-stream) &optional root-level)
(declare (ignorable root-level))
(when (and *compress-streams* (not (no-compression obj))
(> (length (content obj)) *min-size-for-compression*))
;; Or put the HANDLER-CASE in COMPRESS-STRING ? - cph 01-Nov-2004
(let ((compressed (handler-case
(compress-string (content obj))
(error ()
nil))))
(when compressed
(setf (content obj) compressed)
(let ((filter (get-dict-value obj "/Filter")))
(if filter
(change-dict-value obj "/Filter" (vector "/FlateDecode" filter))
(add-dict-value obj "/Filter" "/FlateDecode"))))))
;; replaced by the above (WHEN ...). - cph 01-Nov-2004
#+ignore
(when (and *compress-streams* (not (no-compression obj))
(> (length (content obj)) *min-size-for-compression*))
(setf (content obj) (compress-string (content obj)))
(let ((filter (get-dict-value obj "/Filter")))
(if filter
(change-dict-value obj "/Filter" (vector "/FlateDecode" filter))
(add-dict-value obj "/Filter" "/FlateDecode"))))
(call-next-method)
(write-line "stream" *pdf-stream*)
#+pdf-binary
(write-sequence (content obj) *pdf-stream*)
#-pdf-binary
(if (stringp (content obj))
(write-sequence (content obj) *pdf-stream*)
(loop for c across (content obj) do
(write-char (code-char c) *pdf-stream*)))
(write-char #\Newline *pdf-stream*)
(write-line "endstream" *pdf-stream*))
Maybe this hack will be useful to someones.
Best,
-cph
ps. after a bit of testing, i think the longest string that lww 4.3.7 can
handle is between 2000000 and 2100000. generating a scatterplot of
~20000 circles in pdf produces a string of length 4433794, which
can be happily handled by the cmucl version of cl-pdf without having
to resort to the above hack.
More information about the cl-pdf-devel
mailing list