[Openmcl-devel] Advice needed: best way to fram a Lisp array into an ns-image

Ron Garret ron at awun.net
Fri Jan 18 19:10:42 PST 2008

On Jan 18, 2008, at 6:50 PM, R. Matthew Emerson wrote:

> On Jan 18, 2008, at 8:15 PM, Ron Garret wrote:
>> What is the easiest way to fram a Lisp array of numbers representing
>> pixel data into an ns-image object?  The best I've been able to come
>> up with is:
>> 1.  Create the NSImage and initialize it with initWithSize
>> 2.  Create an NSData object and stick the pixel data into it.
>> 2.  Create an NSBitMapImageRep and initialize it with (deep  
>> breath)...
>> initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bytesPerRow:bitsPerPixel
>> (Whew!)
>> 3.  Add the NSBitMapImageRep to the NSImage using addRepresentation:
>> But that seems horribly clunky compared to how easy everything else
>> having to do with images is turning out to be.  Is there a better way
>> to do this?
>> (BTW, the only reason I really need to do this is that  
>> getPixel:atX:y:
>> and setPixel:atX:y:: are gawdawful slow, like a thousand times slower
>> than an aref.  If there's a fast way to access pixels directly from a
>> NSBitMapImageRep then I can just use that.  But it seems like there's
>> not.)
> When using that really long initWithBitmapDataPlanes:... method, you  
> have two options.  You can pass NULL as the first argument, and  
> memory for the bitmap will be allocated and owned by the  
> NSBitmapImageRep instance.  You can get a reference to the bitmap  
> with the bitmapData method, and read/modify the data with CCL's  
> foreign memory accessors (%get-unsigned-byte, whatever...)
> http://doc.clozure.com/doku.php/doc/openmcl/ffi#referencing_and_using_foreign_memory_addresses
> Alternatively, if you already have the image data somewhere, you can  
> pass initWithBitmapDataPlanes:... a pointer to it.  However, you  
> must ensure that the data sticks around as long as the  
> NSBitmapImageRep instance does.  But, if you've got a regular lisp  
> array with the image data in it, there's no way to pass a pointer to  
> said array to foreign code.
> There is a function called CCL:MAKE-HEAP-IVECTOR that might be  
> useful in this circumstance.  MAKE-HEAP-IVECTOR returns both a  
> macptr and a (one-dimensional) lisp array which share the same  
> memory.  (I don't know offhand what, if any, performance price there  
> would be to pay if you made a 2-D array displaced to the 1-D heap  
> ivector.)  The GC won't move the heap ivector around, so it's safe  
> to reference from foreign code.  On the other hand, you have to call  
> http://doc.clozure.com/doku.php/doc/openmcl/ffi#tutorialallocating_foreign_data_on_the_lisp_heap
> Maybe something I wrote here will give you an idea.

That's pretty much what I'm doing, so I guess that means I'm kinda on  
the right track.  Good to know.


More information about the Openmcl-devel mailing list