changeset 28885:25b7ffb514f3

ind2x.m: Fix for integer saturation (bug #59242). * image/private/ind2x.m: Avoid adding 1 to intmax. Clip image if map extension would be larger than image. * image/ind2rgb.m: Add BIST.
author Markus Mützel <markus.muetzel@gmx.de>
date Fri, 09 Oct 2020 18:25:25 +0200
parents 32dde927e59b
children d8318c12d903
files scripts/image/ind2rgb.m scripts/image/private/ind2x.m
diffstat 2 files changed, 17 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/image/ind2rgb.m	Fri Oct 09 17:26:07 2020 +0200
+++ b/scripts/image/ind2rgb.m	Fri Oct 09 18:25:25 2020 +0200
@@ -141,3 +141,8 @@
 %! ind(3,3) = 65540;
 %! assert (ind2rgb (uint32 (ind), cmap), rgb)
 %! assert (ind2rgb (uint64 (ind), cmap), rgb)
+
+%!test <*59242>
+%! warning ("off", "Octave:ind2rgb:invalid-idx-img", "local");
+%! assert (ind2rgb (uint64 (intmax ("uint64")), jet (64)), ...
+%!         reshape ([0.5,0,0], [1,1,3]));
--- a/scripts/image/private/ind2x.m	Fri Oct 09 17:26:07 2020 +0200
+++ b/scripts/image/private/ind2x.m	Fri Oct 09 18:25:25 2020 +0200
@@ -58,22 +58,28 @@
   ## It is possible that an integer storage class may not have enough room
   ## to make the switch, in which case we convert the data to single.
   maxidx = max (x(:));
-  if (isinteger (x))
+  is_int = isinteger (x);
+  if (is_int)
     if (maxidx == intmax (x))
       x = single (x);
     endif
-    x      += 1;
-    maxidx += 1;
+    x += 1;
   endif
 
   ## When there are more colors in the image, than there are in the map,
   ## pad the colormap with the last color in the map for Matlab compatibility.
   num_colors = rows (map);
-  if (num_colors < maxidx)
+  if (num_colors - is_int < maxidx)
     warning (["Octave:" caller ":invalid-idx-img"],
              [caller ": indexed image contains colors outside of colormap"]);
-    pad = repmat (map(end,:), maxidx - num_colors, 1);
-    map(end+1:maxidx, :) = pad;
+    if (numel (x) > maxidx - num_colors + is_int)
+      ## The image is large. So extend the map.
+      pad = repmat (map(end,:), maxidx - num_colors + is_int, 1);
+      map(end+(1:rows (pad)), :) = pad;
+    else
+      ## The map extension would be large. So clip the image.
+      x(x > rows (map)) = rows (map);
+    endif
   endif
 
 endfunction