views:

79

answers:

2

I was trying to write my own put-pixel on (Gdk) pixbuf in Lisp. When I finally realized how I can operate on C pointers in CL, new obstacle came along - (gdk:pixbuf-get-pixels pb) returns me negative number. My question is: can I convert it somehow to a valid pointer? My attempts to use cffi:convert-from-foreign and cffi:translate-from-foreign (what's the difference between them anyway?) failed.

Below is my actual (not working) code:

(defun put-pixel (pixbuf x y r g b)
  (let ((p (+ (gdk:pixbuf-get-pixels pixbuf) (* x (gdk:pixbuf-get-n-channels pixbuf)) (* y (gdk:pixbuf-get-rowstride pixbuf)))))
    (setf (cffi:mem-aref p :unsigned-char 0) r)
    (setf (cffi:mem-aref p :unsigned-char 1) g)
    (setf (cffi:mem-aref p :unsigned-char 2) b)))
+5  A: 

CFFI:TRANSLATE-FROM-FOREIGN is a generic function. You can define your own foreign types using CFFI:DEFINE-FOREIGN-TYPE and then add a method to CFFI:TRANSLATE-FROM-FOREIGN to specify how the conversions from foreign to Lisp values should work.

CFFI:CONVERT-FROM-FOREIGN is what you should call if you need to explicitly convert some value. It will call CFFI:TRANSLATE-FROM-FOREIGN behind the scenes and it might perform some compile-time optimizations if possible.

Same thing applies to CFFI:CONVERT-TO-FOREIGN and CFFI:TRANSLATE-TO-FOREIGN.

Luís Oliveira
+2  A: 

I think that lambda-gtk incorrectly defined binding for pixbuf-get-pixels.

The negative value for pointer value might appear because of incorrect interpretation of unsigned integer as a signed integer.

The simplest way to correct this value is to use mod:

CL-USER> (mod -1 (expt 2 #+cffi-features:x86 32 #+cffi-features:x86-64 64))
4294967295
dmitry_vk
Well, it seems that something's really is wrong with that function. I had to try different approach.
x13n