changeset 17990:a40156e8b6a7

rgb2ind: backout 5d6243c2acbf removing all quantization (bug #40669) * rgb2ind.m: remove the options n, tol, map, and dither which were implemented by creating tif file, making a system call to gm convert, and reading back the new file. This removes all quantization options limiting rgb2ind to create indexed images equal to the input RGB image and a colormap with as many colors as the input image.
author Carnë Draug <carandraug@octave.org>
date Sat, 23 Nov 2013 23:43:51 +0000
parents 4465699450c2
children 22187db555cf
files scripts/image/rgb2ind.m
diffstat 1 files changed, 27 insertions(+), 137 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/image/rgb2ind.m	Sat Nov 23 09:38:13 2013 -0800
+++ b/scripts/image/rgb2ind.m	Sat Nov 23 23:43:51 2013 +0000
@@ -1,6 +1,5 @@
 ## Copyright (C) 1994-2013 John W. Eaton
 ## Copyright (C) 2012 Carnë Draug
-## Copyright (C) 2013 Adam H Aitkenhead
 ##
 ## This file is part of Octave.
 ##
@@ -20,159 +19,51 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{rgb})
-## @deftypefnx {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{rgb}, @var{map})
-## @deftypefnx {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{rgb}, @var{n})
-## @deftypefnx {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{rgb}, @var{tol})
-## @deftypefnx {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{rgb}, @var{map}, @var{dither_option})
-## @deftypefnx {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{rgb}, @var{n}, @var{dither_option})
-## @deftypefnx {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{rgb}, @var{tol}, @var{dither_option})
 ## @deftypefnx {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{R}, @var{G}, @var{B})
-## @deftypefnx {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{R}, @var{G}, @var{B}, @var{map})
-## @deftypefnx {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{R}, @var{G}, @var{B}, @var{n})
-## @deftypefnx {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{R}, @var{G}, @var{B}, @var{tol})
-## @deftypefnx {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{R}, @var{G}, @var{B}, @var{map}, @var{dither_option})
-## @deftypefnx {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{R}, @var{G}, @var{B}, @var{n}, @var{dither_option})
-## @deftypefnx {Function File} {[@var{x}, @var{map}] =} rgb2ind (@var{R}, @var{G}, @var{B}, @var{tol}, @var{dither_option})
 ## Convert an image in red-green-blue (RGB) color space to an indexed image.
 ##
-## The input image @var{rgb} must be an N-dimensional RGB image
-## (@nospell{MxNxO}@dots{}x3 array) where M,N,O@dots{} are the image
-## dimensions, and the final dimension contains the values in the red, green
-## and blue channels.  Alternatively, the red, green and blue color channels
-## can be input as separate arrays @var{R}, @var{G}, and @var{B}.
-##
-## The input @var{map} defines the colormap to be used.  Alternatively, @var{n}
-## or @var{tol} may be used to define the maximum number of colors to use in an
-## automatically generated colormap.  @var{n} is related to @var{tol} by:
-## @var{n} = (floor (1/@var{tol}) + 1)^3; where 0 < @var{tol} @leq{} 1.
-##
-## @var{dither_option} is a string which enables or disables dithering:
-## @qcode{"dither"} (default) or @qcode{"nodither"}.
-##
 ## @seealso{ind2rgb, rgb2hsv, rgb2ntsc}
 ## @end deftypefn
 
+## FIXME: This function has a very different syntax than the Matlab
+##        one of the same name.
+##        Octave function does not support N, MAP, DITHER, or TOL arguments.
+
 ## Author: Tony Richardson <arichard@stark.cc.oh.us>
 ## Created: July 1994
 ## Adapted-By: jwe
 
-function [x, map] = rgb2ind (varargin)
-
-  ## Gather the inputs
-  if (nargin < 1 || nargin > 6)
-    print_usage ();
-  else
-
-    ## Test for dither_option, by checking if the final input is a string
-    if (ischar (varargin{end}))
-      dither_option = varargin{end};
-      dither_check  = true;
-    else
-      dither_option = "dither";
-      dither_check  = false;
-    endif
-
-    ## Read the rgb input
-    if (nargin-dither_check==1 || nargin-dither_check==2)
-
-      rgb = varargin{1};
-      if (size (rgb)(end) != 3)
-        error ("rgb2ind: The input image must be an RGB image (MxNxO...x3 array).");
-      elseif (min (rgb(:)) < 0 || max (rgb(:)) > 1)
-        error ("rgb2ind: The input image must contain values between 0 and 1.");
-      endif
-      if (nargin-dither_check==2)
-        option = varargin{2};
-      else
-        dither_option = "nodither";
-      endif
-
-      ## Read the R,G,B inputs
-    elseif (nargin - dither_check==3 || nargin - dither_check==4)
-
-      R = varargin{1};
-      G = varargin{2};
-      B = varargin{3};
-      if (! size_equal (R, G, B))
-        error ("rgb2ind: R, G, and B must have the same size");
-      endif
-      if (nargin-dither_check==4)
-        option = varargin{4};
-      else
-        dither_option = "nodither";
-      endif
-      
-      rgb = reshape ([R(:), G(:), B(:)], [size(R), 3]);
+function [x, map] = rgb2ind (R, G, B)
 
-    endif
-  endif
-      
-  sz = size (rgb);
-
-  ## Apply a limited colormap if required
-  if (exist ("option","var"))
-
-    if (size (option, 1)==1)
-
-      if (option>0 && option<=1)
-        ## option: tol
-        tol = option;
-        n   = (floor (1/option) + 1)^3;
-      else
-        ## option: n
-        n   = option;
-      endif
-      optionstr = sprintf ("-colors %d",n);
-      
-    else
-
-      ## option: map
-      map = option;
-      if (isequal (map(:,1),map(:,2)) || isequal (map(:,1),map(:,3))
-          || isequal (map(:,2),map(:,3)))
-        error ("rgb2ind: The colormap cannot contain matching R,G, or B channels.")
-      endif
-      fnmap = tmpnam;
-      map = reshape (map, size (map, 1), 1, 3);
-      imwrite (map, fnmap, "tiff");
-      optionstr = sprintf ("-map %s", fnmap);
-      
-    endif
-  
-    ## If image is an ND array, convert it to a tiled 2D image
-    ## before processing it with Graphicsmagick
-    if (numel (sz) > 3)
-     rgb = reshape (rgb, [prod(sz(1:end-2)), sz(end-1), 3]);
-    endif
-
-    ## Prepare the Graphicsmagick dithering option
-    if (strcmp (dither_option, "nodither"))
-      ditherstr = "+dither";
-    elseif (strcmp (dither_option, "dither"))
-      ditherstr = "-dither";
-    endif
-      
-    ## Perform the image processing using Graphicsmagick
-    fna = tmpnam;
-    fnb = tmpnam;
-    imwrite (rgb, fna, "tiff");
-    gmstr = sprintf ("gm convert %s %s %s %s", fna, ditherstr, optionstr, fnb);
-    system (gmstr);
-    rgb = imread (fnb);
-    
+  if (nargin != 1 && nargin != 3)
+    print_usage ();
   endif
 
-  ## Conversion of rgb image to x,map
-  pr = prod (sz(1:end-1));
-  x = zeros (sz(1:end-1));
-  [map,~,x(:)] = unique (reshape (rgb, [pr, 3]), "rows");
+  if (nargin == 1)
+    rgb = R;
+    if (ndims (rgb) != 3 || size (rgb, 3) != 3)
+      error ("rgb2ind: argument is not an RGB image");
+    else
+      R = rgb(:,:,1);
+      G = rgb(:,:,2);
+      B = rgb(:,:,3);
+    endif
+  elseif (! size_equal (R, G, B))
+    error ("rgb2ind: R, G, and B must have the same size");
+  endif
+
+  x = reshape (1:numel (R), size (R));
+
+  map    = unique ([R(:) G(:) B(:)], "rows");
+  [~, x] = ismember ([R(:) G(:) B(:)], map, "rows");
+  x      = reshape (x, size (R));
 
   ## a colormap is of class double and values between 0 and 1
-  switch (class (rgb))
+  switch (class (R))
     case {"single", "double", "logical"}
       ## do nothing, return the same
     case {"uint8", "uint16"}
-      map = double (map) / double (intmax (class (rgb)));
+      map = double (map) / double (intmax (class (R)));
     case "int16"
       map = (double (im) + 32768) / 65535;
     otherwise
@@ -193,7 +84,6 @@
 
 endfunction
 
-
 %% FIXME: Need some functional tests or %!demo blocks
 
 %% Test input validation