1########################################################################
2##
3## Copyright (C) 2002-2021 The Octave Project Developers
4##
5## See the file COPYRIGHT.md in the top-level directory of this
6## distribution or <https://octave.org/copyright/>.
7##
8## This file is part of Octave.
9##
10## Octave is free software: you can redistribute it and/or modify it
11## under the terms of the GNU General Public License as published by
12## the Free Software Foundation, either version 3 of the License, or
13## (at your option) any later version.
14##
15## Octave is distributed in the hope that it will be useful, but
16## WITHOUT ANY WARRANTY; without even the implied warranty of
17## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18## GNU General Public License for more details.
19##
20## You should have received a copy of the GNU General Public License
21## along with Octave; see the file COPYING.  If not, see
22## <https://www.gnu.org/licenses/>.
23##
24########################################################################
25
26## -*- texinfo -*-
27## @deftypefn  {} {[@var{img}, @var{map}, @var{alpha}] =} imread (@var{filename})
28## @deftypefnx {} {[@dots{}] =} imread (@var{url})
29## @deftypefnx {} {[@dots{}] =} imread (@dots{}, @var{ext})
30## @deftypefnx {} {[@dots{}] =} imread (@dots{}, @var{idx})
31## @deftypefnx {} {[@dots{}] =} imread (@dots{}, @var{param1}, @var{value1}, @dots{})
32## Read images from various file formats.
33##
34## Read an image as a matrix from the file @var{filename} or from the online
35## resource @var{url}.  If neither is given, but @var{ext} was specified, look
36## for a file with the extension @var{ext}.
37##
38## The size and class of the output depends on the format of the image.  A
39## color image is returned as an @nospell{MxNx3} matrix.  Grayscale and
40## black-and-white images are of size @nospell{MxN}@.  Multipage images will
41## have an additional 4th dimension.
42##
43## The bit depth of the image determines the class of the output:
44## @qcode{"uint8"}, @qcode{"uint16"}, or @qcode{"single"} for grayscale and
45## color, and @qcode{"logical"} for black-and-white.  Note that indexed images
46## always return the indexes for a colormap, independent of whether @var{map}
47## is a requested output.  To obtain the actual RGB image, use @code{ind2rgb}.
48## When more than one indexed image is being read, @var{map} is obtained from
49## the first.  In some rare cases this may be incorrect and @code{imfinfo} can
50## be used to obtain the colormap of each image.
51##
52## See the Octave manual for more information in representing images.
53## (@pxref{Representing Images})
54##
55## Some file formats, such as TIFF and GIF, are able to store multiple images
56## in a single file.  @var{idx} can be a scalar or vector specifying the
57## index of the images to read.  By default, Octave will read only the first
58## page.
59##
60## Depending on the file format, it is possible to configure the reading of
61## images with @var{parameter}, @var{value} pairs.  The following options are
62## supported:
63##
64## @table @asis
65## @item @qcode{"Frames"} or @qcode{"Index"}
66## This is an alternative method to specify @var{idx}.  When specifying it
67## in this way, its value can also be the string @qcode{"all"}.
68##
69## @item @qcode{"Info"}
70## This option exists for @sc{matlab} compatibility, but has no effect.  For
71## maximum performance when reading multiple images from a single file, use
72## the @qcode{"Index"} option.
73##
74## @item @qcode{"PixelRegion"}
75## Controls the image region that is read.  The value must be a cell array with
76## two arrays of 3 elements @code{@{[@var{rows}], [@var{cols}]@}}.  The
77## elements in the array are the start, increment, and end pixel to be read.
78## If the increment value is omitted it defaults to 1.  For example, the
79## following are all equivalent:
80##
81## @example
82## @group
83## imread (filename, "PixelRegion", @{[200 600], [300 700]@});
84## imread (filename, "PixelRegion", @{[200 1 600], [300 1 700]@});
85## imread (filename)(200:600, 300:700);
86## @end group
87## @end example
88##
89## @end table
90##
91## @seealso{imwrite, imfinfo, imformats}
92## @end deftypefn
93
94function [img, varargout] = imread (filename, varargin)
95
96  if (nargin < 1)
97    print_usage ();
98  elseif (! ischar (filename))
99    error ("imread: FILENAME must be a string");
100  endif
101
102  [img, varargout{1:nargout-1}] = ...
103    imageIO ("imread", @__imread__, "read", filename, varargin{:});
104
105endfunction
106
107
108%!testif HAVE_MAGICK
109%! vpng = [ ...
110%!  137,  80,  78,  71,  13,  10,  26,  10,   0,   0, ...
111%!    0,  13,  73,  72,  68,  82,   0,   0,   0,   3, ...
112%!    0,   0,   0,   3,   8,   2,   0,   0,   0, 217, ...
113%!   74,  34, 232,   0,   0,   0,   1, 115,  82,  71, ...
114%!   66,   0, 174, 206,  28, 233,   0,   0,   0,   4, ...
115%!  103,  65,  77,  65,   0,   0, 177, 143,  11, 252, ...
116%!   97,   5,   0,   0,   0,  32,  99,  72,  82,  77, ...
117%!    0,   0, 122,  38,   0,   0, 128, 132,   0,   0, ...
118%!  250,   0,   0,   0, 128, 232,   0,   0, 117,  48, ...
119%!    0,   0, 234,  96,   0,   0,  58, 152,   0,   0, ...
120%!   23, 112, 156, 186,  81,  60,   0,   0,   0,  25, ...
121%!   73,  68,  65,  84,  24,  87,  99,  96,  96,  96, ...
122%!  248, 255, 255,  63, 144,   4,  81, 111, 101,  84, ...
123%!   16,  28, 160,  16,   0, 197, 214,  13,  34,  74, ...
124%!  117, 213,  17,   0,   0,   0,   0,  73,  69,  78, ...
125%!   68, 174,  66,  96, 130];
126%! filename = [tempname() ".png"];
127%! unwind_protect
128%!   fid = fopen (filename, "wb");
129%!   fwrite (fid, vpng);
130%!   fclose (fid);
131%!   A = imread (filename);
132%! unwind_protect_cleanup
133%!   unlink (filename);
134%! end_unwind_protect
135%! assert (A(:,:,1), uint8 ([0, 255, 0; 255, 237, 255; 0, 255, 0]));
136%! assert (A(:,:,2), uint8 ([0, 255, 0; 255,  28, 255; 0, 255, 0]));
137%! assert (A(:,:,3), uint8 ([0, 255, 0; 255,  36, 255; 0, 255, 0]));
138
139%!function [r, cmap, a] = write_and_read (w, f_ext, varargin)
140%!  filename = [tempname() "." f_ext];
141%!  unwind_protect
142%!    imwrite (w, filename);
143%!    [r, cmap, a] = imread (filename, varargin{:});
144%!  unwind_protect_cleanup
145%!    unlink (filename);
146%!  end_unwind_protect
147%!endfunction
148
149## test PixelRegion option
150%!testif HAVE_MAGICK
151%! w = randi (255, 100, 100, "uint8");
152%! [r, cmap, a] = write_and_read (w, "tif", "PixelRegion", {[50 70] [20 40]});
153%! assert (r, w(50:70, 20:40));
154%! [r, cmap, a] = write_and_read (w, "tif", "PixelRegion", {[50 2 70] [20 3 40]});
155%! assert (r, w(50:2:70, 20:3:40));
156
157## If a file does not exist, it's the job of imread to check the file
158## exists before sending it over to __imread__ or whatever function
159## is defined in imformats to handle that specific format.  This is the
160## same in imfinfo.  So in this test we replace one format in imformats
161## with something that will not give an error if the file is missing
162## and make sure we do get an error.
163%!testif HAVE_MAGICK
164%! fmt = fmt_ori = imformats ("jpg");
165%! fmt.read = @true;
166%! error_thrown = false;
167%! imformats ("update", "jpg", fmt);
168%! unwind_protect
169%!   try
170%!     imread ("I_sure_hope_this_file_does_not_exist.jpg");
171%!   catch
172%!     error_thrown = true;
173%!   end_try_catch
174%! unwind_protect_cleanup
175%!   imformats ("update", "jpg", fmt_ori);
176%! end_unwind_protect
177%! assert (error_thrown, true);
178
179## make one of the formats read, return what it received as input to
180## confirm that the input parsing is working correctly
181%!testif HAVE_MAGICK
182%! fname = [tempname() ".jpg"];
183%! def_fmt = imformats ();
184%! fid = fopen (fname, "w");
185%! unwind_protect
186%!   fmt = imformats ("jpg");
187%!   fmt.read = @(varargin) varargin;
188%!   imformats ("update", "jpg", fmt);
189%!   assert (imread (fname), {fname});
190%!   assert (imread (fname, "jpg"), {fname});
191%!   assert (imread (fname(1:end-4), "jpg"), {fname});
192%!   extra_inputs = {"some", 89, i, {6 7 8}};
193%!   assert (imread (fname, extra_inputs{:}), {fname, extra_inputs{:}});
194%!   assert (imread (fname, "jpg", extra_inputs{:}), {fname, extra_inputs{:}});
195%!   assert (imread (fname(1:end-4), "jpg", extra_inputs{:}), {fname, extra_inputs{:}});
196%! unwind_protect_cleanup
197%!   fclose (fid);
198%!   unlink (fname);
199%!   imformats (def_fmt);
200%! end_unwind_protect
201
202## Test for bug #41584 (some GM coders report saturated channels as binary)
203%!testif HAVE_MAGICK <41584>
204%! im = zeros ([16 16 3], "uint8");
205%! im(:,:,1) = 255;
206%! im(:,:,3) = repmat (0:16:255, [16 1]);
207%! [r, cmap, a] = write_and_read (im, "png");
208%! assert (class (r), "uint8");
209%! assert (isempty (cmap));
210%! assert (isempty (a));
211