forked from old/legacy-imlib2
Okay. imlib_free_image_and_decache() was leaking images. I hope I made the
right fix here. Basically, the imlib_free_image_and_decache() call in api.c sets the flag F_INVALID then calls the internal __ImlibFreeImage(), this checks if the flag F_UNCACHEABLE is set, and only frees it if so. So the image never got free()d. I have changed the imlib_free_image_and_decache() to set the F_UNCACHEABLE flag *as well* as F_INVALID. I hope that's the correct fix. raster? SVN revision: 3238
This commit is contained in:
parent
54599eddb6
commit
5303cd3cf1
|
@ -492,6 +492,7 @@ imlib_free_image_and_decache(void)
|
|||
CHECK_PARAM_POINTER("imlib_free_image_and_decache", "image", ctxt_image);
|
||||
CAST_IMAGE(im, ctxt_image);
|
||||
SET_FLAG(im->flags, F_INVALID);
|
||||
SET_FLAG(im->flags, F_UNCACHEABLE);
|
||||
__imlib_FreeImage(im);
|
||||
ctxt_image = NULL;
|
||||
}
|
||||
|
|
87
src/image.c
87
src/image.c
|
@ -311,8 +311,7 @@ __imlib_CleanupImageCache(void)
|
|||
{
|
||||
im_last = im;
|
||||
im = im->next;
|
||||
if ((im_last->references <= 0) &&
|
||||
(!(IMAGE_IS_VALID(im_last))))
|
||||
if ((im_last->references <= 0) && (!(IMAGE_IS_VALID(im_last))))
|
||||
{
|
||||
__imlib_RemoveImageFromCache(im_last);
|
||||
__imlib_ConsumeImage(im_last);
|
||||
|
@ -361,7 +360,8 @@ void
|
|||
__imlib_ConsumeImagePixmap(ImlibImagePixmap * ip)
|
||||
{
|
||||
#ifdef DEBUG_CACHE
|
||||
fprintf(stderr, "[Imlib2] Deleting pixmap. Reference count is %d, pixmap 0x%08x, mask 0x%08x\n",
|
||||
fprintf(stderr,
|
||||
"[Imlib2] Deleting pixmap. Reference count is %d, pixmap 0x%08x, mask 0x%08x\n",
|
||||
ip->references, ip->pixmap, ip->mask);
|
||||
#endif
|
||||
if (ip->pixmap)
|
||||
|
@ -372,10 +372,10 @@ __imlib_ConsumeImagePixmap(ImlibImagePixmap *ip)
|
|||
}
|
||||
|
||||
ImlibImagePixmap *
|
||||
__imlib_FindCachedImagePixmap(ImlibImage *im, int w, int h, Display *d, Visual *v,
|
||||
int depth, int sx, int sy, int sw, int sh, Colormap cm,
|
||||
char aa, char hiq, char dmask,
|
||||
DATABIG modification_count)
|
||||
__imlib_FindCachedImagePixmap(ImlibImage * im, int w, int h, Display * d,
|
||||
Visual * v, int depth, int sx, int sy, int sw,
|
||||
int sh, Colormap cm, char aa, char hiq,
|
||||
char dmask, DATABIG modification_count)
|
||||
{
|
||||
ImlibImagePixmap *ip, *previous_ip;
|
||||
|
||||
|
@ -385,19 +385,17 @@ __imlib_FindCachedImagePixmap(ImlibImage *im, int w, int h, Display *d, Visual *
|
|||
while (ip)
|
||||
{
|
||||
/* if all the pixmap attributes match */
|
||||
if ((ip->w == w) && (ip->h == h) && (ip->depth == depth) &&
|
||||
(!ip->dirty) && (ip->image == im) &&
|
||||
(ip->visual == v) && (ip->display == d) &&
|
||||
(ip->source_x == sx) && (ip->source_x == sy) &&
|
||||
(ip->source_w == sw) && (ip->source_h == sh) &&
|
||||
(ip->colormap == cm) && (ip->antialias == aa) &&
|
||||
(ip->modification_count == modification_count) &&
|
||||
(ip->dither_mask == dmask) &&
|
||||
(ip->border.left == im->border.left) &&
|
||||
(ip->border.right == im->border.right) &&
|
||||
(ip->border.top == im->border.top) &&
|
||||
(ip->border.bottom == im->border.bottom)
|
||||
)
|
||||
if ((ip->w == w) && (ip->h == h) && (ip->depth == depth) && (!ip->dirty)
|
||||
&& (ip->image == im) && (ip->visual == v) && (ip->display == d)
|
||||
&& (ip->source_x == sx) && (ip->source_x == sy)
|
||||
&& (ip->source_w == sw) && (ip->source_h == sh)
|
||||
&& (ip->colormap == cm) && (ip->antialias == aa)
|
||||
&& (ip->modification_count == modification_count)
|
||||
&& (ip->dither_mask == dmask)
|
||||
&& (ip->border.left == im->border.left)
|
||||
&& (ip->border.right == im->border.right)
|
||||
&& (ip->border.top == im->border.top)
|
||||
&& (ip->border.bottom == im->border.bottom))
|
||||
{
|
||||
/* move the pixmap to the head of the pixmap list */
|
||||
if (previous_ip)
|
||||
|
@ -478,8 +476,7 @@ __imlib_CleanupImagePixmapCache(void)
|
|||
{
|
||||
ip_last = ip;
|
||||
ip = ip->next;
|
||||
if ((ip_last->references <= 0) &&
|
||||
(ip_last->dirty))
|
||||
if ((ip_last->references <= 0) && (ip_last->dirty))
|
||||
{
|
||||
__imlib_RemoveImagePixmapFromCache(ip_last);
|
||||
__imlib_ConsumeImagePixmap(ip_last);
|
||||
|
@ -528,6 +525,7 @@ LTDL_Init(void)
|
|||
if (errors != 0)
|
||||
{
|
||||
const char *dlerror = lt_dlerror();
|
||||
|
||||
fprintf(stderr, "ERROR: failed to initialise ltdl: %s\n", dlerror);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -594,6 +592,7 @@ __imlib_ListLoaders(int *num_ret)
|
|||
/* make a list of them */
|
||||
*num_ret += num;
|
||||
list = malloc(sizeof(char *) * *num_ret);
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
sprintf(s, "%s/" USER_LOADERS_PATH "/image/%s", home, l[i]);
|
||||
|
@ -609,6 +608,7 @@ __imlib_ListLoaders(int *num_ret)
|
|||
{
|
||||
*num_ret += num;
|
||||
list = realloc(list, sizeof(char *) * *num_ret);
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
sprintf(s, SYS_LOADERS_PATH "/image/%s", l[i]);
|
||||
|
@ -627,11 +627,13 @@ __imlib_ListLoaders(int *num_ret)
|
|||
return list;
|
||||
}
|
||||
|
||||
char **__imlib_TrimLoaderList(char **list, int *num)
|
||||
char **
|
||||
__imlib_TrimLoaderList(char **list, int *num)
|
||||
{
|
||||
int i, n, size = 0;
|
||||
|
||||
char **ret = NULL;
|
||||
|
||||
if (!list)
|
||||
return NULL;
|
||||
if (*num == 0)
|
||||
|
@ -642,6 +644,7 @@ char **__imlib_TrimLoaderList(char **list, int *num)
|
|||
for (i = 0; i < n; i++)
|
||||
{
|
||||
char *ext;
|
||||
|
||||
if (!list[i])
|
||||
continue;
|
||||
ext = strrchr(list[i], '.');
|
||||
|
@ -652,6 +655,7 @@ char **__imlib_TrimLoaderList(char **list, int *num)
|
|||
if (!__imlib_ItemInList(ret, size, list[i]))
|
||||
{
|
||||
ret = realloc(ret, sizeof(char *) * (size + 1));
|
||||
|
||||
ret[size++] = strdup(list[i]);
|
||||
}
|
||||
}
|
||||
|
@ -664,9 +668,11 @@ char **__imlib_TrimLoaderList(char **list, int *num)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int __imlib_ItemInList(char **list, int size, char *item)
|
||||
int
|
||||
__imlib_ItemInList(char **list, int size, char *item)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!size)
|
||||
return 0;
|
||||
if (!list)
|
||||
|
@ -726,7 +732,8 @@ __imlib_RescanLoaders(void)
|
|||
#ifndef __EMX__
|
||||
current_time = __imlib_FileModDate(SYS_LOADERS_PATH "/image/");
|
||||
#else
|
||||
current_time = __imlib_FileModDate(__XOS2RedirRoot(SYS_LOADERS_PATH "/image/"));
|
||||
current_time =
|
||||
__imlib_FileModDate(__XOS2RedirRoot(SYS_LOADERS_PATH "/image/"));
|
||||
#endif
|
||||
if (current_time > last_modified_system_time)
|
||||
{
|
||||
|
@ -822,7 +829,8 @@ __imlib_FindBestLoaderForFile(const char *file)
|
|||
*lower = tolower(*lower);
|
||||
lower++;
|
||||
}
|
||||
if (!extension) return NULL;
|
||||
if (!extension)
|
||||
return NULL;
|
||||
/* go through the loaders - first loader that claims to handle that */
|
||||
/* image type (extension wise) wins as a first guess to use - NOTE */
|
||||
/* this is an OPTIMISATION - it is possible the file has no extension */
|
||||
|
@ -883,7 +891,8 @@ __imlib_FindBestLoaderForFileFormat(const char *file, char *format)
|
|||
lower++;
|
||||
}
|
||||
}
|
||||
if (!extension) return NULL;
|
||||
if (!extension)
|
||||
return NULL;
|
||||
/* look thought the loaders one by one to see if one matches that format */
|
||||
l = loaders;
|
||||
while (l)
|
||||
|
@ -937,10 +946,9 @@ __imlib_CreateImage(int w, int h, DATA32 *data)
|
|||
}
|
||||
|
||||
ImlibImage *
|
||||
__imlib_LoadImage(const char *file,
|
||||
ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load, char dont_cache,
|
||||
ImlibLoadError *er)
|
||||
__imlib_LoadImage(const char *file, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load,
|
||||
char dont_cache, ImlibLoadError * er)
|
||||
{
|
||||
ImlibImage *im;
|
||||
ImlibLoader *best_loader;
|
||||
|
@ -989,7 +997,9 @@ __imlib_LoadImage(const char *file,
|
|||
best_loader = __imlib_FindBestLoaderForFile(file);
|
||||
errno = 0;
|
||||
if (best_loader)
|
||||
loader_ret = best_loader->load(im, progress, progress_granularity, immediate_load);
|
||||
loader_ret =
|
||||
best_loader->load(im, progress, progress_granularity,
|
||||
immediate_load);
|
||||
/* if the caller wants error returns */
|
||||
if (er)
|
||||
{
|
||||
|
@ -1032,13 +1042,15 @@ __imlib_LoadImage(const char *file,
|
|||
if (im->w == 0)
|
||||
{
|
||||
ImlibLoader *l, *previous_l = NULL;
|
||||
|
||||
l = loaders;
|
||||
/* run through all loaders and try load until one succeeds */
|
||||
while ((l) && (im->w == 0))
|
||||
{
|
||||
/* if its not the best loader that alreayd failed - try load */
|
||||
if (l != best_loader)
|
||||
loader_ret = l->load(im, progress, progress_granularity, immediate_load);
|
||||
loader_ret =
|
||||
l->load(im, progress, progress_granularity, immediate_load);
|
||||
/* if it failed - advance */
|
||||
if (im->w == 0)
|
||||
{
|
||||
|
@ -1132,7 +1144,8 @@ __imlib_FindImlibImagePixmapByID(Display *d, Pixmap p)
|
|||
if ((ip->pixmap == p) && (ip->display == d))
|
||||
{
|
||||
#ifdef DEBUG_CACHE
|
||||
fprintf(stderr, "[Imlib2] Match found. Reference count is %d, pixmap 0x%08x, mask 0x%08x\n",
|
||||
fprintf(stderr,
|
||||
"[Imlib2] Match found. Reference count is %d, pixmap 0x%08x, mask 0x%08x\n",
|
||||
ip->references, ip->pixmap, ip->mask);
|
||||
#endif
|
||||
return ip;
|
||||
|
@ -1181,7 +1194,8 @@ __imlib_FreePixmap(Display *d, Pixmap p)
|
|||
/* dereference it by one */
|
||||
ip->references--;
|
||||
#ifdef DEBUG_CACHE
|
||||
fprintf(stderr, "[Imlib2] Reference count is now %d for pixmap 0x%08x\n",
|
||||
fprintf(stderr,
|
||||
"[Imlib2] Reference count is now %d for pixmap 0x%08x\n",
|
||||
ip->references, ip->pixmap);
|
||||
#endif
|
||||
/* if it becaume 0 reference count - clean the cache up */
|
||||
|
@ -1229,8 +1243,7 @@ __imlib_DirtyImage(ImlibImage *im)
|
|||
|
||||
void
|
||||
__imlib_SaveImage(ImlibImage * im, const char *file,
|
||||
ImlibProgressFunction progress,
|
||||
char progress_granularity,
|
||||
ImlibProgressFunction progress, char progress_granularity,
|
||||
ImlibLoadError * er)
|
||||
{
|
||||
ImlibLoader *l;
|
||||
|
|
Loading…
Reference in New Issue