[cl-gd-devel] Loading Images from Pointers

Hans Hübner hans.huebner at gmail.com
Wed May 19 10:43:14 UTC 2010


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
<christoph.senjak at googlemail.com> wrote:
> 2010/5/19 Hans Hübner <hans.huebner at gmail.com>:
>> 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




More information about the Cl-gd-devel mailing list