Date: Wed, 19 May 2004 07:26:57 +0200
Reply-to: edi(a)agharta.de
User-Agent: Gnus/5.1002 (Gnus v5.10.2) Emacs/21.3.50 (gnu/linux)
Hi!
A new release is available from
<http://weitz.de/files/cl-gd.tgz>.
Here's the relevant part from the changelog:
Version 0.4.1
2004-05-21
Fix for memory leak (see WITH-SAFE-ALLOC) by Manuel Odendahl
Documented COLOR-COMPONENT which was missing in index.html (thanks to Manuel Odendahl)
Two new functions, COLOR-COMPONENTS and FIND-COLOR-FROM-IMAGE (both by Manuel Odendahl)
Replaced WRITE-BYTE with WRITE-SEQUENCE for LispWorks - see <http://article.gmane.org/gmane.lisp.lispworks.general/1827>
Have fun,
Edi.
Hi!
We are using cl-gd in our bknr web framework, and use cl-gd to scale,
transform and otherwise manipulate images. We had the problem that
sometimes cl-gd would quit on us saying it could not allocate additional
memory, which suggested a memory leak somewhere. After some code
browsing and testing, I found several race conditions in cl-gd, having
to do with the use of UNWIND-PROTECT, which looked like this:
(let* ((c-style (allocate-foreign-object :int length)))
(unwind-protect (yadayada)
(free-foreign-object c-style)))
However, if somehow the stack is unwound just after the call to
ALLOCATE-FOREIGN-OBJECT, C-STYLE will never get freed. I guess the
UNWIND-PROTECT code was taken from uffi (specifically from
with-foreign-object), which has the same problem (but this is another
story). Anyway, while uffi gets fixed to rewrite the above nicely, I
have added the WITH-SAFE-ALLOC to util.lisp:
(defmacro with-safe-alloc ((var alloc free) &rest body)
`(let (,var)
(unwind-protect
(progn (setf ,var ,alloc)
,@body)
(when ,var ,free))))
and sprinkled the code with it (I replaced all occurences of
UNWIND-PROTECT dealing with memory allocation, and quickly browsed the
code for other allocation code, but couldn't find any).
This seems to fix our problems. On another front, I have added the
function COLOR-COMPONENTS, which returns a list of the color copmonents
of a color (we needed this somewhere), and the function
FIND-COLOR-FROM-IMAGE, which tries to FIND-COLOR a color from a source
image inside a new image (to copy colors between images).
(defun color-components (color &key (image *default-image*))
"Returns the color components of COLOR as a list. The components are in the
order red, green, blue, alpha."
(mapcar #'(lambda (c) (color-component c color :image image))
'(:red :green :blue :alpha)))
(defun find-color-from-image (color source-image &key alpha exact hwb
resolve (image *default-image*))
"Returns the color in IMAGE corresponding to COLOR in SOURCE-IMAGE. The
keyword parameters are passed to FIND-COLOR."
(let ((red (color-component :red color :image source-image))
(blue (color-component :blue color :image source-image))
(green (color-component :green color :image source-image))
(alpha (when alpha (color-component :alpha color :image source-image))))
(find-color red green blue :alpha alpha :exact exact :hwb hwb
:resolve resolve :image image)))
I have made a patch file which I'll attach to the mail, and the patched
cl-gd directory can be downloaded from
http://bl0rg.net/~manuel/cl-gd-patched.tar.gz. I have changed index.html
with documentation for the new functions and a documentation for
COLOR-COMPONENT, which was referenced but not included. I have also
added the Makefile we have to produce the .so file (FreeBSD, haven't
checked it on another platform).
Hope this helps :}
Regards, Manuel Odendahl