# HG changeset patch # User Carnë Draug # Date 1383627911 0 # Node ID aacb9da13df63c5e7291df98b042d031d41d3511 # Parent 4de2eeb7d790adb3953b70cd74584e2e4dc99d9f imwrite: implement LoopCount option. * __magick_read__.cc (F__magick_write__): set animationIterations() when writing an image to implement the LoopCount option. * private/__imwrite__.m: input check for the new option LoopCount and set its default. Also fix bug that was using varargin rather than the param/key cell to print error message on unknown option. * imwrite.m: document new option and its problems. diff -r 4de2eeb7d790 -r aacb9da13df6 libinterp/dldfcn/__magick_read__.cc --- a/libinterp/dldfcn/__magick_read__.cc Mon Jun 24 16:02:54 2013 -0500 +++ b/libinterp/dldfcn/__magick_read__.cc Tue Nov 05 05:05:11 2013 +0000 @@ -1408,6 +1408,32 @@ } } + // FIXME - LoopCount or animationIterations + // How it should work: + // + // This value is only set for the first image in the sequence. Trying + // to set this value with the append mode should have no effect, the + // value used with the first image is the one that counts (that would + // also be Matlab compatible). Thus, the right way to do this would be + // to have an else block on the condition above, and set this only + // when creating a new file. Since Matlab does not interpret a 4D + // matrix as sequence of images to write, its users need to use a for + // loop and set LoopCount only on the first iteration (it actually + // throws warnings otherwise) + // + // Why is this not done the right way: + // + // When GM saves a single image, it discards the value if there is only + // a single image and sets it to "no loop". Since our default is an + // infinite loop, if the user tries to do it the Matlab way (setting + // LoopCount only on the first image) that value will go nowhere. + // See https://sourceforge.net/p/graphicsmagick/bugs/248/ + // Because of this, we document to set LoopCount on every iteration + // (in Matlab will cause a lot of warnings), or pass a 4D matrix with + // all frames (won't work in Matlab at all). + // Note that this only needs to be set on the first frame + imvec[0].animationIterations (options.getfield ("loopcount").uint_value ()); + write_file (filename, ext, imvec); if (error_state) return retval; diff -r 4de2eeb7d790 -r aacb9da13df6 scripts/image/imwrite.m --- a/scripts/image/imwrite.m Mon Jun 24 16:02:54 2013 -0500 +++ b/scripts/image/imwrite.m Tue Nov 05 05:05:11 2013 +0000 @@ -47,6 +47,14 @@ ## dimension must be a singleton. By default, image will be completely ## opaque. ## +## @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 value of 0 or 1 that the sequence is played only once (loops zero times), +## while a value of 2 or above loops that number of times (looping twice means +## it plays the complete sequence 3 times). This option is ignored when there +## is only a single image at the end of writing the file. +## ## @item Quality ## Set the quality of the compression. The value should be an ## integer between 0 and 100, with larger values indicating higher visual diff -r 4de2eeb7d790 -r aacb9da13df6 scripts/image/private/__imwrite__.m --- a/scripts/image/private/__imwrite__.m Mon Jun 24 16:02:54 2013 -0500 +++ b/scripts/image/private/__imwrite__.m Tue Nov 05 05:05:11 2013 +0000 @@ -43,6 +43,7 @@ ## set default for options options = struct ("writemode", "overwrite", "quality", 75, + "loopcount", 0, ## this is actually Inf "alpha", cast ([], class (img))); for idx = 1:2:numel (param_list) @@ -82,8 +83,32 @@ endif options.quality = round (options.quality); + case "loopcount" + options.loopcount = param_list{idx+1}; + if (! isscalar (options.loopcount) || ! isnumeric (options.loopcount) + || (! isinf (options.loopcount) && (options.loopcount < 0 || + options.loopcount > 65535))) + error ("imwrite: value for %s must be Inf or between 0 and 65535", + param_list{idx}); + endif + ## Graphics Magick is a bit weird here. A value of 0 will be an + ## infinite loop, a value of 1, will really be no loop, while a + ## value of 2 or more will be that number of loops (checked + ## with GNOME image viewer). This means that there is no way + ## to make it loop only once. See + ## https://sourceforge.net/p/graphicsmagick/bugs/249/ + ## There is also the problem of setting this when there is only + ## a single frame. See + ## https://sourceforge.net/p/graphicsmagick/bugs/248/ + if (isinf (options.loopcount)) + options.loopcount = 0; + elseif (options.loopcount == 0 || options.loopcount == 1) + options.loopcount++; + endif + options.loopcount = floor (options.loopcount); + otherwise - error ("imwrite: invalid PARAMETER `%s'", varargin{idx}); + error ("imwrite: invalid PARAMETER `%s'", param_list{idx}); endswitch endfor