[cairo] [BUG] cairo-script-surface/_write_image_surface() does not work
ian_bruce at mail.ru
ian_bruce at mail.ru
Wed Apr 26 23:53:08 UTC 2017
Some of the output code for script surfaces seems to be incorrect.
excerpting from here:
https://cgit.freedesktop.org/cairo/tree/src/cairo-script-surface.c?h=1.14#n1212
#if WORDS_BIGENDIAN
...
case CAIRO_FORMAT_RGB24:
for (row = image->height; row--; ) {
int col;
rowdata = data;
for (col = width; col--; ) {
_cairo_output_stream_write (output, rowdata, 3);
rowdata+=4;
}
data += stride;
}
break;
...
#else
...
case CAIRO_FORMAT_RGB24:
for (row = image->height; row--; ) {
uint8_t *src = data;
int col;
for (col = 0; col < width; col++) {
rowdata[3*col+2] = *src++;
rowdata[3*col+1] = *src++;
rowdata[3*col+0] = *src++;
src++;
}
_cairo_output_stream_write (output, rowdata, 3*width);
data += stride;
}
break;
...
#endif
related documentation:
https://www.cairographics.org/manual/cairo-Image-Surfaces.html#cairo-format-t
CAIRO_FORMAT_RGB24
each pixel is a 32-bit quantity, with the upper 8 bits unused. Red,
Green, and Blue are stored in the remaining 24 bits in that order.
(Since 1.0)
To summarize: in the case of a little-endian CPU (!WORDS_BIGENDIAN),
each 32-bit pixel is byte-swapped, and the low-order 24 bits are written
to the output stream. The unused high-order 8 bits are ignored. Fair
enough. However, in the case of a big-endian CPU, the high-order 24
bits, including the 8 unused ones, are written directly to the output
stream, whereas the low-order 8 bits representing the blue channel are
discarded. Nobody cares about blue, anyway.
I don't see how this code can possibly do what it's supposed to. Perhaps
it's never been tested on a big-endian CPU; x86-32 and x86-64 are both
little-endian.
Am I wrong? More startling bugs to follow.
-- Ian Bruce
More information about the cairo
mailing list