[cairo] 1.6: a8-mask: Making non-aligned strides illegal
Behdad Esfahbod
behdad at behdad.org
Mon Jan 28 17:07:27 PST 2008
On Mon, 2008-01-28 at 15:18 -0800, Carl Worth wrote:
> On Mon, 28 Jan 2008 16:59:05 -0500, Behdad Esfahbod wrote:
> > Right. Subsurfacing is only one use case for using a greater width
> > value for stride computation than the actual width.
> >
> > I still prefer at least allowing "any width" for stride.
>
> Yes, it should still be legal to use a smaller width as long as the
> stride matches what was allocated and the stride came from
> cairo_format_stride_for_width.
>
> I've rewritten the documentation again to clarify it, and this is what
> I've come up with:
>
> * @stride: the number of bytes between the start of rows in the
> * buffer as allocated. This value should always be computed by
> * cairo_format_stride_for_width() before allocating the data
> * buffer.
Other question: is a negative stride supported/allowed? FreeType uses
them for example. In new libraries I write I always use unsigned int
where negative values are not allowed. It makes things so much
easier...
...
> * Note that the stride will often be larger than
> * width*bytes_per_pixel to provide proper alignment for each
I'd replace "will often" by "may be". It isn't for ARGB32 after all.
Also this text ignores the fact that RGB24 is 3 bytes per pixel worth of
data but takes 4. But doesn't matter.
> * row. This alignment is required to allow high-performance rendering
> * within cairo. The correct way to obtain a legal stride value is to
> * call cairo_format_stride_for_width() with the desired format and
> * maximum image width value, and the use the resulting stride value
> * to allocate the data and to create the image surface. See
> * cairo_format_stride_for_width() for example code.
> ...
> * This function always returns a valid pointer, but it will return a
> * pointer to a "nil" surface in the case of an error such as out of
> * memory or an invalid stride value. You can use
> * cairo_surface_status() to check for this.
>
> I think that's the best I'm going to come up with for now, so I'll
> just push that. But feel free to tweak it further if you see any ways
> to improve it.
Is quite good actually other than the minor nits above.
> > Right. Also, in the patch I'd define a macro and use that instead of
> > hardcoding the 32-bit requirement in more than one place.
>
> I can throw in a LEGAL_STRIDE macro for (stride % sizeof (uint32_t) ==
> 0), but I'm only seeing that in one place
> (cairo_image_surface_create_for_data). Am I missing something? It's
> actually quite different what we need in
> cairo_format_stride_for_width.
#define STRIDE_ALIGNMENT (sizeof (uint32_t))
in cairo_image_surface_create_for_data:
if (stride & (STRIDE_ALIGNMENT-1) != 0)
err...
in cairo_format_stride_for_width:
return ((bpp*width+7)/8 + STRIDE_ALIGNMENT-1) & ~(STRIDE_ALIGNMENT-1)
> Or shall I do the macro and assert that the stride I compute in
> stride_for_width satisfies it?
>
> > Sounds fine. I marginally prefer requiring int alignment than any-type
> > alignment. But who knows what we'll require in the future...
>
> Right. Documenting things as safer than strictly necessary is a nice
> place to be. With that, we still have the freedom to loosen things up
> in the future if needed.
True. But you don't want to document so strictly that people keep
relying on documented-as-undefined behavior.
> -Carl
--
behdad
http://behdad.org/
"Those who would give up Essential Liberty to purchase a little
Temporary Safety, deserve neither Liberty nor Safety."
-- Benjamin Franklin, 1759
More information about the cairo
mailing list