comparison scripts/image/private/__tiff_imread__.m @ 31197:1604c8812b67

Tiff: added numberOfDirectories method.
author magedrifaat <magedrifaat@gmail.com>
date Thu, 01 Sep 2022 01:56:20 +0200
parents
children e5e8cb049b4b
comparison
equal deleted inserted replaced
31196:1da6d747bf78 31197:1604c8812b67
1 function [A, cmap, alpha] = __tiff_imread__ (filename, varargin)
2 img = Tiff (filename);
3 dir_count = img.numberOfDirectories ();
4
5 ## A lot of the input sanitising logic here is copied from
6 ## scripts/image/__imread__.m and adapted to the needs of the Tiff
7 ## interface
8
9 pages = [1];
10 offset = 1;
11 if (nargin > 1 && ! ischar (varargin{1}))
12 if (! is_valid_index_option (varargin {1}))
13 error ("imread: IDX must be a numeric vector");
14 endif
15 pages = varargin{1};
16 offset = 2;
17 endif
18
19 if (rem (numel (varargin) - offset + 1, 2) != 0)
20 error ("imread: PARAM/VALUE arguments must occur in pairs");
21 endif
22
23 ## Check for Index/Frames argument
24 idx = strcmpi ("index", varargin) | strcmpi ("frames", varargin);
25 if (any (idx))
26 if (sum (idx) > 1)
27 error ("imread: Index or Frames may only be specified once");
28 endif
29 val = varargin{circshift (idx, 1)};
30 if (! is_valid_index_option (val) && ! strcmpi (val, "all"))
31 error ("imread: %s must be a vector or the string 'all'", varargin{idx});
32 endif
33 if (strcmpi (val, "all"))
34 pages = 1:dir_count;
35 else
36 pages = val;
37 endif
38 endif
39
40 if (any ((pages < 1) | (pages > dir_count)))
41 error ("imread: index/frames specified are outside the number of images");
42 endif
43
44 img.setDirectory (pages(1));
45 info = get_image_info (img);
46
47 ## Verify that all images have the same dimensions, number of channels,
48 ## bit-depth, and data type
49 for page_idx = 2:numel (pages)
50 img.setDirectory (pages(page_idx));
51 dir_info = get_image_info (img);
52 if (info.width != dir_info.width || info.height != dir_info.height)
53 error ("imread: all frames must have the same size but frame %d is different",
54 pages(page_idx));
55 endif
56 if (info.bitdepth != dir_info.bitdepth)
57 error ("imread: all frames must have the same bit depth but frame %d is different",
58 pages(page_idx));
59 endif
60 if (info.nchannels != dir_info.nchannels)
61 error ("imread: all frames must have the same number of channels but frame %d is different",
62 pages(page_idx));
63 endif
64 if (info.datatype != dir_info.datatype)
65 error ("imread: all frames must have the same data type but frame %d is different",
66 pages(page_idx));
67 endif
68 if (info.photometric != dir_info.photometric)
69 error ("imread: all frames must have the same photometric interpretation but frame %d is different",
70 pages(page_idx));
71 endif
72 endfor
73
74 region = {1:info.height, 1:info.width};
75 for idx = offset:2:(numel (varargin) - offset + 1)
76 switch (tolower (varargin{idx}))
77
78 case {"frames", "index"}
79 ## Do nothing. This option was already processed before the loop.
80
81 case "pixelregion"
82 region = varargin{idx+1};
83 if (! iscell (region) || numel (region) != 2)
84 error ("imread: %s must be a 2-element cell array",
85 varargin{idx});
86 endif
87 for reg_idx = 1:2
88 if (numel (region{reg_idx}) == 3)
89 ## do nothing
90 elseif (numel (region{reg_idx}) == 2)
91 region{reg_idx}(3) = region{reg_idx}(2);
92 region{reg_idx}(2) = 1;
93 else
94 error ("imread: range for %s must be a 2 or 3 element vector",
95 varargin{idx});
96 endif
97 region{reg_idx} = floor (region{reg_idx}(1)): ...
98 floor (region{reg_idx}(2)): ...
99 floor (region{reg_idx}(3));
100 endfor
101 if (region{1}(end) > info.height)
102 error ("imread: end ROWS for PixelRegions option is larger than image height");
103 elseif (region{2}(end) > info.width)
104 error ("imread: end COLS for PixelRegions option is larger than image width");
105 endif
106
107 case "info"
108 ## We ignore this option. This parameter exists in Matlab to
109 ## speed up the reading of multipage TIFF by passing a structure
110 ## that contains information about the start on the file of each
111 ## page. We can't control it through GraphicsMagic but at least
112 ## we allow to load multiple pages with one command.
113
114 otherwise
115 error ("imread: invalid PARAMETER '%s'", varargin{idx});
116
117 endswitch
118 endfor
119
120 A = [];
121 cmap = [];
122 alpha = [];
123 for page_idx = 1:numel(pages)
124 img.setDirectory (pages(page_idx));
125 ## FIXME: This an ineffecient way to read pixel regions because it
126 ## always reads the entire image first. A better way is to figure
127 ## out which strips/tiles are needed for the region and read only those.
128 data = img.read ();
129 data = data (region{1}, region{2}, :);
130 A = cat (4, A, data);
131 if (info.photometric == Tiff.Photometric.Palette)
132 cmap = cat (3, cmap, img.getTag (Tiff.TagID.ColorMap));
133 endif
134 endfor
135
136 img.close ();
137 endfunction
138
139 function bool = is_valid_index_option (arg)
140 bool = isvector (arg) && isnumeric (arg) && isreal (arg);
141 endfunction
142
143 function info = get_image_info (img)
144 info.height = img.getTag (Tiff.TagID.ImageLength);
145 info.width = img.getTag (Tiff.TagID.ImageWidth);
146 info.bitdepth = img.getTag (Tiff.TagID.BitsPerSample);
147 info.nchannels = img.getTag (Tiff.TagID.BitsPerSample);
148 info.datatype = img.getTag (Tiff.TagID.SampleFormat);
149 info.photometric = img.getTag (Tiff.TagID.Photometric);
150 endfunction