GNU bug report logs - #21714
25.0.50; image-metadata using Emacs --with-ns prevents *.gif animation.

Previous Next

Package: emacs;

Reported by: Keith David Bershatsky <esq <at> lawlist.com>

Date: Mon, 19 Oct 2015 16:30:04 UTC

Severity: normal

Tags: patch

Found in version 25.0.50

Done: Alan Third <alan <at> idiocy.org>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Alan Third <alan <at> idiocy.org>
To: Keith David Bershatsky <esq <at> lawlist.com>
Cc: 21714 <at> debbugs.gnu.org
Subject: bug#21714: [PATCH] Add multiframe image support to NS port (bug#21714)
Date: Sun, 13 Aug 2017 01:58:18 +0100
* src/nsimage.m (image_spec_value): New function.
(ns_load_image): Handle multiple frames.
(EmacsImage::getMetadata, EmacsImage::setFrame): New function.
* src/nsterm.h (EmacsImage::getMetadata, EmacsImage::setFrame): New
function prototypes.
---
 src/nsimage.m | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/nsterm.h  |  2 ++
 2 files changed, 81 insertions(+)

diff --git a/src/nsimage.m b/src/nsimage.m
index fb2322afc3..6717202199 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -70,12 +70,38 @@ Updated by Christian Limpach (chris <at> nice.ch)
   return [EmacsImage allocInitFromFile: file];
 }
 
+static Lisp_Object
+image_spec_value (Lisp_Object spec, Lisp_Object key, bool *found)
+{
+  Lisp_Object tail;
+
+  eassert (valid_image_p (spec));
+
+  for (tail = XCDR (spec);
+       CONSP (tail) && CONSP (XCDR (tail));
+       tail = XCDR (XCDR (tail)))
+    {
+      if (EQ (XCAR (tail), key))
+	{
+	  if (found)
+	    *found = 1;
+	  return XCAR (XCDR (tail));
+	}
+    }
+
+  if (found)
+    *found = 0;
+  return Qnil;
+}
+
 bool
 ns_load_image (struct frame *f, struct image *img,
                Lisp_Object spec_file, Lisp_Object spec_data)
 {
   EmacsImage *eImg = nil;
   NSSize size;
+  Lisp_Object lisp_index = image_spec_value (img->spec, QCindex, NULL);
+  unsigned int index = INTEGERP (lisp_index) ? XFASTINT (lisp_index) : 0;
 
   NSTRACE ("ns_load_image");
 
@@ -99,12 +125,20 @@ Updated by Christian Limpach (chris <at> nice.ch)
       return 0;
     }
 
+  if (index < 0 || ![eImg setFrame: index])
+    {
+      add_to_log ("Unable to set index %d for image %s", index, img->spec);
+      return 0;
+    }
+
   size = [eImg size];
   img->width = size.width;
   img->height = size.height;
 
   /* 4) set img->pixmap = emacsimage */
   img->pixmap = eImg;
+
+  img->lisp_data = [eImg getMetadata];
   return 1;
 }
 
@@ -435,4 +469,49 @@ - (NSColor *)stippleMask
   return stippleMask;
 }
 
+/* If the image has multiple frames, get a count of them and the
+   animation delay, if available. */
+- (Lisp_Object)getMetadata
+{
+  Lisp_Object metadata = Qnil;
+
+  for (NSImageRep * r in [self representations])
+    {
+      if ([r isKindOfClass:[NSBitmapImageRep class]])
+        {
+          NSBitmapImageRep * bm = (NSBitmapImageRep *)r;
+          int frames = [[bm valueForProperty: NSImageFrameCount] intValue];
+          float delay = [[bm valueForProperty: NSImageCurrentFrameDuration]
+                          floatValue];
+
+          if (frames > 1)
+            metadata = Fcons (Qcount, Fcons (make_number (frames), metadata));
+          if (delay > 0)
+            metadata = Fcons (Qdelay, Fcons (make_float (delay), metadata));
+          break;
+        }
+    }
+  return metadata;
+}
+
+/* Attempt to set the animation frame to be displayed. */
+- (BOOL)setFrame: (unsigned int) index
+{
+  for (NSImageRep * r in [self representations])
+    {
+      if ([r isKindOfClass:[NSBitmapImageRep class]])
+        {
+          NSBitmapImageRep * bm = (NSBitmapImageRep *)r;
+          if ([[bm valueForProperty: NSImageFrameCount] intValue] <= index)
+            continue;
+
+          [bm setProperty: NSImageCurrentFrame
+                withValue: [NSNumber numberWithUnsignedInt: index]];
+          return YES;
+        }
+    }
+
+  return NO;
+}
+
 @end
diff --git a/src/nsterm.h b/src/nsterm.h
index 0f1b36db7b..67c0d42ac1 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -668,6 +668,8 @@ typedef id instancetype;
               alpha:(unsigned char)a;
 - (void)setAlphaAtX: (int)x Y: (int)y to: (unsigned char)a;
 - (NSColor *)stippleMask;
+- (Lisp_Object)getMetadata;
+- (BOOL)setFrame: (unsigned int) index;
 @end
 
 
-- 

Animated gif support, and I expect it to handle tiff with multiple
layers, or whatever.

-- 
Alan Third




This bug report was last modified 7 years and 280 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.