On Wed, 31 Aug 2005, Timothy Hunter wrote:

> Darn. After reading Ara's post I started thinking about a way to move pixels
> more-or-less directly from a file into an image, bypassing the need to
> create Magick::Pixel objects. I emailed the ImageMagick team and asked for
> their recommendation. The absolute fastest way to get pixel data into an
> image is via the ImageMagick API that RMagick's Image::import_pixels method
> (http://www.simplesystems.org/RMagick/doc/image2.html#import_pixels) uses,
> called ImportImagePixels. ImportImagePixels expects a C array of pixel data
> in scanline order, top-to-bottom, right-to-left. You can specify the data
> type of the array (char, short, int, long) and the order in which the
> channel data appear (RGB, RGBA, CMYK, etc.) The IM developers tell me that
> ImportImagePixels is optimized for the RGB case so I suspect that this would
> be a very - I repeat, very - fast way to load pixels into an image.

plus plus on the 'very' ;-)

> Currently #import_pixels wants a Ruby array of Fixnums which it then
> converts to a C array. Lotsa overhead.
>
> Following Ara's suggestion, I was thinking about changing #import_pixels to
> accept a string (to be exact, any object that responds to to_str) in place
> of the array. In this case #import_pixels would simply call to_str and
> assume that the result is a C array of the correct type and size and with
> the channel data in the specified order and hand it off to ImportImagePixels
> directly.

so

   pixels, is_string =
     case obj
       when Array
         [ obj, false ]
       else
         [ obj.to_str, true ]
     end

   ...
   ...

??

> I realize this doesn't really help you since your input data isn't in the
> format ImportImagePixels wants. However, if you (or Ara, or anybody else
> with an interest) have an opinion about the usefulness of this idea I'd like
> to hear it.

it sounds brilliant!  but:

     jib:~ > irb -r mmap -r narray

     irb(main):001:0> NArray::byte(42,42).methods.grep /to_s/
     => ["to_s", "to_string"]

     irb(main):002:0> Mmap::new('/home/ahoward/.bashrc').methods.grep /to_s/
     => ["to_sym", "to_str", "to_s"]

so maybe something like

   cast = %w( pixels to_str to_s to_string ).select{|m| obj.respond_to? m }.first

   pixels = obj.send(cast) if cast

eg.  include other likely candidates in addition to to_str.  i think it's safe
to say that any user capable of setting up a region of memory representing an
inline image will be willing to accept any consequences of doing it improperly
so doing a blind read is fine in this case - but that's obviously my opinion.

thanks for keeping tabs on this btw.

cheers.

-a
-- 
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| Your life dwells amoung the causes of death
| Like a lamp standing in a strong breeze.  --Nagarjuna
===============================================================================