From christoph.senjak at googlemail.com Wed May 19 02:37:31 2010 From: christoph.senjak at googlemail.com (Christoph Senjak) Date: Wed, 19 May 2010 04:37:31 +0200 Subject: [cl-gd-devel] Loading Images from Pointers Message-ID: Hello. I have so far been using Lisp-Magick for two reasons: On the one hand, I didnt know that GD can stretch images, on the other hand, cl-gd doesnt support reading images from memory. Well, at least according to [1] there is a function which can do this in libgd, but seems like this isnt implemented in cl-gd yet. This is in fact the only thing keeping me from using CL-GD by now. I would like to use it instead of lisp-magick, since lisp-magick seems not to be well-maintained by now, and I already have to use a few of my personal patches to it. Anyway, I am not very familiar with uffi and stuff, I just tried to use cl-gd::def-function, but didnt really suffice. Is there any way of getting this function work with CL-GD? Regards Christoph Senjak [1] http://libgd.org/ImageCreation#gdImageCreateFromPngPtr.28int_size.2C_void_.2Adata.29_.28FUNCTION.29 From hans.huebner at gmail.com Wed May 19 06:46:42 2010 From: hans.huebner at gmail.com (=?ISO-8859-1?Q?Hans_H=FCbner?=) Date: Wed, 19 May 2010 08:46:42 +0200 Subject: [cl-gd-devel] Loading Images from Pointers In-Reply-To: References: Message-ID: Hi Christoph, implementing an interface to gdImageCreateFrom.*Ptr shouldn't be hard, but I wonder where you'd get your pointers from? If you could supply some sample code and data, we may be able to help you out. -Hans On Wed, May 19, 2010 at 04:37, Christoph Senjak wrote: > Hello. > > I have so far been using Lisp-Magick for two reasons: On the one hand, > I didnt know that GD can stretch images, on the other hand, cl-gd > doesnt support reading images from memory. Well, at least according to > [1] there is a function which can do this in libgd, but seems like > this isnt implemented in cl-gd yet. This is in fact the only thing > keeping me from using CL-GD by now. I would like to use it instead of > lisp-magick, since lisp-magick seems not to be well-maintained by now, > and I already have to use a few of my personal patches to it. Anyway, > I am not very familiar with uffi and stuff, I just tried to use > cl-gd::def-function, but didnt really suffice. > > Is there any way of getting this function work with CL-GD? > > Regards > Christoph Senjak > > [1] http://libgd.org/ImageCreation#gdImageCreateFromPngPtr.28int_size.2C_void_.2Adata.29_.28FUNCTION.29 > > _______________________________________________ > cl-gd-devel site list > cl-gd-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/cl-gd-devel > From christoph.senjak at googlemail.com Wed May 19 10:28:01 2010 From: christoph.senjak at googlemail.com (Christoph Senjak) Date: Wed, 19 May 2010 12:28:01 +0200 Subject: [cl-gd-devel] Loading Images from Pointers In-Reply-To: References: Message-ID: 2010/5/19 Hans H?bner : > Hi Christoph, > > implementing an interface to gdImageCreateFrom.*Ptr shouldn't be hard, > but I wonder where you'd get your pointers from? ?If you could supply > some sample code and data, we may be able to help you out. > > -Hans Hello. I am loading the files into an array of (unsigned-byte 8): (defun si (var val) (setf (symbol-value (intern var)) val)) (defun init-file (file) "Load a file into a Variable. Access with |filename| (without .png and path)." (si (pathname-name file) (with-open-file (in file :element-type '(unsigned-byte 8)) (let* ((length (file-length in)) (content (make-array (list length) :element-type '(unsigned-byte 8) :adjustable nil))) (read-sequence content in) content)))) The reason I am doing this is that I dont like to have more external files than necessary, and want them in my core-dump. SDL can load these byte-arrays with (sdl-image:load-image x :image-type :PNG :alpha 1) what it actually does is (defmethod load-image ((source VECTOR) &key color-key alpha (image-type nil) (force nil) (free-rwops $ "Creates and returns a new surface from the image contained in the byte VECTOR in `SOURCE`." (declare (ignore free-rwops)) (load-image (sdl::create-RWops-from-byte-array source) :color-key color-key :color-key-at color-key-at :alpha alpha :image-type image-type :force force :free-rwops t)) where (defun create-RWops-from-byte-array (array) "Creates and returns a new `RWOPS` object from the Lisp array `ARRAY`." (let ((mem-array (cffi:foreign-alloc :unsigned-char :initial-contents array))) (make-instance 'rwops :fp (sdl-cffi::sdl-rw-from-mem mem-array (length array))))) which should be about the same lisp-magick does. Christoph From hans.huebner at gmail.com Wed May 19 10:43:14 2010 From: hans.huebner at gmail.com (=?ISO-8859-1?Q?Hans_H=FCbner?=) Date: Wed, 19 May 2010 12:43:14 +0200 Subject: [cl-gd-devel] Loading Images from Pointers In-Reply-To: References: Message-ID: Hi Christoph, I now understand what you're trying to do. Here is my take on it: - Accessing a byte vector as C vector is compiler specific. A portable solution would allocate some memory using UFFI's interface to malloc, copy the data to that memory buffer using a lisp loop and memory accessor functions, call the required gdCreate* function and finally free the malloced buffer. - When you want to avoid the copying overhead (which in my opinion should only be done if you're dealing with a lot of data), you'll need to find out how you can pin the byte vector so that the garbage collector does not move it while you're in the FFI. Then, you'll need to find out how you can get a pointer to the byte vector in a format that is understood by UFFI. I would first go for the first option and see how that performs (i.e. if it produces a noticeable performance problem). The copies that you'll make are only temporary, so the memory footprint of your application will be roughly identical. GD will make its own private copy of the data anyway. Let us know if that helps. -Hans On Wed, May 19, 2010 at 12:28, Christoph Senjak wrote: > 2010/5/19 Hans H?bner : >> Hi Christoph, >> >> implementing an interface to gdImageCreateFrom.*Ptr shouldn't be hard, >> but I wonder where you'd get your pointers from? ?If you could supply >> some sample code and data, we may be able to help you out. >> >> -Hans > > Hello. > > I am loading the files into an array of (unsigned-byte 8): > > (defun si (var val) > ?(setf (symbol-value (intern var)) val)) > (defun init-file (file) > ?"Load a file into a Variable. Access with |filename| (without .png > and path)." > ?(si (pathname-name file) > ? ? ?(with-open-file (in file :element-type '(unsigned-byte 8)) > ? ? ? ?(let* ((length (file-length in)) > ? ? ? ? ? ? ? (content (make-array (list length) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?:element-type '(unsigned-byte 8) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?:adjustable nil))) > ? ? ? ? ?(read-sequence content in) > ? ? ? ? ?content)))) > > The reason I am doing this is that I dont like to have more external > files than necessary, and want them in my core-dump. SDL can load > these byte-arrays with > > (sdl-image:load-image x :image-type :PNG :alpha 1) > > what it actually does is > > (defmethod load-image ((source VECTOR) &key color-key alpha > (image-type nil) (force nil) (free-rwops $ > ?"Creates and returns a new surface from the image contained in the > byte VECTOR in `SOURCE`." > ?(declare (ignore free-rwops)) > ?(load-image (sdl::create-RWops-from-byte-array source) > ? ? ? ? ? ? ?:color-key color-key > ? ? ? ? ? ? ?:color-key-at color-key-at > ? ? ? ? ? ? ?:alpha alpha > ? ? ? ? ? ? ?:image-type image-type > ? ? ? ? ? ? ?:force force :free-rwops t)) > where > (defun create-RWops-from-byte-array (array) > ?"Creates and returns a new `RWOPS` object from the Lisp array `ARRAY`." > ?(let ((mem-array (cffi:foreign-alloc :unsigned-char :initial-contents array))) > ? ?(make-instance 'rwops :fp (sdl-cffi::sdl-rw-from-mem mem-array > (length array))))) > > which should be about the same lisp-magick does. > > Christoph > > _______________________________________________ > cl-gd-devel site list > cl-gd-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/cl-gd-devel From christoph.senjak at googlemail.com Wed May 19 14:18:26 2010 From: christoph.senjak at googlemail.com (Christoph Senjak) Date: Wed, 19 May 2010 16:18:26 +0200 Subject: [cl-gd-devel] Loading Images from Pointers In-Reply-To: References: Message-ID: > I now understand what you're trying to do. ?Here is my take on it: > > - Accessing a byte vector as C vector is compiler specific. ?A > portable solution would allocate some memory using UFFI's interface to > malloc, copy the data to that memory buffer using a lisp loop and > memory accessor functions, call the required gdCreate* function and > finally free the malloced buffer. cffi:foreign-alloc seems to have an argument :initial-contents, according to what lispbuilder-sdl does. So there should be no need to perform this loop by hand. The main problem I have now is that I get strange error messages about "unknown alien functions" when trying to use def-function (which I found in gd-uffi.lisp). The function is definitely there, but seems like uffi cannot find it or something (I am not familiar with uffi). From hans.huebner at gmail.com Wed May 19 14:26:10 2010 From: hans.huebner at gmail.com (=?ISO-8859-1?Q?Hans_H=FCbner?=) Date: Wed, 19 May 2010 16:26:10 +0200 Subject: [cl-gd-devel] Loading Images from Pointers In-Reply-To: References: Message-ID: Christoph, can you please post some code that would allow me to try to reproduce and diagnose the problem in isolation? Make it a single lisp file that assumes cl-gd being loaded, attach it to the message that you send. Thanks. Hans On Wed, May 19, 2010 at 16:18, Christoph Senjak wrote: >> I now understand what you're trying to do. ?Here is my take on it: >> >> - Accessing a byte vector as C vector is compiler specific. ?A >> portable solution would allocate some memory using UFFI's interface to >> malloc, copy the data to that memory buffer using a lisp loop and >> memory accessor functions, call the required gdCreate* function and >> finally free the malloced buffer. > > cffi:foreign-alloc seems to have an argument :initial-contents, > according to what lispbuilder-sdl does. So there should be no need to > perform this loop by hand. > > The main problem I have now is that I get strange error messages about > "unknown alien functions" when trying to use def-function (which I > found in gd-uffi.lisp). The function is definitely there, but seems > like uffi cannot find it or something (I am not familiar with uffi). > > _______________________________________________ > cl-gd-devel site list > cl-gd-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/cl-gd-devel From edi at agharta.de Wed May 19 14:25:28 2010 From: edi at agharta.de (Edi Weitz) Date: Wed, 19 May 2010 16:25:28 +0200 Subject: [cl-gd-devel] Loading Images from Pointers In-Reply-To: References: Message-ID: On Wed, May 19, 2010 at 4:18 PM, Christoph Senjak wrote: > The main problem I have now is that I get strange error messages about > "unknown alien functions" when trying to use def-function (which I > found in gd-uffi.lisp). The function is definitely there, but seems > like uffi cannot find it or something (I am not familiar with uffi). Have you made sure that the version of GD you are using is compatible with the GD docs you pointed to? I haven't looked at GD for quite some time, but judging from the URL in your initial email, current GD seems to use names which are different from the ones used in CL-GD, so if CL-GD works for you otherwise, you probably don't have the newest version of GD. Edi. From christoph.senjak at googlemail.com Wed May 19 21:51:56 2010 From: christoph.senjak at googlemail.com (Christoph Senjak) Date: Wed, 19 May 2010 23:51:56 +0200 Subject: [cl-gd-devel] Loading Images from Pointers In-Reply-To: References: Message-ID: Hello. > Have you made sure that the version of GD you are using is compatible > with the GD docs you pointed to? ?I haven't looked at GD for quite > some time, but judging from the URL in your initial email, current GD > seems to use names which are different from the ones used in CL-GD, so > if CL-GD works for you otherwise, you probably don't have the newest > version of GD. CL-GD works (so far), but the page seems not to be up to date, I have the package libgd-xpm-dev from ubuntu, and /usr/include/gd.h contains the line #define GD_VERSION_STRING "2.0.36" which is, according to that site, a prerelease, which I cannot really believe since its in a stable ubuntu release. And it also contains the line BGD_DECLARE(gdImagePtr) gdImageCreateFromGifPtr (int size, void *data); But you are right ... cl-gd is not compatible (I should have done the tests on the same computer I did the other stuff): CL-USER> (cl-gd-test:TEST ) Test 1 failed with the following error: Attempt to call an undefined alien function. Test 2 failed with the following error: Attempt to call an undefined alien function. Test 3 failed with the following error: Attempt to call an undefined alien function. (...) So ... well ... how hard would it be to make it compatible with the new version? Is it just changing a few naming-strings, or more complicated? I have lisp-magick working now, its just not very well maintained, but if cl-gd is outdated, then maybe I will write my own FFI-Binding for GD directly, or keep working with a patched version of lisp-magick (or do the image-processing in CL directly). Regards, Christoph