image: Let __imlib_CreateImage() allocate pixel data buffer

..and check dimensions.

Does simplify things nicely.
This commit is contained in:
Kim Woelders 2023-01-13 11:36:06 +01:00
parent 5d16eb8bb8
commit 5d1083858c
6 changed files with 81 additions and 121 deletions

View File

@ -931,14 +931,11 @@ imlib_blend_image_onto_image(Imlib_Image src_image, char merge_alpha,
EAPI Imlib_Image
imlib_create_image(int width, int height)
{
uint32_t *data;
ImlibImage *im;
if (!IMAGE_DIMENSIONS_OK(width, height))
return NULL;
data = malloc(width * height * sizeof(uint32_t));
if (data)
return __imlib_CreateImage(width, height, data);
return NULL;
im = __imlib_CreateImage(width, height, NULL, 0);
return im;
}
EAPI Imlib_Image
@ -947,11 +944,13 @@ imlib_create_image_using_data(int width, int height, uint32_t * data)
ImlibImage *im;
CHECK_PARAM_POINTER_RETURN("data", data, NULL);
if (!IMAGE_DIMENSIONS_OK(width, height))
im = __imlib_CreateImage(width, height, data, 0);
if (!im)
return NULL;
im = __imlib_CreateImage(width, height, data);
if (im)
IM_FLAG_SET(im, F_DONT_FREE_DATA);
IM_FLAG_SET(im, F_DONT_FREE_DATA);
return im;
}
@ -962,11 +961,12 @@ EAPI Imlib_Image
ImlibImage *im;
CHECK_PARAM_POINTER_RETURN("data", data, NULL);
if (!IMAGE_DIMENSIONS_OK(width, height))
im = __imlib_CreateImage(width, height, data, 0);
if (!im)
return NULL;
im = __imlib_CreateImage(width, height, data);
if (im)
im->data_memory_func = func;
im->data_memory_func = func;
return im;
}
@ -977,20 +977,14 @@ imlib_create_image_using_copied_data(int width, int height, uint32_t * data)
ImlibImage *im;
CHECK_PARAM_POINTER_RETURN("data", data, NULL);
if (!IMAGE_DIMENSIONS_OK(width, height))
return NULL;
im = __imlib_CreateImage(width, height, NULL);
im = __imlib_CreateImage(width, height, NULL, 0);
if (!im)
return NULL;
im->data = malloc(width * height * sizeof(uint32_t));
if (data)
{
memcpy(im->data, data, width * height * sizeof(uint32_t));
return im;
}
else
__imlib_FreeImage(im);
return NULL;
memcpy(im->data, data, width * height * sizeof(uint32_t));
return im;
}
EAPI Imlib_Image
@ -1000,21 +994,14 @@ imlib_clone_image(void)
CHECK_PARAM_POINTER_RETURN("image", ctx->image, NULL);
CAST_IMAGE(im_old, ctx->image);
if (__imlib_LoadImageData(im_old))
return NULL;
/* Note: below check should've ensured by original image allocation,
* but better safe than sorry. */
if (!IMAGE_DIMENSIONS_OK(im_old->w, im_old->h))
im = __imlib_CreateImage(im_old->w, im_old->h, NULL, 0);
if (!im)
return NULL;
im = __imlib_CreateImage(im_old->w, im_old->h, NULL);
if (!(im))
return NULL;
im->data = malloc(im->w * im->h * sizeof(uint32_t));
if (!(im->data))
{
__imlib_FreeImage(im);
return NULL;
}
memcpy(im->data, im_old->data, im->w * im->h * sizeof(uint32_t));
im->flags = im_old->flags;
IM_FLAG_SET(im, F_UNCACHEABLE);
@ -1025,6 +1012,7 @@ imlib_clone_image(void)
im->format = strdup(im_old->format);
if (im_old->file)
im->file = strdup(im_old->file);
return im;
}
@ -1034,18 +1022,14 @@ imlib_create_cropped_image(int x, int y, int width, int height)
ImlibImage *im, *im_old;
CHECK_PARAM_POINTER_RETURN("image", ctx->image, NULL);
if (!IMAGE_DIMENSIONS_OK(abs(width), abs(height)))
return NULL;
CAST_IMAGE(im_old, ctx->image);
if (__imlib_LoadImageData(im_old))
return NULL;
im = __imlib_CreateImage(abs(width), abs(height), NULL);
im->data = malloc(abs(width * height) * sizeof(uint32_t));
if (!(im->data))
{
__imlib_FreeImage(im);
return NULL;
}
im = __imlib_CreateImage(abs(width), abs(height), NULL, 0);
if (!im)
return NULL;
im->has_alpha = im_old->has_alpha;
__imlib_BlendImageToImage(im_old, im, 0, 0, im->has_alpha,
@ -1065,18 +1049,14 @@ imlib_create_cropped_scaled_image(int src_x, int src_y,
ImlibImage *im, *im_old;
CHECK_PARAM_POINTER_RETURN("image", ctx->image, NULL);
if (!IMAGE_DIMENSIONS_OK(abs(dst_width), abs(dst_height)))
return NULL;
CAST_IMAGE(im_old, ctx->image);
if (__imlib_LoadImageData(im_old))
return NULL;
im = __imlib_CreateImage(abs(dst_width), abs(dst_height), NULL);
im->data = malloc(abs(dst_width * dst_height) * sizeof(uint32_t));
if (!(im->data))
{
__imlib_FreeImage(im);
return NULL;
}
im = __imlib_CreateImage(abs(dst_width), abs(dst_height), NULL, 0);
if (!im)
return NULL;
im->has_alpha = im_old->has_alpha;
__imlib_BlendImageToImage(im_old, im, ctx->anti_alias, 0, im->has_alpha,
@ -1938,17 +1918,10 @@ imlib_create_rotated_image(double angle)
dx = (int)(cos(angle) * _ROTATE_PREC_MAX);
dy = -(int)(sin(angle) * _ROTATE_PREC_MAX);
if (!IMAGE_DIMENSIONS_OK(sz, sz))
im = __imlib_CreateImage(sz, sz, NULL, 1);
if (!im)
return NULL;
im = __imlib_CreateImage(sz, sz, NULL);
im->data = calloc(sz * sz, sizeof(uint32_t));
if (!(im->data))
{
__imlib_FreeImage(im);
return NULL;
}
if (ctx->anti_alias)
{
__imlib_RotateAA(im_old->data, im->data, im_old->w, im_old->w,
@ -1998,16 +1971,6 @@ imlib_rotate_image_from_buffer(double angle, Imlib_Image src_image)
else
sz = im->w; // update sz with real width
#if 0 /* Not necessary 'cause destination is context */
im = __imlib_CreateImage(sz, sz, NULL);
im->data = calloc(sz * sz, sizeof(uint32_t));
if (!(im->data))
{
__imlib_FreeImage(im);
return;
}
#endif
if (ctx->anti_alias)
{
__imlib_RotateAA(im_old->data, im->data, im_old->w, im_old->w,

View File

@ -292,21 +292,18 @@ imlib_create_image_from_drawable(Pixmap mask, int x, int y, int width,
ImlibImage *im;
char domask = 0;
if (!IMAGE_DIMENSIONS_OK(width, height))
return NULL;
if (mask)
{
domask = 1;
if (mask == (Pixmap) 1)
mask = None;
}
im = __imlib_CreateImage(width, height, NULL);
im = __imlib_CreateImage(width, height, NULL, 0);
if (!im)
return NULL;
im->data = malloc(width * height * sizeof(uint32_t));
if (!im->data ||
!__imlib_GrabDrawableToRGBA(im->data, 0, 0, width, height, ctx->display,
if (!__imlib_GrabDrawableToRGBA(im->data, 0, 0, width, height, ctx->display,
ctx->drawable, mask, ctx->visual,
ctx->colormap, ctx->depth, x, y, width,
height, &domask, need_to_grab_x))
@ -326,17 +323,10 @@ imlib_create_image_from_ximage(XImage * image, XImage * mask, int x, int y,
{
ImlibImage *im;
if (!IMAGE_DIMENSIONS_OK(width, height))
return NULL;
im = __imlib_CreateImage(width, height, NULL);
im = __imlib_CreateImage(width, height, NULL, 0);
if (!im)
return NULL;
im->data = malloc(width * height * sizeof(uint32_t));
if (!im->data)
{
__imlib_FreeImage(im);
return NULL;
}
__imlib_GrabXImageToRGBA(im->data, 0, 0, width, height,
ctx->display, image, mask, ctx->visual,
ctx->depth, x, y, width, height, need_to_grab_x);
@ -355,23 +345,14 @@ imlib_create_scaled_image_from_drawable(Pixmap mask, int src_x, int src_y,
if (!IMAGE_DIMENSIONS_OK(src_width, src_height))
return NULL;
if (!IMAGE_DIMENSIONS_OK(dst_width, dst_height))
return NULL;
im = __imlib_CreateImage(dst_width, dst_height, NULL);
im = __imlib_CreateImage(dst_width, dst_height, NULL, 0);
if (!im)
return NULL;
im->data = malloc(dst_width * dst_height * sizeof(uint32_t));
if (!im->data)
{
__imlib_FreeImage(im);
return NULL;
}
domask = mask != 0 || get_mask_from_shape;
if (!im->data ||
!__imlib_GrabDrawableScaledToRGBA(im->data, 0, 0, dst_width, dst_height,
if (!__imlib_GrabDrawableScaledToRGBA(im->data, 0, 0, dst_width, dst_height,
ctx->display, ctx->drawable, mask,
ctx->visual, ctx->colormap, ctx->depth,
src_x, src_y, src_width, src_height,

View File

@ -71,24 +71,16 @@ __imlib_render_str(ImlibImage * im, ImlibFont * fn, int drx, int dry,
{
int w, h, ascent;
ImlibImage *im2;
uint32_t *data;
int nx, ny;
__imlib_font_query_advance(fn, text, &w, NULL);
h = __imlib_font_max_ascent_get(fn) - __imlib_font_max_descent_get(fn);
if (!IMAGE_DIMENSIONS_OK(w, h))
return;
data = calloc(w * h, sizeof(uint32_t));
if (!data)
return;
/* TODO check if this is the right way of rendering. Esp for huge sizes */
im2 = __imlib_CreateImage(w, h, data);
im2 = __imlib_CreateImage(w, h, NULL, 1);
if (!im2)
{
free(data);
return;
}
return;
im2->has_alpha = 1;
ascent = __imlib_font_max_ascent_get(fn);

View File

@ -362,19 +362,42 @@ __imlib_GetCacheSize(void)
return cache_size;
}
/* create a new image struct from data passed that is wize w x h then return */
/* a pointer to that image sturct */
/* Create a new image struct
* If data is non-zero use it for pixel data, otherwise allocate the
* pixel data buffer.
* If zero is set the pixel data buffer is zeroed. */
ImlibImage *
__imlib_CreateImage(int w, int h, uint32_t * data)
__imlib_CreateImage(int w, int h, uint32_t * data, int zero)
{
ImlibImage *im;
uint32_t *dptr = data;
if (!IMAGE_DIMENSIONS_OK(w, h))
return NULL;
if (!dptr)
{
if (zero)
dptr = calloc(w * h, sizeof(uint32_t));
else
dptr = malloc(w * h * sizeof(uint32_t));
}
if (!dptr)
return NULL;
im = __imlib_ProduceImage();
if (!im)
{
if (!data)
free(dptr);
return NULL;
}
im->w = w;
im->h = h;
im->data = data;
im->data = dptr;
im->references = 1;
IM_FLAG_SET(im, F_UNCACHEABLE);
return im;
}

View File

@ -98,7 +98,8 @@ typedef struct {
ImlibLoader *__imlib_FindBestLoader(const char *file, const char *format,
int for_save);
ImlibImage *__imlib_CreateImage(int w, int h, uint32_t * data);
ImlibImage *__imlib_CreateImage(int w, int h, uint32_t * data,
int zero);
ImlibImage *__imlib_LoadImage(const char *file, ImlibLoadArgs * ila);
int __imlib_LoadEmbedded(ImlibLoader * l, ImlibImage * im,
int load_data, const char *file);

View File

@ -559,13 +559,12 @@ __imlib_RenderImageSkewed(Display * d, ImlibImage * im, Drawable w, Drawable m,
dy1 = 0;
}
if (!IMAGE_DIMENSIONS_OK(dw, dh))
back = __imlib_CreateImage(dw, dh, NULL, 1);
if (!back)
return;
__imlib_GetContext(d, v, cm, depth);
back = __imlib_CreateImage(dw, dh, NULL);
back->data = calloc(dw * dh, sizeof(uint32_t));
__imlib_GrabDrawableToRGBA(back->data, 0, 0, dw, dh, d, w, 0, v, cm,
depth, dx1, dy1, dw, dh, 0, 1);
@ -576,5 +575,6 @@ __imlib_RenderImageSkewed(Display * d, ImlibImage * im, Drawable w, Drawable m,
__imlib_RenderImage(d, back, w, m, v, cm, depth, 0, 0, dw, dh,
dx1, dy1, dw, dh, 0, hiq, 0, dither_mask, mat, 0,
OP_COPY);
__imlib_FreeImage(back);
}