[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