comparison scripts/image/image.m @ 17692:38cf56b77274

Overhaul image, imagesc to use newplot and support low-level invocation form. * scripts/image/image.m: New variable do_new indicates high-level calling form. For high-level invocation, call newplot before __img__. Correct linearity check if vectors are reversed (high-to-low values). Only apply image properties to axes if doing a high-level invocation. * scripts/image/imagesc.m: New variable do_new indicates high-level calling form. Delete subfunction __imagesc__ and incorporate minimal amount of code into imagesc. Only apply climits for high-level invocation.
author Rik <rik@octave.org>
date Fri, 18 Oct 2013 16:27:44 -0700
parents dd8db3f1c1da
children d63878346099
comparison
equal deleted inserted replaced
17691:8a54a481ecb5 17692:38cf56b77274
63 63
64 function h = image (varargin) 64 function h = image (varargin)
65 65
66 [hax, varargin, nargin] = __plt_get_axis_arg__ ("image", varargin{:}); 66 [hax, varargin, nargin] = __plt_get_axis_arg__ ("image", varargin{:});
67 67
68 if (isempty (hax))
69 hax = gca ();
70 endif
71
72 chararg = find (cellfun ("isclass", varargin, "char"), 1, "first"); 68 chararg = find (cellfun ("isclass", varargin, "char"), 1, "first");
73 69
74 if (nargin == 0 || chararg == 1) 70 do_new = true;
71 if (nargin == 0)
75 img = imread ("default.img"); 72 img = imread ("default.img");
76 x = y = []; 73 x = y = [];
74 elseif (chararg == 1)
75 ## Low-Level syntax
76 do_new = false;
77 x = y = img = [];
78 idx = find (strcmpi (varargin, "cdata"), 1);
79 if (idx)
80 img = varargin{idx+1};
81 varargin(idx:idx+1) = [];
82 endif
83 idx = find (strcmpi (varargin, "xdata"), 1);
84 if (idx)
85 x = varargin{idx+1};
86 varargin(idx:idx+1) = [];
87 endif
88 idx = find (strcmpi (varargin, "ydata"), 1);
89 if (idx)
90 y = varargin{idx+1};
91 varargin(idx:idx+1) = [];
92 endif
77 elseif (nargin == 1 || chararg == 2) 93 elseif (nargin == 1 || chararg == 2)
78 img = varargin{1}; 94 img = varargin{1};
79 x = y = []; 95 x = y = [];
80 elseif (nargin == 2 || chararg == 3) 96 elseif (nargin == 2 || chararg == 3)
81 print_usage (); 97 print_usage ();
83 x = varargin{1}; 99 x = varargin{1};
84 y = varargin{2}; 100 y = varargin{2};
85 img = varargin{3}; 101 img = varargin{3};
86 chararg = 4; 102 chararg = 4;
87 endif 103 endif
88 104
89 htmp = __img__ (hax, x, y, img, varargin{chararg:end}); 105 oldfig = [];
90 set (hax, "layer", "top"); 106 if (! isempty (hax))
107 oldfig = get (0, "currentfigure");
108 endif
109 unwind_protect
110 if (do_new)
111 hax = newplot (hax);
112 elseif (isempty (hax))
113 hax = gca ();
114 endif
115
116 htmp = __img__ (hax, do_new, x, y, img, varargin{chararg:end});
117
118 unwind_protect_cleanup
119 if (! isempty (oldfig))
120 set (0, "currentfigure", oldfig);
121 endif
122 end_unwind_protect
91 123
92 if (nargout > 0) 124 if (nargout > 0)
93 h = htmp; 125 h = htmp;
94 endif 126 endif
95 127
103 135
104 ## Author: Tony Richardson <arichard@stark.cc.oh.us> 136 ## Author: Tony Richardson <arichard@stark.cc.oh.us>
105 ## Created: July 1994 137 ## Created: July 1994
106 ## Adapted-By: jwe 138 ## Adapted-By: jwe
107 139
108 function h = __img__ (hax, x, y, img, varargin) 140 function h = __img__ (hax, do_new, x, y, img, varargin)
109
110 if (isempty (img))
111 error ("__img__: matrix is empty");
112 endif
113 141
114 ## FIXME: Hack for integer formats which use zero-based indexing 142 ## FIXME: Hack for integer formats which use zero-based indexing
115 ## Hack favors correctness of display over size of image in memory. 143 ## Hack favors correctness of display over size of image in memory.
116 ## True fix will be done in C++ code. 144 ## True fix must be done in C++ code for renderer.
117 if (ndims (img) == 2 && (isinteger (img) || islogical (img))) 145 if (ndims (img) == 2 && (isinteger (img) || islogical (img)))
118 img = single (img) + 1; 146 img = single (img) + 1;
119 endif 147 endif
120 148
121 if (isempty (x)) 149 if (! isempty (img))
122 x = [1, columns(img)]; 150
123 endif 151 if (isempty (x))
124 152 x = [1, columns(img)];
125 if (isempty (y)) 153 endif
126 y = [1, rows(img)]; 154
127 endif 155 if (isempty (y))
128 156 y = [1, rows(img)];
129 xdata = x([1, end]); 157 endif
130 ydata = y([1, end]); 158
131 159 xdata = x([1, end]);
132 if (numel (x) > 2 && numel (y) > 2) 160 ydata = y([1, end]);
133 ## Test data for non-linear spacing which is unsupported 161
134 tol = .01; # 1% tolerance. FIXME: this value was chosen without thought. 162 if (numel (x) > 2 && numel (y) > 2)
135 dx = diff (x); 163 ## Test data for non-linear spacing which is unsupported
136 dxmean = (max (x) - min (x)) / (numel (x) - 1); 164 tol = .01; # 1% tolerance. FIXME: this value was chosen without thought.
137 dx = abs ((dx - dxmean) / dxmean); 165 dx = diff (x);
138 dy = diff (y); 166 dxmean = (max (x) - min (x)) / (numel (x) - 1);
139 dymean = (max (y) - min (y)) / (numel (y) - 1); 167 dx = abs ((abs (dx) - dxmean) / dxmean);
140 dy = abs ((dy - dymean) / dymean); 168 dy = diff (y);
141 if (any (dx > tol) || any (dy > tol)) 169 dymean = (max (y) - min (y)) / (numel (y) - 1);
142 warning ("image: non-linear X, Y data is ignored. IMG will be shown with linear mapping"); 170 dy = abs ((abs (dy) - dymean) / dymean);
143 endif 171 if (any (dx > tol) || any (dy > tol))
144 endif 172 warning (["image: non-linear X, Y data is ignored. " ...
145 173 "IMG will be shown with linear mapping"]);
146 htmp = __go_image__ (hax, "cdata", img, "xdata", xdata, "ydata", ydata, 174 endif
147 "cdatamapping", "direct", varargin {:}); 175 endif
148 176
149 px = __image_pixel_size__ (htmp); 177 endif # ! isempty (img)
150 178
151 if (xdata(2) < xdata(1)) 179 h = __go_image__ (hax, "cdata", img, "xdata", xdata, "ydata", ydata,
152 xdata = fliplr (xdata); 180 "cdatamapping", "direct", varargin{:});
153 elseif (xdata(2) == xdata(1)) 181
154 xdata = xdata(1) + [0, columns(img)-1]; 182 if (do_new && ! ishold (hax))
155 endif 183 ## Set axis properties for new images
156 if (ydata(2) < ydata(1)) 184
157 ydata = fliplr (ydata); 185 if (! isempty (img))
158 elseif (ydata(2) == ydata(1)) 186 px = __image_pixel_size__ (h);
159 ydata = ydata(1) + [0, rows(img)-1]; 187
160 endif 188 if (xdata(2) < xdata(1))
161 xlim = xdata + [-px(1), px(1)]; 189 xdata = fliplr (xdata);
162 ylim = ydata + [-px(2), px(2)]; 190 elseif (xdata(2) == xdata(1))
163 191 xdata = xdata(1) + [0, columns(img)-1];
164 ## FIXME -- how can we do this and also get the {x,y}limmode 192 endif
165 ## properties to remain "auto"? I suppose this adjustment should 193 if (ydata(2) < ydata(1))
166 ## happen automatically in axes::update_axis_limits instead of 194 ydata = fliplr (ydata);
167 ## explicitly setting the values here. But then what information is 195 elseif (ydata(2) == ydata(1))
168 ## available to axes::update_axis_limits to determine that the 196 ydata = ydata(1) + [0, rows(img)-1];
169 ## adjustment is necessary? 197 endif
170 set (hax, "xlim", xlim, "ylim", ylim); 198 xlim = xdata + [-px(1), px(1)];
171 199 ylim = ydata + [-px(2), px(2)];
172 if (ndims (img) == 3) 200
173 if (isinteger (img)) 201 ## FIXME -- how can we do this and also get the {x,y}limmode
174 cls = class (img); 202 ## properties to remain "auto"? I suppose this adjustment should
175 mn = intmin (cls); 203 ## happen automatically in axes::update_axis_limits instead of
176 mx = intmax (cls); 204 ## explicitly setting the values here. But then what information is
177 set (hax, "clim", double ([mn, mx])); 205 ## available to axes::update_axis_limits to determine that the
178 endif 206 ## adjustment is necessary?
179 endif 207 set (hax, "xlim", xlim, "ylim", ylim);
180 208
181 set (hax, "view", [0, 90]); 209 if (ndims (img) == 3)
182 210 if (isinteger (img))
183 if (strcmp (get (hax, "nextplot"), "replace")) 211 cls = class (img);
184 ## Always reverse y-axis for images, unless hold is on 212 mn = intmin (cls);
185 set (hax, "ydir", "reverse"); 213 mx = intmax (cls);
186 endif 214 set (hax, "clim", double ([mn, mx]));
187 215 endif
188 if (nargout > 0) 216 endif
189 h = htmp; 217
190 endif 218 endif # ! isempty (img)
219
220 set (hax, "view", [0, 90], "ydir", "reverse", "layer", "bottom");
221
222 endif # do_new
191 223
192 endfunction 224 endfunction
193 225
194 226
195 %!demo 227 %!demo
210 %! ylabel ("limits = [-5.5, 5.5]"); 242 %! ylabel ("limits = [-5.5, 5.5]");
211 %! subplot (2,2,4); 243 %! subplot (2,2,4);
212 %! h = image (-x, -y, img); 244 %! h = image (-x, -y, img);
213 %! title ("image (-x, -y, img)"); 245 %! title ("image (-x, -y, img)");
214 246
247 ## FIXME: Need %!tests for linear