[cairo] Pixel RGB Values...

Chris Wilson chris at chris-wilson.co.uk
Thu Jul 9 04:07:29 PDT 2009


On Thu, 2009-07-09 at 06:52 +0000, Steril 707 wrote:
> I am working on a little image processing app, and would need to be
> able to get the RGB values of certain pixels on a surface.
> Is there any way to do that already with cairo at the moment? I cannot
> find anything in the API reference on that, so I thought I should ask
> you people here... And, if that's not possible, are there any plans
> for this to get implemented?

This is a nice timely reminder that I have something like this in
mind. :)

I've a couple of routines in mind to enable 'direct' access to the
backing pixel storage and enable efficient upload of pixel data.

The first is a convenient method for direct access (prototyped in
cairo-drm, and used to good effect):

  cairo_surface_t *
  cairo_surface_map (cairo_surface_t *surface);

  void
  cairo_surface_unmap (cairo_surface_t *surface,
                       cairo_surface_t *image);

(whilst unmap looks cumbersome in that you have to remember the original
surface, in practice this helps enforce scope and imply that such access
is temporary. For instance, if you map a cairo-drm surface, that then
disables rendering via the GPU until you relinquish the map.)

In use, mapping a surface returns an image surface that you can use to
manipulate pixels directly, and unmapping ensures that the changes are
flushed to the backing surface. Internally this works just like
acquire_dest_image()/release_dest_image() but with the extra caveat that
the surface is exported and so we need to redirect rendering whilst the
map is in effect. I like map/unmap (as used by pixel buffer objects in
OpenGL), but alternative names used elsewhere include lock/unlock.
(lock/unlock imply to me that any rendering to the original surface is
disabled - a side-effect I don't like, but may be cause less confusion
in the long run.)

The second method I think we need is for efficient pixel upload. Already
win32 has such a scheme, but it is of general use. My proposal here is:

  cairo_surface_t *
  cairo_surface_create_similar_image (cairo_surface_t *target,
                                      cairo_content_t content,
                                      int width, int height);

That returns an image that has appropriate backing storage to enable
efficient upload to the target surface. (This is the best name I've come
up with since the last time this proposal stumbled due to not finding a
good name... ;-) The tricky issue here is whether it should take a
content or a format. When uploading pixel data you really want to avoid
format conversion if possible, so maybe:

   typedef pixman_format_code_t cairo_wacky_format_t
   cairo_surface_t *
   cairo_surface_create_similar_image (cairo_surface_t *target,
                                       cairo_wacky_format_t format,
                                       int width, height);

would be better. Ok, cairo_extended_format_t might be more sensible than
cairo_wacky_format_t. How the application falls back when the target
does not support the wacky format is then left up to the application,
but there is still an opportunity not to convert.

If cairo_wacky_format_t is acceptable, I think we should also add:

  cairo_surface_t *
  cairo_image_surface_create_for_wacky_format
              (uint8_t *data,
               cairo_wacky_format_t wacky_format,
               int width,
               int height,
               int stride);

Thoughts? Or, more importantly, objections?
-ickle



More information about the cairo mailing list