Mercurial > hg > octave-nkf
changeset 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 | 8a54a481ecb5 |
children | efbe746f8fa8 |
files | scripts/image/image.m scripts/image/imagesc.m |
diffstat | 2 files changed, 163 insertions(+), 112 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/image/image.m +++ b/scripts/image/image.m @@ -65,15 +65,31 @@ [hax, varargin, nargin] = __plt_get_axis_arg__ ("image", varargin{:}); - if (isempty (hax)) - hax = gca (); - endif - chararg = find (cellfun ("isclass", varargin, "char"), 1, "first"); - if (nargin == 0 || chararg == 1) + do_new = true; + if (nargin == 0) img = imread ("default.img"); x = y = []; + elseif (chararg == 1) + ## Low-Level syntax + do_new = false; + x = y = img = []; + idx = find (strcmpi (varargin, "cdata"), 1); + if (idx) + img = varargin{idx+1}; + varargin(idx:idx+1) = []; + endif + idx = find (strcmpi (varargin, "xdata"), 1); + if (idx) + x = varargin{idx+1}; + varargin(idx:idx+1) = []; + endif + idx = find (strcmpi (varargin, "ydata"), 1); + if (idx) + y = varargin{idx+1}; + varargin(idx:idx+1) = []; + endif elseif (nargin == 1 || chararg == 2) img = varargin{1}; x = y = []; @@ -85,9 +101,25 @@ img = varargin{3}; chararg = 4; endif - - htmp = __img__ (hax, x, y, img, varargin{chararg:end}); - set (hax, "layer", "top"); + + oldfig = []; + if (! isempty (hax)) + oldfig = get (0, "currentfigure"); + endif + unwind_protect + if (do_new) + hax = newplot (hax); + elseif (isempty (hax)) + hax = gca (); + endif + + htmp = __img__ (hax, do_new, x, y, img, varargin{chararg:end}); + + unwind_protect_cleanup + if (! isempty (oldfig)) + set (0, "currentfigure", oldfig); + endif + end_unwind_protect if (nargout > 0) h = htmp; @@ -105,89 +137,89 @@ ## Created: July 1994 ## Adapted-By: jwe -function h = __img__ (hax, x, y, img, varargin) - - if (isempty (img)) - error ("__img__: matrix is empty"); - endif +function h = __img__ (hax, do_new, x, y, img, varargin) ## FIXME: Hack for integer formats which use zero-based indexing ## Hack favors correctness of display over size of image in memory. - ## True fix will be done in C++ code. + ## True fix must be done in C++ code for renderer. if (ndims (img) == 2 && (isinteger (img) || islogical (img))) img = single (img) + 1; endif - if (isempty (x)) - x = [1, columns(img)]; - endif + if (! isempty (img)) + + if (isempty (x)) + x = [1, columns(img)]; + endif - if (isempty (y)) - y = [1, rows(img)]; - endif + if (isempty (y)) + y = [1, rows(img)]; + endif - xdata = x([1, end]); - ydata = y([1, end]); + xdata = x([1, end]); + ydata = y([1, end]); - if (numel (x) > 2 && numel (y) > 2) - ## Test data for non-linear spacing which is unsupported - tol = .01; # 1% tolerance. FIXME: this value was chosen without thought. - dx = diff (x); - dxmean = (max (x) - min (x)) / (numel (x) - 1); - dx = abs ((dx - dxmean) / dxmean); - dy = diff (y); - dymean = (max (y) - min (y)) / (numel (y) - 1); - dy = abs ((dy - dymean) / dymean); - if (any (dx > tol) || any (dy > tol)) - warning ("image: non-linear X, Y data is ignored. IMG will be shown with linear mapping"); + if (numel (x) > 2 && numel (y) > 2) + ## Test data for non-linear spacing which is unsupported + tol = .01; # 1% tolerance. FIXME: this value was chosen without thought. + dx = diff (x); + dxmean = (max (x) - min (x)) / (numel (x) - 1); + dx = abs ((abs (dx) - dxmean) / dxmean); + dy = diff (y); + dymean = (max (y) - min (y)) / (numel (y) - 1); + dy = abs ((abs (dy) - dymean) / dymean); + if (any (dx > tol) || any (dy > tol)) + warning (["image: non-linear X, Y data is ignored. " ... + "IMG will be shown with linear mapping"]); + endif endif - endif + + endif # ! isempty (img) - htmp = __go_image__ (hax, "cdata", img, "xdata", xdata, "ydata", ydata, - "cdatamapping", "direct", varargin {:}); + h = __go_image__ (hax, "cdata", img, "xdata", xdata, "ydata", ydata, + "cdatamapping", "direct", varargin{:}); - px = __image_pixel_size__ (htmp); + if (do_new && ! ishold (hax)) + ## Set axis properties for new images - if (xdata(2) < xdata(1)) - xdata = fliplr (xdata); - elseif (xdata(2) == xdata(1)) - xdata = xdata(1) + [0, columns(img)-1]; - endif - if (ydata(2) < ydata(1)) - ydata = fliplr (ydata); - elseif (ydata(2) == ydata(1)) - ydata = ydata(1) + [0, rows(img)-1]; - endif - xlim = xdata + [-px(1), px(1)]; - ylim = ydata + [-px(2), px(2)]; + if (! isempty (img)) + px = __image_pixel_size__ (h); + + if (xdata(2) < xdata(1)) + xdata = fliplr (xdata); + elseif (xdata(2) == xdata(1)) + xdata = xdata(1) + [0, columns(img)-1]; + endif + if (ydata(2) < ydata(1)) + ydata = fliplr (ydata); + elseif (ydata(2) == ydata(1)) + ydata = ydata(1) + [0, rows(img)-1]; + endif + xlim = xdata + [-px(1), px(1)]; + ylim = ydata + [-px(2), px(2)]; - ## FIXME -- how can we do this and also get the {x,y}limmode - ## properties to remain "auto"? I suppose this adjustment should - ## happen automatically in axes::update_axis_limits instead of - ## explicitly setting the values here. But then what information is - ## available to axes::update_axis_limits to determine that the - ## adjustment is necessary? - set (hax, "xlim", xlim, "ylim", ylim); + ## FIXME -- how can we do this and also get the {x,y}limmode + ## properties to remain "auto"? I suppose this adjustment should + ## happen automatically in axes::update_axis_limits instead of + ## explicitly setting the values here. But then what information is + ## available to axes::update_axis_limits to determine that the + ## adjustment is necessary? + set (hax, "xlim", xlim, "ylim", ylim); - if (ndims (img) == 3) - if (isinteger (img)) - cls = class (img); - mn = intmin (cls); - mx = intmax (cls); - set (hax, "clim", double ([mn, mx])); - endif - endif + if (ndims (img) == 3) + if (isinteger (img)) + cls = class (img); + mn = intmin (cls); + mx = intmax (cls); + set (hax, "clim", double ([mn, mx])); + endif + endif - set (hax, "view", [0, 90]); + endif # ! isempty (img) - if (strcmp (get (hax, "nextplot"), "replace")) - ## Always reverse y-axis for images, unless hold is on - set (hax, "ydir", "reverse"); - endif + set (hax, "view", [0, 90], "ydir", "reverse", "layer", "bottom"); - if (nargout > 0) - h = htmp; - endif + endif # do_new endfunction @@ -212,3 +244,4 @@ %! h = image (-x, -y, img); %! title ("image (-x, -y, img)"); +## FIXME: Need %!tests for linear
--- a/scripts/image/imagesc.m +++ b/scripts/image/imagesc.m @@ -52,23 +52,66 @@ function h = imagesc (varargin) - if (nargin < 1 || nargin > 4) + [hax, varargin, nargin] = __plt_get_axis_arg__ ("imagesc", varargin{:}); + + chararg = find (cellfun ("isclass", varargin, "char"), 1, "first"); + + do_new = true; + if (nargin == 0) print_usage (); - elseif (isscalar (varargin{1}) && ishandle (varargin{1})) - hax = varargin{1}; - if (! isaxes (hax)) - error ("imagesc: HAX argument must be an axes object"); + elseif (chararg == 1) + ## Low-Level syntax + do_new = false; + img = x = y = climits = []; + elseif (nargin == 1 || chararg == 2) + img = varargin{1}; + x = y = climits = []; + elseif (nargin == 2 || chararg == 3) + img = varargin{1}; + climits = varargin{2}; + x = y = []; + elseif (nargin == 3 || chararg == 4) + x = varargin{1}; + y = varargin{2}; + img = varargin{3}; + climits = []; + elseif (nargin == 4 || chararg == 5) + x = varargin{1}; + y = varargin{2}; + img = varargin{3}; + climits = varargin{4}; + endif + + oldfig = []; + if (! isempty (hax)) + oldfig = get (0, "currentfigure"); + endif + unwind_protect + if (do_new) + hax = newplot (hax); + elseif (isempty (hax)) + hax = gca (); endif - oldh = gca (); - unwind_protect - axes (h); - htmp = __imagesc__ (hax, varargin{2:end}); - unwind_protect_cleanup - axes (oldh); - end_unwind_protect - else - htmp = __imagesc__ (gca (), varargin{:}); - endif + + if (do_new) + htmp = image (x, y, img, "cdatamapping", "scaled", varargin{chararg:end}); + else + htmp = image ("cdatamapping", "scaled", varargin{:}); + endif + + if (do_new && ! ishold (hax)) + ## use given climits or guess them from the matrix + if (numel (climits) == 2 && climits(1) <= climits(2)) + set (hax, "clim", climits); + elseif (! isempty (climits)) + error ("imagesc: CLIMITS must be in form [lo, hi]"); + endif + endif + unwind_protect_cleanup + if (! isempty (oldfig)) + set (0, "currentfigure", oldfig); + endif + end_unwind_protect if (nargout > 0) h = htmp; @@ -76,31 +119,6 @@ endfunction -function h = __imagesc__ (ax, x, y, img, climits) - - if (nargin == 2) - img = x; - x = y = climits = []; - elseif (nargin == 3) - img = x; - climits = y; - x = y = []; - elseif (nargin == 4 && ! isscalar (x) && ! isscalar (y) && ! isscalar (img)) - climits = []; - endif - - h = image (ax, x, y, img); - set (h, "cdatamapping", "scaled"); - - ## use given climits or guess them from the matrix - if (numel (climits) == 2 && climits(1) <= climits(2)) - set (ax, "clim", climits); - elseif (! isempty (climits)) - error ("imagesc: CLIMITS must be in form [lo, hi]"); - endif - -endfunction - %!demo %! clf;