changeset 17854:adb0ba0d0c13

imwrite: implement DelayTime option. * __magick_read__.cc (F__magick_write__): set animationDelay() when writing an image to implement the DelayTime option. * private/__imwrite__.m: input check for the new option DelayTime and set its default. Organize options in alphabetic order. * imwrite.m: document new option.
author Carnë Draug <carandraug@octave.org>
date Tue, 05 Nov 2013 05:48:56 +0000
parents aacb9da13df6
children bfbe5dcc9943
files libinterp/dldfcn/__magick_read__.cc scripts/image/imwrite.m scripts/image/private/__imwrite__.m
diffstat 3 files changed, 43 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/dldfcn/__magick_read__.cc	Tue Nov 05 05:05:11 2013 +0000
+++ b/libinterp/dldfcn/__magick_read__.cc	Tue Nov 05 05:48:56 2013 +0000
@@ -1387,11 +1387,14 @@
 
   const octave_idx_type nFrames = imvec.size ();
 
-  // FIXME What happens when we try to set with formats that do not support it?
   const octave_idx_type quality = options.getfield ("quality").int_value ();
   for (octave_idx_type i = 0; i < nFrames; i++)
     imvec[i].quality (quality);
 
+  const ColumnVector delaytime = options.getfield ("delaytime").column_vector_value ();
+  for (octave_idx_type i = 0; i < nFrames; i++)
+    imvec[i].animationDelay (delaytime(i));
+
   // If writemode is set to append, read the image and append to it. Even
   // if set to append, make sure that something was read at all.
   const std::string writemode = options.getfield ("writemode").string_value ();
--- a/scripts/image/imwrite.m	Tue Nov 05 05:05:11 2013 +0000
+++ b/scripts/image/imwrite.m	Tue Nov 05 05:48:56 2013 +0000
@@ -47,6 +47,13 @@
 ## dimension must be a singleton.  By default, image will be completely
 ## opaque.
 ##
+## @item DelayTime
+## For formats that accept animations (such as GIF), controls for how long a
+## frame is displayed until it moves to the next one. The value must be scalar
+## (which will applied to all frames in @var{img}), or a vector of length
+## equal to the number of frames in @var{im}.  The value is in seconds, must
+## be between 0 and 655.35, and defaults to 0.5.
+##
 ## @item LoopCount
 ## For formats that accept animations (such as GIF), controls how many times
 ## the sequence is repeated.  A value of Inf means an infinite loop (default),
--- a/scripts/image/private/__imwrite__.m	Tue Nov 05 05:05:11 2013 +0000
+++ b/scripts/image/private/__imwrite__.m	Tue Nov 05 05:48:56 2013 +0000
@@ -43,6 +43,7 @@
   ## set default for options
   options = struct ("writemode", "overwrite",
                     "quality",   75,
+                    "delaytime", ones (1, size (img, 4)) *500, # 0.5 seconds
                     "loopcount", 0, ## this is actually Inf
                     "alpha",     cast ([], class (img)));
 
@@ -65,23 +66,23 @@
                  param_list{idx});
         endif
 
-      case "writemode",
-        options.writemode = param_list{idx+1};
-        if (! ischar (options.writemode)
-            || ! any (strcmpi (options.writemode, {"append", "overwrite"})))
-          error ('imwrite: value for %s option must be "append" or "overwrite"',
+      case "delaytime"
+        options.delaytime = param_list{idx+1};
+        if (! isnumeric (options.delaytime))
+          error ("imwrite: value for %s option must be numeric",
                  param_list{idx});
         endif
-        options.writemode = tolower (options.writemode);
-
-      case "quality",
-        options.quality = param_list{idx+1};
-        if (! isnumeric (options.quality) || ! isscalar (options.quality)
-            || options.quality < 0 || options.quality > 100)
-          error ("imwrite: value for %s option must be a scalar between 0 and 100",
+        options.delaytime *= 100; # convert to 1/100ths of second
+        if (isscalar (options.delaytime))
+          options.delaytime(1:size (img, 4)) = options.delaytime;
+        elseif (size (img, 4) != numel (options.delaytime))
+          error ("imwrite: value for %s must either be a scalar or the number of frames",
                  param_list{idx});
         endif
-        options.quality = round (options.quality);
+        if (any (options.delaytime(:) < 0) || any (options.delaytime(:) > 65535))
+          error ("imwrite: value for %s must be between 0 and 655.35 seconds",
+                 param_list{idx});
+        endif
 
       case "loopcount"
         options.loopcount = param_list{idx+1};
@@ -107,6 +108,24 @@
         endif
         options.loopcount = floor (options.loopcount);
 
+      case "quality",
+        options.quality = param_list{idx+1};
+        if (! isnumeric (options.quality) || ! isscalar (options.quality)
+            || options.quality < 0 || options.quality > 100)
+          error ("imwrite: value for %s option must be a scalar between 0 and 100",
+                 param_list{idx});
+        endif
+        options.quality = round (options.quality);
+
+      case "writemode",
+        options.writemode = param_list{idx+1};
+        if (! ischar (options.writemode)
+            || ! any (strcmpi (options.writemode, {"append", "overwrite"})))
+          error ('imwrite: value for %s option must be "append" or "overwrite"',
+                 param_list{idx});
+        endif
+        options.writemode = tolower (options.writemode);
+
       otherwise
         error ("imwrite: invalid PARAMETER `%s'", param_list{idx});