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