# HG changeset patch
# User Martin Janda <janda.martin1@gmail.com>
# Date 1629068163 -7200
#      Mon Aug 16 00:56:03 2021 +0200
# Node ID 2abc3f58636dfae96c80e9c6f65b341f9b992722
# Parent  4667f437bce7eaf4b1665131c75a6c027cf705bc
imshowpair.m: add new function file

diff -r 4667f437bce7 -r 2abc3f58636d inst/imshowpair.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inst/imshowpair.m	Mon Aug 16 00:56:03 2021 +0200
@@ -0,0 +1,162 @@
+## Copyright (C) 2021 Martin Janda <janda.martin1@gmail.com>
+## 
+## This program is free software: you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+## 
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+## 
+## You should have received a copy of the GNU General Public License
+## along with this program.  If not, see
+## <https://www.gnu.org/licenses/>.
+
+## -*- texinfo -*- 
+## @deftypefn {} {@var{c} =} imshowpair (@var{a}, @var{b})
+## @deftypefnx {} {[@var{c}, @var{rc}] =} imshowpair (@var{a}, @var{ra}, @var{b}, @var{rb})
+## @deftypefnx {} {@var{c} =} imshowpair (@dots{}, @var{method})
+## @deftypefnx {} {@var{c} =} imshowpair (@dots{}, @var{name}, @var{value})
+##
+## @seealso{imfuse}
+## @end deftypefn
+
+function img = imshowpair (varargin)
+  if (nargin < 2)
+    print_usage ();
+  endif
+
+  [a, b, ra, rb, method, scaling, color_channels, parent] = parse_varargin(varargin{:});
+  if (isempty (ra) || isempty (rb))
+    c = imfuse (a, b, method, "ColorChannels", color_channels, "Scaling", scaling);
+  else
+    [c, rc] = imfuse (a, ra, b, rb, method, "ColorChannels", color_channels, "Scaling", scaling);
+  endif
+  img = imshow (c);
+  if (! isempty (parent))
+    set (img, "parent", parent);
+  endif
+endfunction
+
+function [a, b, ra, rb, method, scaling, color_channels, parent] = parse_varargin(varargin)
+  check_is_image (varargin{1}, "A");
+  a = varargin{1};
+  
+  if (isimage (varargin{2}))
+    b = varargin{2};
+    varargin(1:2) = [];
+    ra = [];
+    rb = [];
+  elseif (is_imref (varargin{2}))
+    if (length (varargin) < 4)
+      error ("Octave:invalid-input-arg", ...
+      "expected at least 4 arguments: A, RA, B, RB");
+    endif
+    
+    validateattributes (varargin{2}, {"imref2d"}, {}, "imshowpair", "RA");
+    check_is_image (varargin{3}, "B");
+    validateattributes (varargin{4}, {"imref2d"}, {}, "imshowpair", "RB");
+    
+    ra = varargin{2};
+    b = varargin{3};
+    rb = varargin{4};
+    varargin(1:4) = [];
+  endif
+  
+  method_names = {"falsecolor", "blend", "checkerboard", "diff", "montage"};
+  scaling_names = {"independent", "joint", "none"};
+  scaling = scaling_names{1};
+  method = [];
+  parent = [];
+  
+  green_magenta = [2, 1, 2];
+  red_cyan = [1, 2, 2];
+  color_channels = green_magenta;
+  
+  while (! isempty (varargin))
+    if (isempty (method) && is_valid_method (varargin{1}, method_names))
+      method = lower (varargin{1});
+      varargin(1) = [];
+    else
+      if (length (varargin) < 2)
+        error ("Octave:invalid-input-arg", "expected NAME, VALUE pairs");
+      endif
+      validateattributes (varargin{1}, {"char"}, {"nonempty"}, "imshowpair", ...
+      "NAME");
+      validateattributes (varargin{2}, {}, {"nonempty"}, "imshowpair", "VALUE");
+      name = varargin{1};
+      value = varargin{2};
+      
+      switch (lower (name))
+        case "scaling"
+          if (! is_valid_scaling (value, scaling_names))
+            error ("Octave:invalid-input-arg", "imshowpair: SCALING expected to\
+ be one of 'independent', 'joint', 'none'");
+          endif
+          scaling = value;
+        case "colorchannels"
+          if (ischar (value))
+            switch (value)
+              case "green-magenta"
+                color_channels = green_magenta;
+              case "red-cyan"
+                color_channels = red_cyan;
+              otherwise
+                error ("Octave:invalid-input-arg", ...
+                "imshowpair: expected COLORCHANNELS to be one of 'green-magenta',\
+ 'red-cyan'");
+            endswitch
+          else
+            validateattributes (value, {"numeric"}, ...
+            {"integer", "vector", "numel", 3, ">=", 0, "<=", 2}, ...
+            "imshowpair", "COLORCHANNELS")
+            if (! is_valid_channels (value))
+              error ("Octave:invalid-input-arg", ...
+              "imshowpair: COLORCHANNELS must include values 1 and 2");
+            endif
+            color_channels = value;
+          endif
+        case "interpolation"
+          error ("Octave:invalid-input-arg", "imshowpair: INTERPOLATION not \
+          implemented yet");
+        case "parent"
+          parent = value;
+        otherwise
+          error ("Octave:invalid-input-arg", ...
+          strcat (name, " is not a recognized parameter"));
+      endswitch
+      
+      varargin(1:2) = [];
+    endif
+  endwhile
+  
+  if (isempty (method))
+    method = method_names{1};
+  endif
+  
+endfunction
+
+function check = is_imref (arg)
+  check = isa (arg, "imref2d");
+endfunction
+
+function check = is_valid_method (arg, method_names)
+  check = ischar (arg) && ismember (lower (arg), method_names);
+endfunction
+
+function check = is_valid_scaling (arg, scaling_names)
+  check = ischar (arg) && ismember (lower (arg), scaling_names);
+endfunction
+
+function check = is_valid_channels (arg)
+  check = find (arg == 1) != 0 && find (arg == 2) != 0;
+endfunction
+
+function check_is_image (arg, name)
+  if (! isimage (arg))
+    error ("Octave:invalid-input-arg", ...
+    strcat(name, " expected to be logical, RGB or grayscale image"));
+  endif
+endfunction
\ No newline at end of file
