Leo Zovic | 23 Oct 18:23
Picon
Gravatar

FFI error (I assume)

Not sure whether this is a bug, or I don't have a required library set up. Whenever I try to do 


(with-image-from file (img "/my/image/path.jpg")
    (image-size img))

I get an UNDEFINED-ALIEN-FUNCTION-ERROR

trace follows

Attempt to call an undefined alien function.
   [Condition of type SB-KERNEL::UNDEFINED-ALIEN-FUNCTION-ERROR]

Restarts:
 0: [RETRY] Retry SLIME REPL evaluation request.
 1: [*ABORT] Return to SLIME's top level.
 2: [TERMINATE-THREAD] Terminate this thread (#<THREAD "repl-thread" RUNNING {10032E9BA1}>)

Backtrace:
  0: (SB-KERNEL::UNDEFINED-ALIEN-FUNCTION-ERROR)
  1: ("foreign function: #x422520")
  2: (GD-IMAGE-CREATE-FROM-JPEG-FILE "/my/image.path.jpg" #<SB-ALIEN-INTERNALS:ALIEN-VALUE :SAP #X7FFFF37AFFF0 :TYPE (* (SB-ALIEN:SIGNED 32))>)
  3: (CREATE-IMAGE-FROM-FILE #<unavailable argument> NIL)
  4: ((LAMBDA ()))
  5: (SB-INT:SIMPLE-EVAL-IN-LEXENV ..)
  6: (SWANK::EVAL-REGION "(with-image-from-file (img \"/my/image.path.jpg\")\n   (image-size img))\n")
  7: ((LAMBDA ()))
  8: (SWANK::TRACK-PACKAGE #<CLOSURE (LAMBDA #) {1004B732C9}>)
  9: (SWANK::CALL-WITH-RETRY-RESTART "Retry SLIME REPL evaluation request." #<CLOSURE (LAMBDA #) {1004B731E9}>)
 10: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CLOSURE (LAMBDA #) {1004B731B9}>)
 11: (SWANK::REPL-EVAL "(with-image-from-file (img \"/my/image.path.jpg\")\n   (image-size img))\n")
 12: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK:LISTENER-EVAL "(with-image-from-file (img \"/my/image.path.jpg\")\n   (image-size img))\n") #<NULL-LEXENV>)
 13: (SWANK::EVAL-FOR-EMACS (SWANK:LISTENER-EVAL "(with-image-from-file (img \"/my/image.path.jpg\")\n   (image-size img))\n") "CL-GD" 172)
 14: (SWANK::PROCESS-REQUESTS NIL)
 15: ((LAMBDA ()))
 16: ((LAMBDA ()))
 17: (SWANK-BACKEND::CALL-WITH-BREAK-HOOK #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA #) {10032F3139}>)
 18: ((FLET SWANK-BACKEND:CALL-WITH-DEBUGGER-HOOK) #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA #) {10032F3139}>)
 19: (SWANK::CALL-WITH-BINDINGS ((*STANDARD-OUTPUT* . #) (*STANDARD-INPUT* . #) (*TRACE-OUTPUT* . #) (*ERROR-OUTPUT* . #) (*DEBUG-IO* . #) (*QUERY-IO* . #) ...) #<CLOSURE (LAMBDA #) {10032F3159}>)
 20: (SWANK::HANDLE-REQUESTS #<SWANK::CONNECTION {1002E87B91}> NIL)
 21: (SWANK::CALL-WITH-BINDINGS NIL #<CLOSURE (LAMBDA #) {10032F30F9}>)
 22: ((FLET #:WITHOUT-INTERRUPTS-BODY-[BLOCK369]374))
 23: ((FLET SB-THREAD::WITH-MUTEX-THUNK))
 24: ((FLET #:WITHOUT-INTERRUPTS-BODY-[CALL-WITH-MUTEX]300))
 25: (SB-THREAD::CALL-WITH-MUTEX ..)
 26: (SB-THREAD::INITIAL-THREAD-FUNCTION)
 27: ("foreign function: #x422520")
 28: ("foreign function: #x419227")

I've tried it running SBCL 1.0.40 from the Debian repos, as well as 1.0.52 from the official SBCL site. I'm using the copy of cl-gb from the latest quicklisp release, and I've tried it on both a 32 bit and 64 bit system (the included stack trace is from the 64-bit SBCL 1.0.40). 

Any ideas?
Jeffrey Cunningham | 8 Sep 18:05
Gravatar

CL-GD on 64-bit Lisp problem

Hi,

I've been using CL-GD on 32-bit systems for years without difficulties.  
Now I'm trying to set a Lisp environment up on a fresh 64-bit Debian  
machine and I can't get CL-GD to work. When I try to load it I get this  
error:

Error opening shared object  
"/home/jcunningham/src/lisp/cl-gd-0.5.7/cl-gd-glue.so":
/home/jcunningham/src/lisp/cl-gd-0.5.7/cl-gd-glue.so: wrong ELF class:  
ELFCLASS64..

I remember their being an issue with CL-GD on 64-bit machines a couple  
years ago that involved having to use CFFI-UFFI-COMPAT instead of CFFI. I  
also vaguely remember that there was a problem at the time trying to have  
both CFFI and UFFI working, as the former used the same asd file name as  
the latter or something like that. Quite a number of other libraries I use  
depend on CFFI so I don't want to do anything that would break it. But I  
also need to get CL-GD working again if this machine is to be useful.

My gd lib is 64-bit - actually, everything I can think of is 64-bit. Is  
this still an issue? Is anyone using CL-GD on a 64-bit machine?

If so, mind sharing what it takes to get it working?

Much obliged.

--Jeff Cunningham

--
--
Edi Weitz | 31 Aug 17:11
Picon
Favicon

My open source libraries (aka "ediware")

[My apologies if you receive multiple copies of this email.]

Hi everybody!

As some of you will know, I'll start on a new job tomorrow.  This new
job won't involve much hacking, if at all, and thus it doesn't look
like I'll have a lot of time to maintain my open source libraries in
the near future.  I have no plans to suddenly disappear from the CL
world, but don't expect new releases of any of my libs any time soon.
(At least none published by me or on my server.)

Luckily, Hans Hübner - who already did most of the maintenance and
development work for Hunchentoot in the last two years or so - offered
to coordinate further development via github.  See his full
announcement at
<http://netzhansa.blogspot.com/2011/08/ediware-moving-to-github.html>.

I'll continue to read the mailing lists for my libs and I'm still
interested in fixing bugs you might find in the release tarballs
available on my web server.  However, I will likely not bother to
discuss or work on new features or compatibility code for
implementations other than LispWorks (which happens to be the one I'm
using).

Lastly, I hope to see a lot of you in Amsterdam
<http://weitz.de/eclm2011/> in October.  The number of registrations
so far has been pretty disappointing, but you still have three weeks
left to change your mind... :)

Take care,
Edi.

Chris Perkins | 17 Sep 22:51

CL-GD and LispWorks 5.1: Loading images with extended characters in their pathnames?

Hello,

If I have a pathnamewith extended characters in its namestring (like
curly quotes, etc), how do I get that image to load with CL-GD?

Maybe I have to go diving into UFFI or the sources for GD itself, but I
thought I'd ask here first, since it seems like this has probably come
up already.

Thanks for any assistance,

Chris

Example:  f => #P"/Users/cperkins/Pictures/image file names
testing/Earth “fatter” copy.gif"

(cl-gd:create-image-from-file f)

Error: External format (:LATIN-1 :EOL-STYLE :LF) got error writing
#<Pointer to type (:UNSIGNED :CHAR) = #x0102B008> at position 55: No
encoding exists for character “.
  1 (abort) Return to level 0.
  2 Return to top loop level 0.

Christoph Senjak | 19 May 04:37

Loading Images from Pointers

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

colimal | 11 Mar 18:29

[question] change of colors when tiling an image

Hello all :)

I'm using cl-gd to generate tiles of a larger image. I'm generating a set of
tiles of each, e.g. 256x256 pixels, from an input image that is much larger,
e.g. 4096x2048.

When using "debug-images" (pngs) with few colors and large areas of the same
color this works well. However, when I want to tile a png file with higher
frequencies and lots of colors the resulting tile images seem to be resampled
somehow, with a huge loss of quality.

Here is part of my code:

  (with-image-from-file (src input-name)
   (let ((width (image-width src))
         (height (image-height src)))

        ;; store a single tile
        (defun generate-tile (x y)
          "Generates a single tile. The index of which is given in x and y"
          (with-image (dest size size)
            (copy-image src dest (* x size) (* y size) 0 0 size size)
            (write-image-to-file (concatenate 'string output-base "-" (write-to-string x) "-" (write-to-string
y) "." ext)
                                 :image dest :if-exists :supersede :compression-level 0)))

        ;; master's actual code
        (let ((count-x (ceiling (/ width size)))
              (count-y (ceiling (/ height size))))
             (format t "Slicing up ~s (~d x ~d) into (~d x ~d) tiles of size (~d x ~d).~%" input-name width height count-x
count-y size size)
             (dotimes (x count-x)
                      (dotimes (y count-y)
                               (generate-tile x y))))))

As you can see, I don't compress the image (doesn't change, if I leave the
compression key out), and only copy a given section to the output image.
The version of cl-gd I'm using is 0.5.7, the version of is libgd 2.0.0.

I would appreciate if someone would hint me to what I'm missing :)

Thanks in advance,
   Kai.

Edi Weitz | 23 Nov 21:05
Picon
Favicon

[cl-gd-announce] New release 0.5.7 (Was: cl-gd patch)

2009/11/15 Jeff Cunningham <j.k.cunningham <at> comcast.net>:

> In any event, now that I've seen Hans' request, I slapped my forehead for
> not seeing the debug statements, removed them, and here's the remade patch.

I've now uploaded release 0.5.7 which contains your patch.

Thanks,
Edi.

Edi Weitz | 15 Nov 12:53
Picon
Favicon

Re: cl-gd patch

Hi,

That nobody seems to have looked at it is probably a bit exaggerated
as at least Hans and I looked at it, and Hans also asked for a
revision (and I agree with this request) to which you haven't replied
yet.

FWIW, here are the patch guidelines again:

  http://weitz.de/patches.html

Thanks,
Edi.

On Sun, Nov 15, 2009 at 4:40 AM, Jeff Cunningham
<j.k.cunningham <at> comcast.net> wrote:
> Dear Dr Weitz;
>
> I posted a patch to the cl-gd project through the  mailing list about a week
> ago which no one seems to have looked at. I believe it solves a minor
> irritation with SBCL users (warnings go away), is backwards compatible and
> disturbs nothing else. I was hoping you would adopt it. I know you are very
> busy and probably since this list is so inactive seldom look at it anymore.
> But I use this library all the time and am planning to release a scientific
> plotting library built on top of it very shortly, so I'd like to have all
> the interfaces working as cleanly as possible.
>
> Best regards,
> Jeff Cunningham
>
>

Jeff Cunningham | 9 Nov 04:58
Picon

proposed patch for WITH-TRANSFORMATION macro

Hi,

I use cl-gd extensively and decided to figure out how to eliminate the 
incessant SBCL generated warnings that trace back to the 
WITH-TRANSFORMATION macro. It looks like work has already been done 
there. I came up with a pretty clean solution which removes the existing 
argument checking, provides it through a different mechanism and 
satisfies SBCL and backwards compatibility. I don't have any other 
platforms to test with but I think it will run on anything. I've 
attached the patch.

Regards,
Jeff Cunningham

--- cl-gd-0.5.6/transform.lisp	2007-07-29 09:37:13.000000000 -0700
+++ source/cl-gd-0.5.6/transform.lisp	2009-11-08 19:31:08.000000000 -0800
@@ -72,7 +72,10 @@
   "Like ROUND but make sure result isn't longer than 32 bits."
   (mod (round x) +most-positive-unsigned-byte-32+))

-(defmacro with-transformation ((&key x1 x2 width y1 y2 height reverse-x reverse-y (radians t) (image
'*default-image*)) &body body)
+(defmacro with-transformation ((&key (x1 0 x1set) (x2 0 x2set) (width 0 wset)
+                                     (y1 0 y1set) (y2 0 y2set) (height 0 hset)
+                                     reverse-x reverse-y (radians t) (image '*default-image*))
+                               &body body)
   "Executes BODY such that all points and width/height data are
 subject to a simple affine transformation defined by the keyword
 parameters. The new x-axis of IMAGE will start at X1 and end at X2 and
@@ -85,93 +88,91 @@
 BODY will be assumed to be provided in radians, otherwise in degrees."
   (with-rebinding (x1 x2 width y1 y2 height reverse-x reverse-y radians image)
     (with-unique-names (image-width image-height
-                        stretch-x stretch-y
-                        w-transformer h-transformer
-                        x-transformer y-transformer
-                        w-inv-transformer h-inv-transformer
-                        x-inv-transformer y-inv-transformer
-                        angle-transformer)
+                                    stretch-x stretch-y
+                                    w-transformer h-transformer
+                                    x-transformer y-transformer
+                                    w-inv-transformer h-inv-transformer
+                                    x-inv-transformer y-inv-transformer
+                                    angle-transformer)
       ;; rebind for thread safety
       `(let ((*transformers* *transformers*))
-        (unless (<= 2 (count-if #'identity (list ,x1 ,x2 ,width)))
-          (error "You must provide at least two of X1, X2, and WIDTH."))
-        (unless (<= 2 (count-if #'identity (list ,y1 ,y2 ,height)))
-          (error "You must provide at least two of Y1, Y2, and HEIGHT."))
-        (when (and ,x1 ,x2 ,width
-                   (/= ,width (- ,x2 ,x1)))
-          (error "X1, X2, and WIDTH don't match. Try to provide just two of the three arguments."))
-        (when (and ,y1 ,y2 ,height
-                   (/= ,height (- ,y2 ,y1)))
-          (error "Y1, Y2, and HEIGHT don't match. Try to provide just two of the three arguments."))
-        ;; kludgy code to keep SBCL quiet
-        (unless ,x1 (setq ,x1 (- ,x2 ,width)))
-        (unless ,x2 (setq ,x2 (+ ,x1 ,width)))
-        (unless ,width (setq ,width (- ,x2 ,x1)))
-        (unless ,y1 (setq ,y1 (- ,y2 ,height)))
-        (unless ,y2 (setq ,y2 (+ ,y1 ,height)))
-        (unless ,height (setq ,height (- ,y2 ,y1)))
-        (multiple-value-bind (,image-width ,image-height)
-            (without-transformations
-             (image-size ,image))
-          (let* ((,stretch-x (/ ,image-width ,width))
-                 (,stretch-y (/ ,image-height ,height))
-                 (,w-transformer (lambda (w)
-                                  (round-to-signed-byte-32
-                                   (* w ,stretch-x))))
-                 (,w-inv-transformer (lambda (w)
-                                       (/ w ,stretch-x)))
-                 (,h-transformer (lambda (h)
-                                  (round-to-signed-byte-32
-                                   (* h ,stretch-y))))
-                 (,h-inv-transformer (lambda (h)
-                                       (/ h ,stretch-y)))
-                 (,x-transformer (if ,reverse-x
-                                  (lambda (x)
+         (macrolet ((checkargs (a1 a1set a2 a2set aspan aspanset c lbl)
+                      `(progn
+                         (cond ((and ,a1set ,a2set) (setq ,aspan (- ,a2 ,a1)))
+                               ((and ,a1set ,aspanset) (setq ,a2 (+ ,a1 ,aspan)))
+                               ((and ,a2set ,aspanset) (setq ,a1 (- ,a2 ,aspan)))
+                               (t (error "Require two of ~c1, ~:*~c2, or ~a to be set." ,c ,lbl)))
+                         (unless (> ,aspan 0)
+                           (format t "~&a1=~a a2=~a span=~a~%" ,a1 ,a2 ,aspan)
+                           (error "Require ~c1 < ~:*~c2" ,c))
+                         (unless (< (abs (/ (- ,a2 (+ ,a1 ,aspan)) ,aspan)) 1.e-5)
+                           (format t "~&a1=~a a2=~a span=~a~%" ,a1 ,a2 ,aspan)
+                           (format t "error=~a~%" (- ,aspan (- ,a2 ,a1)))
+                           (error "~c1, ~:*~c2, and ~a don't match. Try to provide just two of the three arguments." ,c ,lbl)))))
+           (checkargs ,x1 ,x1set ,x2 ,x2set ,width ,wset #\x "width")
+           (checkargs ,y1 ,y1set ,y2 ,y2set ,height ,hset #\y "height"))
+         (multiple-value-bind (,image-width ,image-height)
+             (without-transformations
+               (image-size ,image))
+           (let* ((,stretch-x (/ ,image-width ,width))
+                  (,stretch-y (/ ,image-height ,height))
+                  (,w-transformer (lambda (w)
                                     (round-to-signed-byte-32
-                                     (* (- ,x2 x) ,stretch-x)))
-                                  (lambda (x)
+                                     (* w ,stretch-x))))
+                  (,w-inv-transformer (lambda (w)
+                                        (/ w ,stretch-x)))
+                  (,h-transformer (lambda (h)
                                     (round-to-signed-byte-32
-                                     (* (- x ,x1) ,stretch-x)))))
-                 (,x-inv-transformer (if ,reverse-x
-                                       (lambda (x)
-                                         (- ,x2 (/ x ,stretch-x)))
-                                       (lambda (x)
-                                         (+ ,x1 (/ x ,stretch-x)))))
-                 (,y-transformer (if ,reverse-y
-                                  (lambda (y)
-                                    (round-to-signed-byte-32
-                                     (* (- y ,y1) ,stretch-y)))
-                                  (lambda (y)
-                                    (round-to-signed-byte-32
-                                     (* (- ,y2 y) ,stretch-y)))))
-                 (,y-inv-transformer (if ,reverse-y
-                                       (lambda (y)
-                                         (+ ,y1 (/ y ,stretch-y)))
-                                       (lambda (y)
-                                         (- ,y2 (/ y ,stretch-y)))))
-                 (,angle-transformer (cond (,radians
+                                     (* h ,stretch-y))))
+                  (,h-inv-transformer (lambda (h)
+                                        (/ h ,stretch-y)))
+                  (,x-transformer (if ,reverse-x
+                                      (lambda (x)
+                                        (round-to-signed-byte-32
+                                         (* (- ,x2 x) ,stretch-x)))
+                                      (lambda (x)
+                                        (round-to-signed-byte-32
+                                         (* (- x ,x1) ,stretch-x)))))
+                  (,x-inv-transformer (if ,reverse-x
+                                          (lambda (x)
+                                            (- ,x2 (/ x ,stretch-x)))
+                                          (lambda (x)
+                                            (+ ,x1 (/ x ,stretch-x)))))
+                  (,y-transformer (if ,reverse-y
+                                      (lambda (y)
+                                        (round-to-signed-byte-32
+                                         (* (- y ,y1) ,stretch-y)))
+                                      (lambda (y)
+                                        (round-to-signed-byte-32
+                                         (* (- ,y2 y) ,stretch-y)))))
+                  (,y-inv-transformer (if ,reverse-y
+                                          (lambda (y)
+                                            (+ ,y1 (/ y ,stretch-y)))
+                                          (lambda (y)
+                                            (- ,y2 (/ y ,stretch-y)))))
+                  (,angle-transformer (cond (,radians
                                              (lambda (angle)
                                                (round-to-signed-byte-32
                                                 (* angle
                                                    +radians-to-degree-factor+))))
-                                           (t
+                                            (t
                                              #'identity))))
-            (push (make-instance 'transformer
-                                 :image ,image
-                                 :w-transformer ,w-transformer
-                                 :h-transformer ,h-transformer
-                                 :x-transformer ,x-transformer
-                                 :y-transformer ,y-transformer
-                                 :w-inv-transformer ,w-inv-transformer
-                                 :h-inv-transformer ,h-inv-transformer
-                                 :x-inv-transformer ,x-inv-transformer
-                                 :y-inv-transformer ,y-inv-transformer
-                                 :angle-transformer ,angle-transformer)
-                  *transformers*)
-            (unwind-protect
-              (progn
-                ,@body)
-              (pop *transformers*))))))))
+             (push (make-instance 'transformer
+                                  :image ,image
+                                  :w-transformer ,w-transformer
+                                  :h-transformer ,h-transformer
+                                  :x-transformer ,x-transformer
+                                  :y-transformer ,y-transformer
+                                  :w-inv-transformer ,w-inv-transformer
+                                  :h-inv-transformer ,h-inv-transformer
+                                  :x-inv-transformer ,x-inv-transformer
+                                  :y-inv-transformer ,y-inv-transformer
+                                  :angle-transformer ,angle-transformer)
+                   *transformers*)
+             (unwind-protect
+                  (progn
+                    ,@body)
+               (pop *transformers*))))))))

 (defmacro with-transformed-alternative ((&rest transformations) &body body)
   "Internal macro used to make functions
Anon Alex | 21 May 16:46
Picon

performance issue with CL-GD on SBCL, UFFI vs. CFFI

Hello, I wanted to report a performance-related issue with CL-GD and
UFFI vs CFFI-UFFI-COMPAT

Here is a simple function for comparing two images:
As you can see, this loops over every pixel of both images, compares
the R,G,B components.

(defun compare-images (image1 image2)
  "Comapre two images -- uses API exported by CL-GD"
  (declare (optimize (debug 0) (speed 3)(safety 0)))
  ;(declare (optimize (debug 3) (speed 0)))
  (let ((err 0)
	(height (cl-gd:image-height image1))
	(width (cl-gd:image-width image1)))
    (declare (fixnum err height width))
    (format t "height1=~a, height2=~a" height width)
    (assert (and (= height (cl-gd:image-height image2))
		 (= width (cl-gd:image-width image2))))
    (loop for y fixnum from 0 below height do
	  (loop for x fixnum from 0 below width do
		(let ((img-color (cl-gd:get-pixel y x :image image2))
		      (target-color (cl-gd:get-pixel y x :image image1)))
		  (incf err (square (- (the fixnum(cl-gd:color-component :red
img-color :image image2))
				       (the fixnum(cl-gd:color-component :red target-color :image
image1)))))
		  (incf err (square (- (the fixnum (cl-gd:color-component :blue
img-color :image image2))
				       (the fixnum(cl-gd:color-component :blue target-color :image
image1)))))
		  (incf err (square (- (the fixnum(cl-gd:color-component :green
img-color :image image2))
				       (the fixnum(cl-gd:color-component :green target-color
:image image1))))))))
    err))

Here's another version, which uses non-exported functions to speed it
up a little bit (and for benchmarking, eliminate some of the the
API-level overhead)

(defun compare-images-raw (image1 image2)
  "Compare two images -- use internal functions to eliminate overhead
added by CL-GD API"
  (declare (optimize (debug 0) (speed 3)(safety 0)))
  ;(declare (optimize (debug 3) (speed 0)))
  (let ((err 0)
	(height (cl-gd:image-height image1))
	(width (cl-gd:image-width image1))
	(img1 (cl-gd::img image1))
	(img2 (cl-gd::img image2)))
    (declare (fixnum err height width))
    (format t "height1=~a, height2=~a" height width)
    (assert (and (= height (cl-gd:image-height image2))
		 (= width (cl-gd:image-width image2))))
    (loop for y fixnum from 0 below height do
	  (loop for x fixnum from 0 below width do
		(let ((img2-color (cl-gd:get-pixel y x :image image2))
		      (img1-color (cl-gd:get-pixel y x :image image1)))
		  (incf err (square (- (the fixnum(cl-gd::gd-image-get-red img2 img2-color))
				       (the fixnum(cl-gd::gd-image-get-red img1 img1-color)))))
		  (incf err (square (- (the fixnum(cl-gd::gd-image-get-green img2 img2-color))
				       (the fixnum(cl-gd::gd-image-get-green img1 img1-color)))))
		  (incf err (square (- (the fixnum(cl-gd::gd-image-get-blue img2 img2-color))
				       (the fixnum(cl-gd::gd-image-get-blue img1 img1-color))))))))
    err))

This is the result of running the above pair of functions on a 1024x768 image.

----
First, the timing with the standard CL-GD:
(SBCL 1.0.28, CL-GD 0.5.6, UFFI-1.6.1, 3GHz Intel Core2 Duo, Linux))

CL-GD uses UFFI by default on SBCL

EVO-LISA> (progn
  (defparameter *image1* (cl-gd:create-image-from-file "023.JPG"))
  (defparameter *image2* (cl-gd:create-image-from-file "023.JPG"))
  (time (compare-images *image1* *image2*)))

height1=1024, height2=768
Evaluation took:
  1.684 seconds of real time
  1.688105 seconds of total run time (1.688105 user, 0.000000 system)
  100.24% CPU
  5,061,067,326 processor cycles
  141,296 bytes consed

0

EVO-LISA> (progn
  (defparameter *image1* (cl-gd:create-image-from-file "023.JPG"))
  (defparameter *image2* (cl-gd:create-image-from-file "023.JPG"))
  (time (compare-images-raw *image1* *image2*)))

height1=1024, height2=768
Evaluation took:
  1.476 seconds of real time
  1.424088 seconds of total run time (1.420088 user, 0.004000 system)
  96.48% CPU
  4,437,702,108 processor cycles
  106,112 bytes consed

0

-----

After changing cl-gd.asd so that CFFI-UFFI-COMPAT is used for SBCL
instead of UFFI:

;;;;;;;;

EVO-LISA> (progn
  (defparameter *image1* (cl-gd:create-image-from-file "023.JPG"))
  (defparameter *image2* (cl-gd:create-image-from-file "023.JPG"))
  (time (compare-images *image1* *image2*)))

height1=1024, height2=768
Evaluation took:
  0.336 seconds of real time
  0.336021 seconds of total run time (0.336021 user, 0.000000 system)
  100.00% CPU
  1,010,111,976 processor cycles
  21,712 bytes consed

0
EVO-LISA> (progn
  (defparameter *image1* (cl-gd:create-image-from-file "023.JPG"))
  (defparameter *image2* (cl-gd:create-image-from-file "023.JPG"))
  (time (compare-images-raw *image1* *image2*)))

height1=1024, height2=768
Evaluation took:
  0.282 seconds of real time
  0.284018 seconds of total run time (0.284018 user, 0.000000 system)
  100.71% CPU
  845,516,097 processor cycles
  21,936 bytes consed

0

------------

Surprisingly,  there is a 5x difference between using CFFI and UFFI.

Pixel-level access to an image, as provided by
cl-gd:get-pixel, and cl-gd:color-component, is usually used in image
processing, where cl-gd:get-pixel, and cl-gd:color-component will be
called for many pixels on the image (usually the whole image), so the
speed of these accessors is critical for image processing, and
for some reason, CFFI (viat cffi-uffi-compat) offers 5x faster pixel
level access than UFFI.

I don't know much about either CFFI or UFFI, but
CFFI-UFFI-COMPAT is the default already for CLISP and OpenMCL.
Maybe it's worth considering making CFFI-UFFI-COMPAT the default for
SBCL as well?

Regards,
Alex Fukunaga

Jeff Cunningham | 17 Oct 05:57
Favicon

problem compiling cl-gd-glue.c on 64-bit sytem

Has anyone had a problem compiling the cl-gd-glue.c into the shared 
library on a 64-bit system? It's never given me any problem on 32-bit 
systems, and I could swear I've done it on a 64-bit AMD Debian system 
before, but I just tried it on a new one and got this error:

make
gcc -I/usr/local/include -fPIC -c cl-gd-glue.c
ld -shared -lgd -lz -lpng -ljpeg -lfreetype -liconv -lm -lc cl-gd-glue.o 
-o cl-gd-glue.so -L/usr/local/lib
ld: /usr/local/lib/libz.a(compress.o): relocation R_X86_64_32 against `a 
local symbol' can not be used when making a shared object; recompile 
with -fPIC
/usr/local/lib/libz.a: could not read symbols: Bad value
make: *** [cl-gd-glue.so] Error 1

I'm trying to install cl-gd-0.5.6 straight from Edi's site. gd-2.0.35 is 
installed, along with the other dependencies. This is puzzling.

Jeff


Gmane