kwo pushed a commit to branch master.

http://git.enlightenment.org/legacy/imlib2.git/commit/?id=1f883a721a4378e7fdf3d929539cc572e5868e05

commit 1f883a721a4378e7fdf3d929539cc572e5868e05
Author: Kim Woelders <[email protected]>
Date:   Thu Jan 13 17:18:15 2022 +0100

    Add dispose-to-previous frame handling
    
    Dispose to previous appears to be used often by apng's.
---
 src/bin/imlib2_view.c | 54 +++++++++++++++++++++++++++++++++++++++++++++------
 src/lib/Imlib2.h.in   |  7 ++++---
 src/lib/image.h       |  7 ++++---
 3 files changed, 56 insertions(+), 12 deletions(-)

diff --git a/src/bin/imlib2_view.c b/src/bin/imlib2_view.c
index abfdb90..84fb6f9 100644
--- a/src/bin/imlib2_view.c
+++ b/src/bin/imlib2_view.c
@@ -204,15 +204,54 @@ anim_update(Imlib_Image im, const rect_t * up_in, rect_t 
* up_out, int flags)
 {
    static const rect_t r_zero = { };
    static rect_t       r_prev = r_zero;
+   static Imlib_Image  im_prev = NULL;
+   Imlib_Image         im_save = NULL;
+
+   if (!im)
+     {
+        /* Cleanup */
+        if (im_prev)
+          {
+             imlib_context_set_image(im_prev);
+             imlib_free_image_and_decache();
+             im_prev = NULL;
+          }
+        return;
+     }
 
    imlib_context_set_image(fg_im);
 
+   if (flags & IMLIB_FRAME_DISPOSE_PREV)
+     {
+        Dprintf("Save  %d,%d %dx%d\n", up_in->x, up_in->y, up_in->w, up_in->h);
+        im_save =
+           imlib_create_cropped_image(up_in->x, up_in->y, up_in->w, up_in->h);
+     }
+
    if (r_prev.w > 0)
      {
         /* "dispose" of (clear) previous area before rendering new */
-        Dprintf("Clear %d,%d %dx%d\n", r_prev.x, r_prev.y, r_prev.w, r_prev.h);
-        imlib_context_set_color(0, 0, 0, 0);
-        imlib_image_fill_rectangle(r_prev.x, r_prev.y, r_prev.w, r_prev.h);
+        if (im_prev)
+          {
+             Dprintf("Prev  %d,%d %dx%d\n",
+                     r_prev.x, r_prev.y, r_prev.w, r_prev.h);
+             imlib_context_set_blend(0);
+             imlib_blend_image_onto_image(im_prev, 1,
+                                          0, 0, r_prev.w, r_prev.h,
+                                          r_prev.x, r_prev.y,
+                                          r_prev.w, r_prev.h);
+             imlib_context_set_image(im_prev);
+             imlib_free_image_and_decache();
+             imlib_context_set_image(fg_im);
+             im_prev = NULL;
+          }
+        else
+          {
+             Dprintf("Clear %d,%d %dx%d\n",
+                     r_prev.x, r_prev.y, r_prev.w, r_prev.h);
+             imlib_context_set_color(0, 0, 0, 0);
+             imlib_image_fill_rectangle(r_prev.x, r_prev.y, r_prev.w, 
r_prev.h);
+          }
 
         /* Damaged area is (cleared + new frame) */
         up_out->x = MIN(r_prev.x, up_in->x);
@@ -224,9 +263,10 @@ anim_update(Imlib_Image im, const rect_t * up_in, rect_t * 
up_out, int flags)
      {
         *up_out = *up_in;
      }
+   im_prev = im_save;
 
-   if (flags & IMLIB_FRAME_DISPOSE_CLEAR)
-      r_prev = *up_in;          /* Clear next time around */
+   if (flags & (IMLIB_FRAME_DISPOSE_CLEAR | IMLIB_FRAME_DISPOSE_PREV))
+      r_prev = *up_in;          /* Clear/revert next time around */
    else
       r_prev = r_zero;          /* No clearing before next frame */
 
@@ -345,7 +385,7 @@ progress(Imlib_Image im, char percent, int update_x, int 
update_y,
 
    if (animated)
      {
-        rect_t              r_dam;
+        rect_t              r_dam = { };
 
         /* Update animated "target" canvas image (fg_im) */
         anim_update(im, &r_up, &r_dam, finfo.frame_flags);
@@ -434,6 +474,8 @@ load_image(int no, const char *name)
 
    Vprintf("Show  %d: '%s'\n", no, name);
 
+   anim_update(NULL, NULL, NULL, 0);    /* Clean up previous animation */
+
    image_width = 0;             /* Force redraw in progress() */
 
    draw = strtoul(name, &ptr, 0);
diff --git a/src/lib/Imlib2.h.in b/src/lib/Imlib2.h.in
index 0e465c5..7783a61 100644
--- a/src/lib/Imlib2.h.in
+++ b/src/lib/Imlib2.h.in
@@ -615,9 +615,10 @@ typedef struct {
 } Imlib_Frame_Info;
 
 /* frame info flags */
-#define IMLIB_IMAGE_ANIMATED      (1 << 0)      /* Frames are an animated 
sequence   */
-#define IMLIB_FRAME_DISPOSE_CLEAR (1 << 1)      /* Clear before rendering next 
frame */
-#define IMLIB_FRAME_BLEND         (1 << 2)      /* Blend current onto previous 
frame */
+#define IMLIB_IMAGE_ANIMATED      (1 << 0)      /* Frames are an animated 
sequence    */
+#define IMLIB_FRAME_BLEND         (1 << 1)      /* Blend current onto previous 
frame  */
+#define IMLIB_FRAME_DISPOSE_CLEAR (1 << 2)      /* Clear before rendering next 
frame  */
+#define IMLIB_FRAME_DISPOSE_PREV  (1 << 3)      /* Revert before rendering 
next frame */
 
 EAPI Imlib_Image    imlib_load_image_frame(const char *file, int frame);
 EAPI void           imlib_image_get_frame_info(Imlib_Frame_Info * info);
diff --git a/src/lib/image.h b/src/lib/image.h
index daaac57..393c37b 100644
--- a/src/lib/image.h
+++ b/src/lib/image.h
@@ -30,9 +30,10 @@ enum _iflags {
 typedef enum _iflags ImlibImageFlags;
 
 /* Must match the ones in Imlib2.h.in */
-#define FF_IMAGE_ANIMATED       (1 << 0)        /* Frames are an animated 
sequence   */
-#define FF_FRAME_DISPOSE_CLEAR  (1 << 1)        /* Clear before rendering next 
frame */
-#define FF_FRAME_BLEND          (1 << 2)        /* Blend current onto previous 
frame */
+#define FF_IMAGE_ANIMATED       (1 << 0)        /* Frames are an animated 
sequence    */
+#define FF_FRAME_BLEND          (1 << 1)        /* Blend current onto previous 
frame  */
+#define FF_FRAME_DISPOSE_CLEAR  (1 << 2)        /* Clear before rendering next 
frame  */
+#define FF_FRAME_DISPOSE_PREV   (1 << 3)        /* Revert before rendering 
next frame */
 
 typedef struct {
    int                 left, right, top, bottom;

-- 


Reply via email to