1 ## Copyright (C) 2008-2012 John W. Eaton
3 ## This file is part of Octave.
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ## General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING. If not, see
17 ## <http://www.gnu.org/licenses/>.
20 ## @deftypefn {Function File} {} imwrite (@var{img}, @var{filename})
21 ## @deftypefnx {Function File} {} imwrite (@var{img}, @var{filename}, @var{fmt})
22 ## @deftypefnx {Function File} {} imwrite (@var{img}, @var{filename}, @var{fmt}, @var{p1}, @var{v1}, @dots{})
23 ## @deftypefnx {Function File} {} imwrite (@var{img}, @var{map}, @var{filename}, @dots{})
24 ## Write images in various file formats.
26 ## If @var{fmt} is not supplied, the file extension of @var{filename} is used
27 ## to determine the format.
29 ## The parameter-value pairs (@var{p1}, @var{v1}, @dots{}) are optional.
30 ## Currently the following options are supported for @t{JPEG} images:
34 ## Set the quality of the compression. The value should be an
35 ## integer between 0 and 100, with larger values indicating higher visual
36 ## quality and lower compression.
39 ## @strong{Supported Formats}
40 ## @multitable @columnfractions .33 .66
41 ## @headitem Extension @tab Format
42 ## @item bmp @tab Windows Bitmap
43 ## @item gif @tab Graphics Interchange Format
44 ## @item jpg and jpeg @tab Joint Photographic Experts Group
45 ## @item pbm @tab Portable Bitmap
47 ## @item pgm @tab Portable Graymap
48 ## @item png @tab Portable Network Graphics
49 ## @item pnm @tab Portable Anymap
50 ## @item ppm @tab Portable Pixmap
51 ## @item ras @tab Sun Raster
52 ## @item tif and tiff @tab Tagged Image File Format
53 ## @item xwd @tab X11 Dump
56 ## @strong{Unsupported Formats}
57 ## @multitable @columnfractions .33 .66
58 ## @headitem Extension @tab Format
59 ## @item hdf @tab Hierarchical Data Format V4
60 ## @item @nospell{jp2} and jpx @tab Joint Photographic Experts Group 2000
63 ## @seealso{imread, imfinfo}
66 function imwrite (img, varargin)
68 persistent imwrite_possible_formats = {
69 "bmp"; "gif"; "jp2"; "jpg"; "jpx"; "jpeg"; "hdf"; "pbm"; "pcx";
70 "pgm"; "png"; "pnm"; "ppm"; "ras"; "tif"; "tiff"; "xwd" };
72 persistent accepted_formats = __magick_format_list__ (imwrite_possible_formats);
74 if (nargin < 2 || ! (isnumeric (img) || islogical (img)))
82 if (isnumeric (varargin{1}))
85 error ("imwrite: colormap must not be empty");
89 if (offset <= length (varargin) && ischar (varargin{offset}))
90 filename = varargin{offset};
92 if (rem (length (varargin) - offset, 2) == 0 && ischar (varargin{offset}))
93 fmt = varargin{offset};
99 if (offset < length (varargin))
101 for ii = offset:2:(length (varargin) - 1)
102 options.(varargin{ii}) = varargin{ii + 1};
108 filename = tilde_expand (filename);
111 [d, n, fmt] = fileparts (filename);
118 error ("imwrite: invalid empty image");
121 if (issparse (img) || issparse (map))
122 error ("imwrite: sparse images not supported");
125 if (! strcmp (fmt, accepted_formats))
126 error ("imwrite: %s: unsupported or invalid image format", fmt);
129 img_class = class (img);
130 map_class = class (map);
134 if (any (strcmp (img_class, {"logical", "uint8", "uint16", "double"})))
135 if ((nd == 2 || nd == 3) && strcmp (img_class, "double"))
136 img = uint8 (img * 255);
138 ## FIXME -- should we handle color images w/ alpha channel here?
139 if (nd == 3 && size (img, 3) < 3)
140 error ("imwrite: invalid dimensions for truecolor image");
143 error ("imwrite: invalid %d-dimensional image data", nd);
146 error ("imwrite: %s: invalid class for truecolor image", img_class);
149 __magick_write__ (filename, fmt, img, options);
151 __magick_write__ (filename, fmt, img);
154 if (any (strcmp (img_class, {"uint8", "uint16", "double"})))
155 if (strcmp (img_class, "double"))
156 img = uint8 (img - 1);
158 if (nd != 2 && nd != 4)
159 error ("imwrite: invalid size for indexed image");
162 error ("imwrite: %s: invalid class for indexed image data", img_class);
164 if (isa (map, "double"))
165 if (ndims (map) != 2 || size (map, 2) != 3)
166 error ("imwrite: invalid size for colormap");
169 error ("imwrite: %s invalid class for indexed image colormap",
173 ## FIXME -- we should really be writing indexed images here but
174 ## __magick_write__ needs to be fixed to handle them.
176 [r, g, b] = ind2rgb (img, map);
177 tmp = uint8 (cat (3, r, g, b) * 255);
180 __magick_write__ (filename, fmt, tmp, options);
181 ## __magick_write__ (filename, fmt, img, map, options);
183 __magick_write__ (filename, fmt, tmp);
184 ## __magick_write__ (filename, fmt, img, map);
190 %% Test input validation
191 %!error imwrite () # Wrong # of args
192 %!error imwrite (1) # Wrong # of args
193 %!error imwrite ({"cell"}, "filename.jpg") # Wrong class for img
194 %!error imwrite (1, [], "filename.jpg") # Empty image map
195 %!error imwrite (1, 2, 3) # No filename specified
196 %!error imwrite (1, "filename") # No fmt specified
197 %!error imwrite (1, "filename", "junk") # Invalid fmt specified
198 %!error imwrite ([], "filename.jpg") # Empty img matrix
199 %!error imwrite (spones(2), "filename.jpg") # Invalid sparse img