3

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)))
x13n
  • 4,103
  • 2
  • 21
  • 28

2 Answers2

5

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,964
  • 1
  • 20
  • 26
2

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
  • 4,399
  • 18
  • 21
  • Well, it seems that something's really is wrong with that function. I had to try different approach. – x13n Nov 18 '09 at 10:52