if (!g_size_checked_mul (&plane_size, plane_width, block_bytes)) returnFALSE; /* round up to alignment using fancy checked math */ if (!g_size_checked_add (&plane_size, plane_size, (align - plane_size % align) % align)) returnFALSE;
if (!gdk_memory_format_is_block_boundary (self->format, self->width, self->height))
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED, "image size %zux%zu is not a multiple of the block size %zux%zu",
self->width, self->height,
gdk_memory_format_get_block_width (self->format),
gdk_memory_format_get_block_height (self->format)); returnFALSE;
}
needed_size = 0; for (p = 0; p < gdk_memory_format_get_n_planes (self->format); p++)
{
gsize block_width, block_height, block_bytes, plane_size;
if (self->planes[p].offset < needed_size)
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED, "offset for plane %zu is %zu which overlaps previous plane going up to offset %zu",
p, self->planes[p].offset, needed_size); returnFALSE;
}
if (!g_size_checked_mul (&plane_size, self->width / block_width, block_bytes))
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED, "stride for plane %zu is %zu bytes, but image width %zu would overflow the stride requirement",
p, self->planes[p].stride, self->width); returnFALSE;
} if (plane_size > self->planes[p].stride)
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED, "stride for plane %zu is %zu bytes, but image width %zu requires a stride of %zu bytes",
p, self->planes[p].stride, self->width, plane_size); returnFALSE;
}
if (!g_size_checked_mul (&plane_size, self->planes[p].stride, (self->height - 1) / block_height) ||
!g_size_checked_add (&plane_size, plane_size, self->width / block_width * block_bytes))
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED, "size for plane %zu would overflow, image size %zux%zu with stride of %zu bytes is too large",
p, self->width, self->height, self->planes[p].stride); returnFALSE;
} if (!g_size_checked_add (&needed_size, self->planes[p].offset, plane_size))
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED, "size for plane %zu of %zu bytes at offset %zu does overflow",
p, plane_size, self->planes[p].offset); returnFALSE;
}
}
if (needed_size > self->size)
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED, "image size of %zu bytes is too small, at least %zu bytes are needed",
self->size, needed_size); returnFALSE;
}
align = MAX (align, gdk_memory_format_alignment (self->format));
if (self->size % align) returnFALSE;
for (i = 0; i < gdk_memory_format_get_n_planes (self->format); i++)
{ if (self->planes[i].offset % align ||
self->planes[i].stride % align) returnFALSE;
}
returnTRUE;
}
/* This is just meant to be a good enough check for assertions, not a guaranteed *checkyoucanrelyon. *It'smeanttocheckaccidentaloverlapduringcopiesbetweenlayouts.
*/
gboolean
gdk_memory_layout_has_overlap (const guchar *data1, const GdkMemoryLayout *layout1, const guchar *data2, const GdkMemoryLayout *layout2)
{ /* really, these are pointers, but we wanna do math on them */
gsize start1, end1, start2, end2, shift;
/* This can't happen with subimages of the same large image, so something
* is probably screwed up. */ if (layout1->planes[0].stride != layout2->planes[0].stride) returnTRUE;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.