[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