[cairo] CAIRO_FORMAT_ARGB32 format [ was: Re: "data" in cairo_image_surface_get_data ()

Nguyen Vu Hung vuhung16plus at gmail.com
Thu Nov 29 03:57:54 PST 2007


2007/11/28, Baz <brian.ewins at gmail.com>:

> You can share buffers between cairo and leptonica directly though,
> with a bit of trickery. Consider a 2-pixel image, in RGB24 format
> (choosing some rgb values to make this clear)
>

> on a little-endian platform: (bgrxbgrx)
> 0xa3 0xa2 0xa1 0x00 0xa6 0xa5 0xa4 0x00
>
> now here's that data in PIX format:

> on a little-endian platform: (xbgrxbgr)
> 0x00 0xa3 0xa2 0xa1 0x00 0xa6 0xa5 0xa4
>
> It should be obvious what the trick is now. Add 0x00 padding to the
> ends of the buffer, then if the cairo image is at 'c', the PIX image
> is at 'c + 1' on big-endian systems, and at 'c - 1' on little-endian
> systems. Of course, YMMV, one of the libs will not be accessing
> word-aligned data. You could use the same trick to copy the data from
> one buffer to another as well, avoiding individual bit shifts.
>

> So, assuming you are using a buffer which has padding around it as
> above (ie you've allocated it yourself and used
> cairo_image_surface_create_for_data), setting up a PIX structure for
> an RGB24 buffer is something like
>
> pix.w = cairo_image_surface_get_width (surf);
> pix.h = cairo_image_surface_get_height (surf);
> pix.d = 8;
> pix.wpl = cairo_image_surface_get_stride (surf) / 4;
> pix.data = cairo_image_surface_get_data (surf) + 1; // big-endian;
> little endian would have -1 here.
>
I don't understand your code.
pix.data, cairo_image_surface_get_data (surf) are pointers, is

pix.data = cairo_image_surface_get_data (surf) + 1;

syntax valid?

I'ved tried to convert back PIX to cairo's data format. In the
following code, I get PIX's data byte by byte, and set it to cairo's
data pointer. The code runs fine, but when I write cairo's *data to a
PNG file, the PNG output is weird.

One more point, In the function

cairo_image_surface_create_for_data

do I have to set the last paramater ( stride ) to wpl * 4 or w * 4?


    U32    *data, *ppixel;

    data = (U32*) pixGetData(pixCut); // PIX->data format

    U32 wpl = pixGetWpl(pixCut); // word per line
    U32 w = pixGetWidth(pixCut); // pix width
    U32 h = pixGetHeight(pixCut); // pix height

    cairo_surface_t* tmp_surface;
    unsigned char * data_cairo;

    int  i, j, k;

    unsigned char* rowptr;

    for (i = 0; i < h; i++) {
      ppixel = data + i * wpl;
      rowptr = &data_cairo[i * w * 4];
      for ( j = k = 0; j < w ; j++) {
	rowptr[k++] = GET_DATA_BYTE(ppixel, COLOR_BLUE);
	rowptr[k++] = GET_DATA_BYTE(ppixel, COLOR_GREEN);
	rowptr[k++] = GET_DATA_BYTE(ppixel, COLOR_RED);
	rowptr[k++] = 0xff; // alpha,
	ppixel++;
      }
    }

http://cairographics.org/manual/cairo-Image-Surfaces.html#cairo-image-surface-create-for-data
    tmp_surface = cairo_image_surface_create_for_data (data_cairo,
                               //CAIRO_FORMAT_ARGB32,
                               CAIRO_FORMAT_RGB24,
                               w, h,
                               wpl * 4);


http://aoclife.ddo.jp/~vuhung/tmp/leptonlib-1.51/src/arrayaccess.h
#define  GET_DATA_BYTE(pdata, n)              l_getDataByte(pdata, n)

http://aoclife.ddo.jp/~vuhung/tmp/leptonlib-1.51/src/arrayaccess.c
/*!
 *  l_getDataByte()
 *
 *      Input:  line  (ptr to beginning of data line)
 *              n     (pixel index)
 *      Return: value of the n-th (byte) pixel
 */
l_int32
l_getDataByte(l_uint32  *line,
              l_int32    n)
{
#ifdef  L_BIG_ENDIAN
    return *((l_uint8 *)line + n);
#else  /* L_LITTLE_ENDIAN */
    return *(l_uint8 *)((l_uintptr_t)((l_uint8 *)line + n) ^ 3);
#endif  /* L_BIG_ENDIAN */
}

http://aoclife.ddo.jp/~vuhung/tmp/leptonlib-1.51/src/pix.h
/*-------------------------------------------------------------------------*
 *                             Colors for 32 bpp                           *
 *-------------------------------------------------------------------------*/
/* Note: colors are used in 32 bpp images.  The 4th byte, typically
 *       known as the "alpha channel", can be used for blending.
 *       It's not explicitly used in leptonica.  */
enum {
    COLOR_RED = 0,
    COLOR_GREEN = 1,
    COLOR_BLUE = 2,
    L_ALPHA_CHANNEL = 3
};


-- 
Best Regards,
Nguyen Hung Vu
vuhung16plus{remove}@gmail.dot.com
An inquisitive look at Harajuku
http://www.flickr.com/photos/vuhung/sets/72157600109218238/


More information about the cairo mailing list