kwo pushed a commit to branch master.

http://git.enlightenment.org/legacy/imlib2.git/commit/?id=87c84278ec4cf293b7904c0b1765a8b4e8f8a9db

commit 87c84278ec4cf293b7904c0b1765a8b4e8f8a9db
Author: Kim Woelders <[email protected]>
Date:   Sat Nov 30 16:19:25 2019 +0100

    image.c: Add infrastructure to simplify progress handling
---
 src/lib/image.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 src/lib/image.h |   9 +++++
 2 files changed, 108 insertions(+), 14 deletions(-)

diff --git a/src/lib/image.c b/src/lib/image.c
index 2c1a61a..0b2b1a5 100644
--- a/src/lib/image.c
+++ b/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);
 }
diff --git a/src/lib/image.h b/src/lib/image.h
index a6baf5a..2accc16 100644
--- a/src/lib/image.h
+++ b/src/lib/image.h
@@ -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);

-- 


Reply via email to