Skip to content

Commit

Permalink
Fixes for dt_image_update_final_size() and dt_image_get_final_size()
Browse files Browse the repository at this point in the history
In dt_image_update_final_size() we **must not** use dt_cache_release() if the entry is NULL.

In dt_image_get_final_size() we kept a pointer to a dt_image_t struct and later used it after
the original dt_image_t has been released.
If system is under heavy cache load this could very well fail - and it does.
  • Loading branch information
jenshannoschwalm committed Dec 26, 2024
1 parent 5319fa8 commit b525deb
Showing 1 changed file with 27 additions and 24 deletions.
51 changes: 27 additions & 24 deletions src/common/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -851,43 +851,44 @@ void dt_image_update_final_size(const dt_imgid_t imgid)
&ww, &hh);

dt_image_t *imgtmp = dt_image_cache_get(darktable.image_cache, imgid, 'w');
if(!imgtmp || (ww == imgtmp->final_width && hh == imgtmp->final_height))
{
dt_cache_release(&darktable.image_cache->cache, imgtmp->cache_entry);
}
else
if(imgtmp)
{
const gboolean changed = (ww != imgtmp->final_width) || (hh != imgtmp->final_height);
imgtmp->final_width = ww;
imgtmp->final_height = hh;
dt_image_cache_write_release(darktable.image_cache, imgtmp, DT_IMAGE_CACHE_RELAXED);
DT_CONTROL_SIGNAL_RAISE(DT_SIGNAL_METADATA_UPDATE);
DT_CONTROL_SIGNAL_RAISE(DT_SIGNAL_DEVELOP_IMAGE_CHANGED);
if(changed)
{
dt_print(DT_DEBUG_PIPE, "[dt_image_update_final_size] for ID=%i, updated to %ix%i", imgid, ww, hh);
DT_CONTROL_SIGNAL_RAISE(DT_SIGNAL_METADATA_UPDATE);
DT_CONTROL_SIGNAL_RAISE(DT_SIGNAL_DEVELOP_IMAGE_CHANGED);
}
}
}
dt_print(DT_DEBUG_PIPE, "[dt_image_update_final_size] for ID=%i, updated to %ix%i", imgid, ww, hh);
}

gboolean dt_image_get_final_size(const dt_imgid_t imgid, int *width, int *height)
{
if(!dt_is_valid_imgid(imgid)) return TRUE;
// get the img strcut
dt_image_t *imgtmp = dt_image_cache_get(darktable.image_cache, imgid, 'r');
dt_image_t img = *imgtmp;
dt_image_cache_read_release(darktable.image_cache, imgtmp);
if(!imgtmp)
dt_image_t *timg = dt_image_cache_get(darktable.image_cache, imgid, 'r');
if(!timg)
{
*width = 0;
*height = 0;
return FALSE;
}

// if we already have computed them
if(img.final_height > 0 && img.final_width > 0)
const gboolean available = timg->final_height > 0 && timg->final_width > 0;
if(available)
{
*width = img.final_width;
*height = img.final_height;
*width = timg->final_width;
*height = timg->final_height;
dt_print(DT_DEBUG_PIPE, "[dt_image_get_final_size] for ID=%i from cache %ix%i", imgid, *width, *height);
return FALSE;
}
dt_image_cache_read_release(darktable.image_cache, timg);
if(available) return FALSE;

// we have to do the costly pipe run to get the final image size
dt_print(DT_DEBUG_PIPE, "[dt_image_get_final_size] calculate it for ID=%i", imgid);
Expand All @@ -896,8 +897,9 @@ gboolean dt_image_get_final_size(const dt_imgid_t imgid, int *width, int *height
dt_dev_load_image(&dev, imgid);

dt_dev_pixelpipe_t pipe;
int wd = dev.image_storage.width, ht = dev.image_storage.height;
gboolean res = dt_dev_pixelpipe_init_dummy(&pipe, wd, ht);
int wd = dev.image_storage.width;
int ht = dev.image_storage.height;
const gboolean res = dt_dev_pixelpipe_init_dummy(&pipe, wd, ht);
if(res)
{
// set mem pointer to 0, won't be used.
Expand All @@ -909,16 +911,17 @@ gboolean dt_image_get_final_size(const dt_imgid_t imgid, int *width, int *height
&pipe.processed_height);
wd = pipe.processed_width;
ht = pipe.processed_height;
res = TRUE;
dt_dev_pixelpipe_cleanup(&pipe);
}
dt_dev_cleanup(&dev);

imgtmp = dt_image_cache_get(darktable.image_cache, imgid, 'w');
imgtmp->final_width = *width = wd;
imgtmp->final_height = *height = ht;
dt_image_cache_write_release(darktable.image_cache, imgtmp, DT_IMAGE_CACHE_RELAXED);

dt_image_t * imgwr = dt_image_cache_get(darktable.image_cache, imgid, 'w');
if(imgwr)
{
imgwr->final_width = *width = wd;
imgwr->final_height = *height = ht;
dt_image_cache_write_release(darktable.image_cache, imgwr, DT_IMAGE_CACHE_RELAXED);
}
return res;
}

Expand Down

0 comments on commit b525deb

Please sign in to comment.