Mercurial > octave-libtiff
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 |