optimizations in image display, resolved some false leak report due to untracked mallocs

This commit is contained in:
Stefan Frederik 2022-01-20 00:47:15 +01:00
parent c3af523559
commit 3958faf1aa
6 changed files with 42 additions and 39 deletions

View File

@ -583,9 +583,7 @@ int setup_rect_extraptr(int what, xRect *drptr, xRect *srptr)
s = srptr->extraptr;
if(s) {
d = my_malloc(1478, sizeof(xEmb_image));
d->data = my_malloc(1479, s->data_size);
memcpy(d->data, s->data, s->data_size);
d->data_size = s->data_size;
d->image = NULL;
drptr->extraptr = d;
} else {
drptr->extraptr = NULL;
@ -596,8 +594,7 @@ int setup_rect_extraptr(int what, xRect *drptr, xRect *srptr)
if(!drptr->extraptr) {
xEmb_image *d;
d = my_malloc(1465, sizeof(xEmb_image));
d->data = NULL;
d->data_size = 0;
d->image = NULL;
drptr->extraptr = d;
}
}
@ -605,7 +602,9 @@ int setup_rect_extraptr(int what, xRect *drptr, xRect *srptr)
if(drptr->flags & 1024) { /* embedded image */
if(drptr->extraptr) {
xEmb_image *d = drptr->extraptr;
if(d->data) my_free(1475, &d->data);
#if HAS_CAIRO==1
if(d->image) cairo_surface_destroy(d->image);
#endif
my_free(1476, &drptr->extraptr);
}
}

View File

@ -2594,8 +2594,9 @@ int draw_images_all(void)
#if HAS_CAIRO==1
int i, bbox_set = 0, w, h;
double x, y, rw, rh;
double sx1, sy1, sx2, sy2;
int save_bbx1, save_bby1, save_bbx2, save_bby2;
cairo_surface_t *image;
if(xctx->draw_single_layer==-1 || GRIDLAYER == xctx->draw_single_layer) {
if(xctx->enable_layer[GRIDLAYER]) for(i = 0; i < xctx->rects[GRIDLAYER]; i++) {
@ -2616,7 +2617,13 @@ int draw_images_all(void)
save_bby2 = xctx->bby2;
bbox(END, 0.0, 0.0, 0.0, 0.0);
}
/* screen position */
sx1=X_TO_SCREEN(r->x1);
sy1=Y_TO_SCREEN(r->y1);
sx2=X_TO_SCREEN(r->x2);
sy2=Y_TO_SCREEN(r->y2);
if(RECT_OUTSIDE(sx1, sy1, sx2, sy2,
xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2)) continue;
if(!r->extraptr) {
setup_rect_extraptr(1, r, NULL);
}
@ -2625,36 +2632,33 @@ int draw_images_all(void)
cairo_save(xctx->cairo_save_ctx);
/* read PNG from in-memory buffer ... */
if(emb_ptr && emb_ptr->data && emb_ptr->data_size) {
closure.buffer = emb_ptr->data;
closure.pos = 0;
closure.size = emb_ptr->data_size; /* should not be necessary */
image = cairo_image_surface_create_from_png_stream(png_reader, &closure);
dbg(1, "draw_images_all(): length1 = %d\n", closure.pos);
if(emb_ptr && emb_ptr->image) {
; /* nothing to do, image is already created */
/* ... or read PNG from image_data attribute */
} else if( (attr = get_tok_value(r->prop_ptr, "image_data", 0))[0] ) {
emb_ptr->data = base64_decode(attr, strlen(attr), &emb_ptr->data_size);
closure.buffer = emb_ptr->data;
size_t data_size;
closure.buffer = base64_decode(attr, strlen(attr), &data_size);
closure.pos = 0;
closure.size = emb_ptr->data_size; /* should not be necessary */
image = cairo_image_surface_create_from_png_stream(png_reader, &closure);
closure.size = data_size; /* should not be necessary */
emb_ptr->image = cairo_image_surface_create_from_png_stream(png_reader, &closure);
if(closure.buffer == NULL) dbg(0, "Error: null closure.buffer, i=%d\n", i);
my_free(1467, &closure.buffer);
dbg(1, "draw_images_all(): length2 = %d\n", closure.pos);
/* ... or read PNG from file (image attribute) */
} else if( (filename = get_tok_value(r->prop_ptr, "image", 0))[0] && !stat(filename, &buf)) {
char *image_data = NULL;
size_t olength;
image = cairo_image_surface_create_from_png(filename);
if(cairo_surface_status(image) != CAIRO_STATUS_SUCCESS) return 1;
emb_ptr->image = cairo_image_surface_create_from_png(filename);
if(cairo_surface_status(emb_ptr->image) != CAIRO_STATUS_SUCCESS) return 1;
/* write PNG to in-memory buffer */
closure.buffer = NULL;
closure.size = 0;
closure.pos = 0;
cairo_surface_write_to_png_stream(image, png_writer, &closure);
cairo_surface_write_to_png_stream(emb_ptr->image, png_writer, &closure);
dbg(1, "draw_images_all(): length3 = %d\n", closure.pos);
emb_ptr->data = closure.buffer;
emb_ptr->data_size = closure.pos;
/* put base64 encoded data to rect image_data attrinute */
image_data = base64_encode(emb_ptr->data, emb_ptr->data_size, &olength);
image_data = base64_encode(closure.buffer, closure.pos, &olength);
my_free(1468, &closure.buffer);
my_realloc(1466, &image_data, olength + 1);
image_data[olength] = '\0';
my_strdup2(1473, &r->prop_ptr, subst_token(r->prop_ptr, "image_data", image_data));
@ -2662,9 +2666,9 @@ int draw_images_all(void)
} else {
return 1;
}
if(cairo_surface_status(image) != CAIRO_STATUS_SUCCESS) return 1;
w = cairo_image_surface_get_width (image);
h = cairo_image_surface_get_height (image);
if(cairo_surface_status(emb_ptr->image) != CAIRO_STATUS_SUCCESS) return 1;
w = cairo_image_surface_get_width (emb_ptr->image);
h = cairo_image_surface_get_height (emb_ptr->image);
dbg(1, "draw_images_all() w=%d, h=%d\n", w, h);
x = X_TO_SCREEN(r->x1);
y = Y_TO_SCREEN(r->y1);
@ -2674,10 +2678,8 @@ int draw_images_all(void)
scalex = rw/w * xctx->mooz;
scaley = rh/h * xctx->mooz;
cairo_scale(xctx->cairo_save_ctx, scalex, scaley);
cairo_set_source_surface(xctx->cairo_save_ctx, image, 0. , 0.);
cairo_set_source_surface(xctx->cairo_save_ctx, emb_ptr->image, 0. , 0.);
cairo_paint(xctx->cairo_save_ctx);
cairo_surface_destroy(image);
cairo_restore(xctx->cairo_ctx);
cairo_restore(xctx->cairo_save_ctx);
if(bbox_set) {

View File

@ -42,7 +42,7 @@ char *base64_encode(const unsigned char *data, size_t input_length, size_t *outp
char *encoded_data;
*output_length = 4 * ((input_length + 2) / 3);
encoded_data = malloc(*output_length);
encoded_data = my_malloc(1469, *output_length);
if (encoded_data == NULL) return NULL;
for (i = 0, j = 0; i < input_length;) {
int octet_a = i < input_length ? (unsigned char)data[i++] : 0;
@ -86,7 +86,7 @@ unsigned char *base64_decode(const char *data, size_t input_length, size_t *outp
*output_length = input_length / 4 * 3;
if (data[input_length - 1] == '=') (*output_length)--;
if (data[input_length - 2] == '=') (*output_length)--;
decoded_data = malloc(*output_length);
decoded_data = my_malloc(1470, *output_length);
if (decoded_data == NULL) return NULL;
for (i = 0, j = 0; i < input_length;) {
int sextet_a = data[i] == '=' ? 0 & i++ : b64_dec[(int)data[i++]];

View File

@ -397,8 +397,7 @@ typedef struct
typedef struct
{
unsigned char *data;
size_t data_size;
cairo_surface_t *image;
} xEmb_image;
typedef struct

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long