forked from old/legacy-imlib2
image.c: Add infrastructure to simplify progress handling
This commit is contained in:
parent
9f479126f9
commit
87c84278ec
113
src/lib/image.c
113
src/lib/image.c
|
@ -15,6 +15,14 @@
|
|||
#include "file.h"
|
||||
#include "image.h"
|
||||
|
||||
/* Imlib loader context */
|
||||
struct _imlibldctx {
|
||||
ImlibProgressFunction progress;
|
||||
char granularity;
|
||||
int pct, area, row;
|
||||
int pass, n_pass;
|
||||
};
|
||||
|
||||
static ImlibImage *images = NULL;
|
||||
|
||||
#ifdef BUILD_X11
|
||||
|
@ -534,14 +542,15 @@ __imlib_CreateImage(int w, int h, DATA32 * data)
|
|||
}
|
||||
|
||||
static int
|
||||
__imlib_LoadImageWrapper(const ImlibLoader * l, ImlibImage * im,
|
||||
ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load)
|
||||
__imlib_LoadImageWrapper(const ImlibLoader * l, ImlibImage * im, int load_data)
|
||||
{
|
||||
int rc;
|
||||
|
||||
immediate_load = immediate_load || progress || im->loader;
|
||||
rc = l->load(im, progress, progress_granularity, immediate_load);
|
||||
if (im->lc)
|
||||
rc = l->load(im, im->lc->progress, im->lc->granularity, 1);
|
||||
else
|
||||
rc = l->load(im, NULL, 0, load_data);
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
/* Failed - clean up */
|
||||
|
@ -568,6 +577,19 @@ __imlib_LoadImageWrapper(const ImlibLoader * l, ImlibImage * im,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static void
|
||||
__imlib_LoadCtxInit(ImlibImage * im, ImlibLdCtx * lc,
|
||||
ImlibProgressFunction prog, int gran)
|
||||
{
|
||||
im->lc = lc;
|
||||
lc->progress = prog;
|
||||
lc->granularity = gran;
|
||||
lc->pct = lc->row = 0;
|
||||
lc->area = 0;
|
||||
lc->pass = 0;
|
||||
lc->n_pass = 1;
|
||||
}
|
||||
|
||||
ImlibImage *
|
||||
__imlib_LoadImage(const char *file, ImlibProgressFunction progress,
|
||||
char progress_granularity, char immediate_load,
|
||||
|
@ -576,6 +598,7 @@ __imlib_LoadImage(const char *file, ImlibProgressFunction progress,
|
|||
ImlibImage *im;
|
||||
ImlibLoader *best_loader;
|
||||
int loader_ret;
|
||||
ImlibLdCtx ilc;
|
||||
|
||||
if (!file || file[0] == '\0')
|
||||
return NULL;
|
||||
|
@ -634,6 +657,9 @@ __imlib_LoadImage(const char *file, ImlibProgressFunction progress,
|
|||
|
||||
im->data_memory_func = imlib_context_get_image_data_memory_function();
|
||||
|
||||
if (progress)
|
||||
__imlib_LoadCtxInit(im, &ilc, progress, progress_granularity);
|
||||
|
||||
/* ok - just check all our loaders are up to date */
|
||||
__imlib_RescanLoaders();
|
||||
|
||||
|
@ -643,10 +669,7 @@ __imlib_LoadImage(const char *file, ImlibProgressFunction progress,
|
|||
best_loader = __imlib_FindBestLoaderForFile(im->real_file, 0);
|
||||
errno = 0;
|
||||
if (best_loader)
|
||||
loader_ret =
|
||||
__imlib_LoadImageWrapper(best_loader, im,
|
||||
progress, progress_granularity,
|
||||
immediate_load);
|
||||
loader_ret = __imlib_LoadImageWrapper(best_loader, im, immediate_load);
|
||||
|
||||
if (loader_ret > 0)
|
||||
{
|
||||
|
@ -664,10 +687,7 @@ __imlib_LoadImage(const char *file, ImlibProgressFunction progress,
|
|||
/* if its not the best loader that already failed - try load */
|
||||
if (l == best_loader)
|
||||
continue;
|
||||
loader_ret =
|
||||
__imlib_LoadImageWrapper(l, im,
|
||||
progress, progress_granularity,
|
||||
immediate_load);
|
||||
loader_ret = __imlib_LoadImageWrapper(l, im, immediate_load);
|
||||
if (loader_ret > 0)
|
||||
break;
|
||||
}
|
||||
|
@ -687,6 +707,8 @@ __imlib_LoadImage(const char *file, ImlibProgressFunction progress,
|
|||
}
|
||||
}
|
||||
|
||||
im->lc = NULL;
|
||||
|
||||
/* all loaders have been tried and they all failed. free the skeleton */
|
||||
/* image struct we had and return NULL */
|
||||
if (loader_ret <= 0)
|
||||
|
@ -707,6 +729,7 @@ __imlib_LoadImage(const char *file, ImlibProgressFunction progress,
|
|||
__imlib_AddImageToCache(im);
|
||||
else
|
||||
SET_FLAG(im->flags, F_UNCACHEABLE);
|
||||
|
||||
return im;
|
||||
}
|
||||
|
||||
|
@ -714,11 +737,67 @@ int
|
|||
__imlib_LoadImageData(ImlibImage * im)
|
||||
{
|
||||
if ((!(im->data)) && (im->loader) && (im->loader->load))
|
||||
if (__imlib_LoadImageWrapper(im->loader, im, NULL, 0, 1) == 0)
|
||||
if (__imlib_LoadImageWrapper(im->loader, im, 1) == 0)
|
||||
return 1; /* Load failed */
|
||||
return im->data == NULL;
|
||||
}
|
||||
|
||||
__EXPORT__ void
|
||||
__imlib_LoadProgressSetPass(ImlibImage * im, int pass, int n_pass)
|
||||
{
|
||||
im->lc->pass = pass;
|
||||
im->lc->n_pass = n_pass;
|
||||
|
||||
im->lc->row = 0;
|
||||
}
|
||||
|
||||
__EXPORT__ int
|
||||
__imlib_LoadProgress(ImlibImage * im, int x, int y, int w, int h)
|
||||
{
|
||||
ImlibLdCtx *lc = im->lc;
|
||||
int rc;
|
||||
|
||||
lc->area += w * h;
|
||||
lc->pct = (100. * lc->area + .1) / (im->w * im->h);
|
||||
|
||||
rc = !lc->progress(im, lc->pct, x, y, w, h);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
__EXPORT__ int
|
||||
__imlib_LoadProgressRows(ImlibImage * im, int row, int nrows)
|
||||
{
|
||||
ImlibLdCtx *lc = im->lc;
|
||||
int rc = 0;
|
||||
int pct, nrtot;
|
||||
|
||||
if (nrows > 0)
|
||||
{
|
||||
/* Row index counting up */
|
||||
nrtot = row + nrows;
|
||||
row = lc->row;
|
||||
nrows = nrtot - lc->row;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Row index counting down */
|
||||
nrtot = im->h - row;
|
||||
row = row;
|
||||
nrows = nrtot - lc->row;
|
||||
}
|
||||
|
||||
pct = (100 * nrtot * (lc->pass + 1)) / (im->h * lc->n_pass);
|
||||
if (pct == 100 || pct >= lc->pct + lc->granularity)
|
||||
{
|
||||
rc = !lc->progress(im, pct, 0, row, im->w, nrows);
|
||||
lc->row = nrtot;
|
||||
lc->pct += lc->granularity;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef BUILD_X11
|
||||
/* find an imagepixmap cache entry by the display and pixmap id */
|
||||
ImlibImagePixmap *
|
||||
|
@ -840,6 +919,7 @@ __imlib_SaveImage(ImlibImage * im, const char *file,
|
|||
{
|
||||
ImlibLoader *l;
|
||||
char e, *pfile;
|
||||
ImlibLdCtx ilc;
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -861,6 +941,9 @@ __imlib_SaveImage(ImlibImage * im, const char *file,
|
|||
return;
|
||||
}
|
||||
|
||||
if (progress)
|
||||
__imlib_LoadCtxInit(im, &ilc, progress, progress_granularity);
|
||||
|
||||
/* set the filename to the user supplied one */
|
||||
pfile = im->real_file;
|
||||
im->real_file = strdup(file);
|
||||
|
@ -872,6 +955,8 @@ __imlib_SaveImage(ImlibImage * im, const char *file,
|
|||
free(im->real_file);
|
||||
im->real_file = pfile;
|
||||
|
||||
im->lc = NULL;
|
||||
|
||||
if (er)
|
||||
*er = __imlib_ErrorFromErrno(e > 0 ? 0 : errno, 1);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#endif
|
||||
|
||||
typedef struct _imlibimage ImlibImage;
|
||||
typedef struct _imlibldctx ImlibLdCtx;
|
||||
|
||||
#ifdef BUILD_X11
|
||||
typedef struct _imlibimagepixmap ImlibImagePixmap;
|
||||
|
@ -68,6 +69,7 @@ struct _imlibimage {
|
|||
char *real_file;
|
||||
char *key;
|
||||
ImlibImageDataMemoryFunction data_memory_func;
|
||||
ImlibLdCtx *lc;
|
||||
};
|
||||
|
||||
#ifdef BUILD_X11
|
||||
|
@ -133,6 +135,13 @@ DATA32 *__imlib_AllocateData(ImlibImage * im);
|
|||
void __imlib_FreeData(ImlibImage * im);
|
||||
void __imlib_ReplaceData(ImlibImage * im, DATA32 * new_data);
|
||||
|
||||
void __imlib_LoadProgressSetPass(ImlibImage * im,
|
||||
int pass, int n_pass);
|
||||
int __imlib_LoadProgress(ImlibImage * im,
|
||||
int x, int y, int w, int h);
|
||||
int __imlib_LoadProgressRows(ImlibImage * im,
|
||||
int row, int nrows);
|
||||
|
||||
#ifdef BUILD_X11
|
||||
ImlibImagePixmap *__imlib_ProduceImagePixmap(void);
|
||||
void __imlib_ConsumeImagePixmap(ImlibImagePixmap * ip);
|
||||
|
|
Loading…
Reference in New Issue