Mercurial > hg > octave-nkf
changeset 20616:5b8e4f668c53
Add compression option to imwrite and default to "none" (bug #45565)
* libinterp/dldfcn/__magick_read__.cc: we did not specify compression type
and let it up to GM coder. However, Matlab users seem to be expect it to
be uncompressed since Matlab only does that (except for jpeg). So we
add the compression method and apply to the images being writen.
* scripts/image/imwrite.m: document new option and add tests (bug was about
bmp and type compression is defined at offset byte 30)
* scripts/image/private/__imwrite__.m: parse new compression option.
author | Carnë Draug <carandraug@octave.org> |
---|---|
date | Tue, 28 Jul 2015 17:43:23 +0100 |
parents | e3f84a8c6788 |
children | 4bde15a9c8bb |
files | libinterp/dldfcn/__magick_read__.cc scripts/image/imwrite.m scripts/image/private/__imwrite__.m |
diffstat | 3 files changed, 67 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/dldfcn/__magick_read__.cc +++ b/libinterp/dldfcn/__magick_read__.cc @@ -1551,6 +1551,23 @@ // Note that this only needs to be set on the first frame imvec[0].animationIterations (options.getfield ("loopcount").uint_value ()); + const std::string compression = options.getfield ("compression").string_value (); +#define COMPRESS_MAGICK_IMAGE_VECTOR(COMPRESSION_STRING, GM_TYPE) \ + if (compression == COMPRESSION_STRING) \ + for (std::vector<Magick::Image>::size_type i = 0; i < imvec.size (); i++) \ + imvec[i].compressType (GM_TYPE); + + COMPRESS_MAGICK_IMAGE_VECTOR("none", Magick::NoCompression) + else COMPRESS_MAGICK_IMAGE_VECTOR("bzip", Magick::BZipCompression) + else COMPRESS_MAGICK_IMAGE_VECTOR("fax3", Magick::FaxCompression) + else COMPRESS_MAGICK_IMAGE_VECTOR("fax4", Magick::Group4Compression) + else COMPRESS_MAGICK_IMAGE_VECTOR("jpeg", Magick::JPEGCompression) + else COMPRESS_MAGICK_IMAGE_VECTOR("lzw", Magick::LZWCompression) + else COMPRESS_MAGICK_IMAGE_VECTOR("rle", Magick::RLECompression) + else COMPRESS_MAGICK_IMAGE_VECTOR("deflate", Magick::ZipCompression) + +#undef COMPRESS_MAGICK_IMAGE_VECTOR + write_file (filename, ext, imvec); if (error_state) return retval;
--- a/scripts/image/imwrite.m +++ b/scripts/image/imwrite.m @@ -46,6 +46,12 @@ ## multipage image, the size of the 4th dimension must also match and the third ## dimension must be a singleton. By default, image will be completely opaque. ## +## @item Compression +## Compression to use one the image. Can be one of the following: "none" +## (default), "bzip", "fax3", "fax4", "jpeg", "lzw", "rle", or "deflate". +## Note that not all compression types are available for all image formats +## in which it defaults to your Magick library. +## ## @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 @@ -200,3 +206,32 @@ %! [g] = write_and_read (".jpeg", gray, "quality", 100); %! assert (g, gray) +%!function [compression] = get_bmp_compression (ext, cmap = [], varargin) +%! gray = repmat (uint8 (0:255), 100, 1); +%! filename = [tempname() ext]; +%! unwind_protect +%! if (isempty (cmap)) +%! imwrite (gray, filename, varargin{1:end}); +%! else +%! imwrite (gray, cmap, filename, varargin{1:end}); +%! endif +%! fid = fopen (filename); +%! unwind_protect +%! compression = fread (fid, 31)(end); +%! unwind_protect_cleanup +%! fclose (fid); +%! end_unwind_protect +%! unwind_protect_cleanup +%! unlink (filename); +%! end_unwind_protect +%!endfunction + +## BMP images must be saved uncompressed by default (bug #45565) +%!testif HAVE_MAGICK +%! assert (get_bmp_compression ("", [], "BMP"), 0) +%! assert (get_bmp_compression ("", [], "bmp"), 0) +%! assert (get_bmp_compression (".BMP"), 0) +%! assert (get_bmp_compression (".bmp"), 0) +%! assert (get_bmp_compression (".bmp", [], "bmp"), 0) +%! assert (get_bmp_compression ("", gray (256), "bmp"), 0) +%! assert (get_bmp_compression (".bmp", gray (256), "Compression", "rle"), 1)
--- a/scripts/image/private/__imwrite__.m +++ b/scripts/image/private/__imwrite__.m @@ -46,7 +46,8 @@ "quality", 75, "delaytime", ones (1, size (img, 4)) *500, # 0.5 seconds "loopcount", 0, ## this is actually Inf - "alpha", cast ([], class (img))); + "alpha", cast ([], class (img)), + "compression", "none"); for idx = 1:2:numel (param_list) @@ -67,6 +68,19 @@ param_list{idx}); endif + case "compression" + options.compression = param_list{idx+1}; + if (! ischar (options.compression)) + error ("imwrite: value for %s option must be a string", + param_list{idx}); + endif + options.compression = tolower (options.compression); + if (! any (strcmp (options.compression, {"none", "bzip", "fax3", ... + "fax4", "jpeg", "lzw", ... + "rle", "deflate"}))) + error ("imwrite: invalid compression `%s'", options.compression); + endif + case "delaytime" options.delaytime = param_list{idx+1}; if (! isnumeric (options.delaytime))