Bug #10797 fixed - contour, contour2d, contourf did not check input arguments. +... 67/6567/3
Allan CORNET [Fri, 2 Mar 2012 10:41:23 +0000 (11:41 +0100)]
Change-Id: Icc2d2593c842f4672e0d90020d45e77ae07b768c

scilab/CHANGES_5.4.X
scilab/modules/graphics/macros/contour.sci
scilab/modules/graphics/macros/contour2d.sci
scilab/modules/graphics/macros/contourf.sci
scilab/modules/graphics/tests/nonreg_tests/bug_10797.dia.ref [new file with mode: 0644]
scilab/modules/graphics/tests/nonreg_tests/bug_10797.tst [new file with mode: 0644]

index 4679cf6..ba85922 100644 (file)
@@ -370,6 +370,8 @@ Bug fixes
 
 * Bug #10656 fixed - Exception when an empty help browser was closed.
 
+* Bug #10797 fixed - contour, contour2d, contourf did not check input arguments.
+
 
             Changes between version 5.3.3 and 5.4.0-alpha-1 of Scilab
             =========================================================
index 910a281..7dd80c3 100644 (file)
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) INRIA
 // Copyright (C) 2011 - DIGITEO - Michael Baudin
+// Copyright (C) 2012 - DIGITEO - Allan CORNET
 // This file must be used under the terms of the CeCILL.
 // This source file is licensed as described in the file COPYING, which
 // you should have received as part of this distribution.  The terms
 // are also available at
 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
 
-function contour(x,y,z,nz,theta,alpha,leg,flag,ebox,zlev)
+function contour(x, y, z, nz, theta, alpha, leg, flag, ebox, zlev)
 
-       rhs=argn(2);
+  function contour_demo()
+    function z = Surf1(x, y)
+      z = x^2 + y^3;
+    endfunction
 
-       if rhs == 0 then   // demo
+    function z = Surf2(x, y)
+      z = x^2 + y^2;
+    endfunction
 
-               deff('[z]=Surf1(x,y)','z=x^2+y^3');
-               deff('[z]=Surf2(x,y)','z=x^2+y^2');
+    x = -1:0.1:1;
+    y = x;
+    z = eval3d(Surf2, x, y)
 
-               x = -1:0.1:1;
-               y = x;
-               z = eval3d(Surf2,x,y)
+    scf();
+    subplot(211);
+    contour(x, y, Surf1, 10);
+    subplot(212);
+    plot3d(x, y, z);
+    contour(x, y, z + 0.1, 10, flag = [0 2 4]);
+  endfunction
 
-               subplot(211);
-               contour(x,y,Surf1,10);
-               subplot(212);
-               plot3d(x,y,z);
-               contour(x,y,z+0.1,10,flag=[0 2 4]);
-               return
-       end
+  rhs = argn(2);
 
-  if rhs<4
+  // demo
+  if rhs == 0 then
+    contour_demo();
+    return
+  end
+
+  if rhs < 4 then
     error(msprintf(gettext("%s: Wrong number of input argument(s): At least %d expected.\n"), "contour", 4));
   end
-  levels=[]
 
-  opts=[]
-  if exists('theta','local')==1 then opts=[opts,'theta=theta'],end
-  if exists('alpha','local')==1 then opts=[opts,'alpha=alpha'],end
-  if exists('leg'  ,'local')==1 then opts=[opts,'leg=leg']    ,end
-  if exists('ebox' ,'local')==1 then opts=[opts,'ebox=ebox']  ,end
-  if exists('flag' ,'local')==0 then flag=[2 2 3], end
-  if exists('zlev' ,'local')==0 then zlev=0  ,end
+  if type(x) <> 1 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contour", 1));
+  end
 
-  if or(type(z)==[11 13]) then
-    fun=z;clear z //to avoid redfinition warning
-    if type(fun)==11 then comp(fun),end
-    z=feval(x,y,fun)
+  if type(y) <> 1 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contour", 2));
   end
 
-  job=flag(1)
-  if rhs==4|job==2 then
-    contour2d(x,y,z,nz);
-    return,
+  if type(z) <> 1 & type(z) <> 13 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix or Scilab function expected.\n"), "contour", 3));
   end
 
-  if size(nz,'*')==1 then
-    style=1:nz,
-  else
-    style=1:size(nz,'*')
+  if type(nz) <> 1 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"), "contour", 4));
+  end
+
+  if ~isvector(x) then
+    error(999, msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contour", 1));
+  end
+
+  if ~isvector(y) then
+    error(999, msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contour", 2));
+  end
+
+  levels = [];
+
+  opts = [];
+  if exists('theta', 'local') == 1 then
+    opts = [opts, 'theta=theta'];
+  end
+  if exists('alpha', 'local') == 1 then
+    opts = [opts, 'alpha=alpha'];
+  end
+  if exists('leg'  , 'local') == 1 then
+    opts = [opts, 'leg=leg'];
+  end
+  if exists('ebox' , 'local') == 1 then
+    opts = [opts, 'ebox=ebox'];
+  end
+  if exists('flag' , 'local') == 0 then
+    flag = [2 2 3];
+  end
+  if exists('zlev' , 'local') == 0 then
+    zlev = 0;
+  end
+
+  if or(type(z) == [11 13]) then
+    fun = z;
+    clear z //to avoid redfinition warning
+    if type(fun) == 11 then
+      comp(fun);
+    end
+    z = feval(x, y, fun);
+  end
+
+  job = flag(1);
+  if rhs == 4 | job == 2 then
+    contour2d(x, y, z, nz);
+    return;
   end
 
-  opts=strcat([opts,'flag=flag(2:3)'],',');
+  if size(nz, '*') == 1 then
+    style = 1:nz;
+  else
+    style = 1:size(nz, '*');
+  end
 
-  [xc,yc]=contour2di(x,y,z,nz);
+  opts = strcat([opts, 'flag=flag(2:3)'], ',');
 
+  [xc, yc] = contour2di(x, y, z, nz);
 
-  fig=gcf();
-  //autoc=fig.auto_clear;
-  //if autoc=="on" then, clf(),end
-  a=gca();
-  fg=a.foreground
-  v=fig.immediate_drawing;
-  fig.immediate_drawing="off"
-  //fig.auto_clear="off"
-  cnt=0
+  fig = gcf();
+  a = gca();
+  fg = a.foreground;
+  v = fig.immediate_drawing;
+  fig.immediate_drawing = "off";
+  cnt = 0;
 
-  fpf=xget("fpf");if fpf=='' then fpf='%.2g',end
-  k=1;n=yc(k); c=0; level = %inf;
+  fpf = xget("fpf");
+  if fpf == '' then
+   fpf = '%.2g';
+  end
+  k = 1;
+  n = yc(k);
+  c = 0;
+  level = %inf;
   while k < length(xc)
     n = yc(k)
     if xc(k) ~= level then
-      c = c+1; level = xc(k),levels=[level levels];
-      a.foreground=c;
-      if cnt>0 then glue(a.children(1:cnt)),cnt=0,end
+      c = c+1;
+      level = xc(k);
+      levels = [level levels];
+      a.foreground = c;
+      if cnt > 0 then
+        glue(a.children(1:cnt));
+        cnt = 0;
+      end
     end
 
-    if job==1 then zz=zlev,else zz=level,end
-    execstr('param3d(xc(k+(1:n)),yc(k+(1:n)),zz*ones(1,n),'+opts+')')
-
-    cnt = cnt+1
-    if stripblanks(fpf)<>'' then
-         // don't clip as in contour2d since we are in 3D here
-         // and stringbox gives data in 2D
-      xstring(xc(k+1+n/2),yc(k+1+n/2)," "+msprintf(fpf,level))
-      e=gce();e.data(3)=zz;e.clip_state = "off"
-      cnt=cnt+1
+    if job == 1 then
+      zz = zlev;
+    else
+      zz = level;
     end
-    k=k+n+1;
+    execstr('param3d(xc(k + (1:n)), yc(k + (1:n)), zz * ones(1, n), ' + opts + ')');
+
+    cnt = cnt + 1;
+    if stripblanks(fpf) <> '' then
+      // don't clip as in contour2d since we are in 3D here
+      // and stringbox gives data in 2D
+      xstring(xc(k + 1 + n / 2), yc(k + 1 + n/2), " " + msprintf(fpf, level));
+      e = gce();
+      e.data(3) = zz;
+      e.clip_state = "off";
+      cnt = cnt + 1;
+    end
+    k = k + n + 1;
+  end
+  if cnt > 0 then
+    glue(a.children(1:cnt));
+    cnt = 0;
   end
-  if cnt>0 then glue(a.children(1:cnt)),cnt=0,end
-  set('current_entity',a);
-  a.foreground=fg
+  set('current_entity', a);
+  a.foreground = fg;
   if flag(3) == 0 then
-    a.axes_visible='off';
-    a.box='off';
+    a.axes_visible = 'off';
+    a.box = 'off';
   elseif flag(3) == 1 then
-    a.axes_visible='off';
-    a.box='off';
+    a.axes_visible = 'off';
+    a.box = 'off';
   elseif flag(3) == 2 then
-    a.axes_visible='off';
-    a.box='back_half';
-  elseif flag(3)==3 then
-    a.axes_visible='off';
-    a.box='on';
-   elseif flag(3)>=4 then
-    a.axes_visible='on';
-    a.box='on';
-  end
-  fig.immediate_drawing=v;
-  //fig.auto_clear=autoc;
+    a.axes_visible = 'off';
+    a.box = 'back_half';
+  elseif flag(3) == 3 then
+    a.axes_visible = 'off';
+    a.box = 'on';
+  elseif flag(3) >= 4 then
+    a.axes_visible = 'on';
+    a.box = 'on';
+  end
+  fig.immediate_drawing = v;
 endfunction
 
index 405e354..71eb1c7 100644 (file)
 // are also available at
 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
 
-function levels=contour2d(x,y,z,nz,style,strf,leg,rect,nax,void)
+function levels = contour2d(x, y, z, nz, style, strf, leg, rect, nax, void)
 
-[lhs,rhs]=argn(0)
-if rhs<4 then
+  [lhs, rhs] = argn(0);
+
+  if rhs == 0 then
+    scf();
+    contour2d(1:10, 1:10, rand(10,10), 5, rect = [0, 0, 11, 11]);
+  end
+
+  if rhs < 4 then
     error(msprintf(gettext("%s: Wrong number of input argument(s): At least %d expected.\n"), "contour2d", 4));
-end
+  end
+
+  if type(x) <> 1 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contour2d", 1));
+  end
+
+  if type(y) <> 1 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contour2d", 2));
+  end
+
+  if type(z) <> 1 & type(z) <> 13 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix or Scilab function expected.\n"), "contour2d", 3));
+  end
+
+  if type(nz) <> 1 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"), "contour2d", 4));
+  end
+
+  if ~isvector(x) then
+    error(999, msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contour2d", 1));
+  end
+
+  if ~isvector(y) then
+    error(999, msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contour2d", 2));
+  end
 
-opts=[]
-levels=[]
-if ~exists('style','local')==1 then
-    if size(nz,'*')==1 then
-        style=1:nz,
+  opts = [];
+  levels = [];
+
+  if ~exists('style', 'local') == 1 then
+    if size(nz, '*') == 1 then
+      style = 1:nz;
     else
-        style=1:size(nz,'*')
+      style = 1:size(nz, '*');
     end
-end
-if exists('strf','local')==1 then
-    yflag=part(strf,2)
-    if or(yflag==['2' '4' '6' '8']) then
-        rect=[min(x),min(y),max(x),max(y)]
-        yflag=string(evstr(yflag)-1)
-        strf=part(strf,1)+yflag+part(strf,3)
+  end
+
+  if exists('strf', 'local') == 1 then
+    yflag = part(strf, 2);
+    if or(yflag == ['2' '4' '6' '8']) then
+      rect = [min(x), min(y), max(x), max(y)];
+      yflag = string(evstr(yflag) - 1);
+      strf = part(strf, 1) + yflag + part(strf, 3);
     end
-    opts=[opts,'strf=strf'],
-end
-if exists('leg','local')==1 then
-    opts=[opts,'leg=leg'];
-end
-rectSpecified = %f ;
-if exists('rect','local')==1 then
-    opts=[opts,'rect=rect'];
-    rectSpecified = %t ;
-end
-if exists('nax','local')==1 then
-    opts=[opts,'nax=nax'];
-end
-if exists('logflag','local')==1 then
-    opts=[opts,'logflag=logflag'];
-end
-if exists('frameflag','local')==1 then
-    opts=[opts,'frameflag=frameflag'];
-else
-    frameflag=[]
-end
-if exists('axesflag','local')==1 then
-    opts=[opts,'axesflag=axesflag'];
-end
-opts=strcat([opts,"style=style(c)"],',')
-
-if or(type(z)==[11 13]) then
-    fun=z;clear z //to avoid redfinition warning
-    if type(fun)==11 then
-        comp(fun);
+    opts = [opts,'strf=strf'];
+  end
+
+  if exists('leg', 'local') == 1 then
+    opts = [opts, 'leg=leg'];
+  end
+  rectSpecified = %f;
+  if exists('rect','local') == 1 then
+    opts = [opts, 'rect=rect'];
+    rectSpecified = %t;
+  end
+  if exists('nax','local') == 1 then
+    opts = [opts, 'nax=nax'];
+  end
+  if exists('logflag','local') == 1 then
+    opts = [opts, 'logflag=logflag'];
+  end
+  if exists('frameflag','local') == 1 then
+    opts = [opts,'frameflag=frameflag'];
+  else
+    frameflag = [];
+  end
+  if exists('axesflag','local') == 1 then
+    opts = [opts, 'axesflag=axesflag'];
+  end
+  opts = strcat([opts, "style=style(c)"], ',');
+
+  if or(type(z) == [11 13]) then
+    fun = z;
+    //to avoid redfinition warning
+    clear z
+    if type(fun) == 11 then
+      comp(fun);
     end
-    z=feval(x,y,fun)
-end
-
-[xc,yc]=contour2di(x,y,z,nz);
-fpf=xget("fpf");
-if fpf=='' then
-    fpf='%.3g';
-end
-
-
-fig = gcf();
-a = gca();
-autoc = a.auto_clear;
-if autoc=="on" then
+    z = feval(x, y, fun);
+  end
+
+  [xc, yc] = contour2di(x, y, z, nz);
+  fpf = xget("fpf");
+  if fpf == '' then
+    fpf = '%.3g';
+  end
+
+  fig = gcf();
+  a = gca();
+  autoc = a.auto_clear;
+  if autoc == "on" then
     if ~isempty(a.children) then
-        delete(a.children)
+      delete(a.children);
     end
-end
-v=fig.immediate_drawing;
-fig.immediate_drawing="off"
-a.auto_clear="off"
-cnt=0
-
-
-// we draw the contour with call to plot2d for each level line
-// however the data_bounds will be always reset after each plot
-// so we must compute before the bounding rectangle (xmin,ymin,xmax,ymax)
-// and give it to each plot2d. This is useful for frameflag = (2,4,6,8)
-// since the data_bounds are given by the extrema of x and y
-if ( frameflag == 2 | frameflag == 4 | frameflag == 6 | frameflag == 8 )
+  end
+  v = fig.immediate_drawing;
+  fig.immediate_drawing = "off";
+  a.auto_clear = "off";
+  cnt = 0;
+
+
+  // we draw the contour with call to plot2d for each level line
+  // however the data_bounds will be always reset after each plot
+  // so we must compute before the bounding rectangle (xmin,ymin,xmax,ymax)
+  // and give it to each plot2d. This is useful for frameflag = (2,4,6,8)
+  // since the data_bounds are given by the extrema of x and y
+  if ( frameflag == 2 | frameflag == 4 | frameflag == 6 | frameflag == 8 )
     // get the bounding rectangle
-    rect = [min(x),min(y),max(x),max(y)];
+    rect = [min(x), min(y), max(x), max(y)];
     // set the option accordingly
     if ~rectSpecified then
-        opts=strcat([opts,'rect=rect'],',');
+      opts = strcat([opts, 'rect=rect'], ',');
     end
     // the rect will be taken into account
     frameflag = frameflag - 1 ;
-elseif (~rectSpecified) then
+  elseif (~rectSpecified) then
     // get rect any way for clipping
-    rect = [min(x),min(y),max(x),max(y)];
-end
-
-k=1;n=yc(k); c=0; level = %inf;
-while k < length(xc)
-    n = yc(k)
+    rect = [min(x), min(y), max(x), max(y)];
+  end
+
+  k = 1;
+  n = yc(k);
+  c = 0;
+  level = %inf;
+  while k < length(xc)
+    n = yc(k);
     if xc(k) ~= level then
-        c = c+1; level = xc(k),levels=[level levels];
-
-        if cnt>0 then
-            glue(a.children(1:cnt));
-            cnt=0;
-        end
-
+      c = c + 1;
+      level = xc(k);
+      levels = [level levels];
+      if cnt>0 then
+        glue(a.children(1:cnt));
+        cnt = 0;
+      end
     end
-    err = execstr('plot2d(xc(k+(1:n)),yc(k+(1:n)),'+opts+')','errcatch','m');
-    frameflag = 0 ;
+    err = execstr('plot2d(xc(k + (1:n)), yc(k + (1:n)),' + opts + ')', 'errcatch', 'm');
+    frameflag = 0;
 
     // add a test to see if plot2d call succeed
     // and, if not, restore good figure property values before exiting
     if err <> 0
-        mprintf("Error %d : in plot2d called by contour2d",err);
-        fig.immediate_drawing=v;
-        a.auto_clear=autoc;
-        return;
+      mprintf(gettext("Error %d : in plot2d called by contour2d"), err);
+      fig.immediate_drawing = v;
+      a.auto_clear = autoc;
+      return;
     end
 
     unglue(a.children(1))
-    cnt = cnt+1
-
-    if stripblanks(fpf)<>'' then
-        labelText = " " + msprintf(fpf,level);
-        labelPos = [xc(k+1+n/2),yc(k+1+n/2)];
-        labelBox = stringbox(labelText, labelPos(1), labelPos(2));
-        // check that the text is not outside the box
-        // better than clipping to avoid half cut strings
-        if labelBox(1,1) > rect(1) & labelBox(2,1) > rect(2) & ...
-                labelBox(1,3) < rect(3) & labelBox(2,3) < rect(4) then
-            xstring(labelPos(1),labelPos(2),labelText)
-            e = gce();
-            e.clip_state = "off";
-            cnt=cnt+1;
-        end
+    cnt = cnt + 1;
+
+    if stripblanks(fpf) <> '' then
+      labelText = " " + msprintf(fpf, level);
+      labelPos = [xc(k + 1 + n/2), yc(k + 1 + n/2)];
+      labelBox = stringbox(labelText, labelPos(1), labelPos(2));
+      // check that the text is not outside the box
+      // better than clipping to avoid half cut strings
+      if labelBox(1,1) > rect(1) & labelBox(2,1) > rect(2) & ..
+        labelBox(1,3) < rect(3) & labelBox(2,3) < rect(4) then
+        xstring(labelPos(1), labelPos(2), labelText)
+        e = gce();
+        e.clip_state = "off";
+        cnt = cnt + 1;
+      end
     end
-    k=k+n+1;
-end
-
+    k = k + n + 1;
+  end
 
-if cnt>0 then
+  if cnt > 0 then
     glue(a.children(1:cnt));
-    cnt=0;
-end
-set('current_entity',a);
-fig.immediate_drawing=v;
-//fig.auto_clear=autoc;
-draw(fig)
+    cnt = 0;
+  end
+  set('current_entity', a);
+  fig.immediate_drawing = v;
+  draw(fig);
 endfunction
index 10d9074..0e3d398 100644 (file)
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) INRIA
+// Copyright (C) DIGITEO - 2012 - Allan CORNET
 // This file must be used under the terms of the CeCILL.
 // This source file is licensed as described in the file COPYING, which
 // you should have received as part of this distribution.  The terms
-// are also available at    
+// are also available at
 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
 
-function contourf(x,y,z,nv,style,strf,leg,rect,nax)
-       
-       [nout,nin]=argn(0);
-       
-       if nin == 0 then   // demo
-               t = -%pi:0.1:%pi;
-               m = sin(t)'*cos(t);
-               contourf(t,t,m);
-               return;
-  end
-
-if nin <= 0 then x=1:10;end
-if nin <= 1 then y=1:10;end
-if nin <= 2 then z=rand(size(x,'*'),size(y,'*'));end
-if nin <= 3 then zmin=min(z);zmax=max(z);nv = zmin + (1:10)*(zmax-zmin)/(11);end
-if nin <= 5 then strf="021";end
-if nin <= 6 then leg=" ";end
-if nin <= 7 then rect=[0,0,1,1];end
-if nin <= 8 then nax=[1,10,1,10];end
-if x==[] then x=1:size(z,'r');end 
-if y==[] then y=1:size(z,'c');end 
-
-nvs=size(nv,'*') ;
-if nvs==1 then nvs=nv;zmin=min(z);zmax=max(z);nv = zmin + (1:nvs)*(zmax-zmin)/(nvs+1);end;
-if nin <= 4 then style = -1*ones(1,nvs);end
-if nin <= 7 then rect=[min(x),min(y),max(x),max(y)]; end 
-nv1=nv
-[mz,nz] = size(z);
-minz = min(z);
-maxz = max(z);
-// Surround the matrix by a very low region to get closed contours, and
-// replace any NaN with low numbers as well.
-zz=[ %nan*ones(1,nz+2); %nan*ones(mz,1),z,%nan*ones(mz,1);%nan*ones(1,nz+2)];
-kk=find(isnan(zz(:)));
-zz(kk)=minz-1e4*(maxz-minz)+zeros(kk);
-
-xx = [2*x(1)-x(2); x(:); 2*x(mz)-x(mz-1)];
-yy = [2*y(1)-y(2); y(:); 2*y(nz)-y(nz-1)];
-
-// Internal call to get the contours 
-[x1,y1]=contour2di(xx,yy,zz,nv);
-CS=[x1;y1];
-// Find the indices of the curves in the c matrix, and get the
-// area of closed curves in order to draw patches correctly. 
-ii = 1;
-ncurves = 0;
-I = [];
-Area=[];
-
-while (ii < size(CS,2)),
-  nl=CS(2,ii);
-  ncurves = ncurves + 1;
-  I(ncurves) = ii;
-  xp=CS(1,ii+(1:nl));  // First patch
-  yp=CS(2,ii+(1:nl));
-  Area(ncurves)=sum( mtlb_diff(xp).*(yp(1:nl-1)+yp(2:nl))/2 );
-  ii = ii + nl + 1;
-end
-
-lp=xget('lastpattern');
-
-if size(nv,'*') > 1 // case where nv is a vector defining the level curve values
-  if  size(nv,'*') > lp ; write(%io(2),'Colormap too small');return ;end 
-else
-  if nv > lp ; write(%io(2),'Colormap too small');return ;end 
-end
-
-min_nv=min(nv);
-max_nv=max(nv);
-
-plot2d([min(xx);max(xx)],[min(yy);max(yy)],0,strf,leg,rect,nax);
-
-// Plot patches in order of decreasing size. This makes sure that
-// all the lev1es get drawn, not matter if we are going up a hill or
-// down into a hole. When going down we shift levels though, you can
-// tell whether we are going up or down by checking the sign of the
-// area (since curves are oriented so that the high side is always
-// the same side). Lowest curve is largest and encloses higher data
-// always.
-
-draw_min=1;
-H=[];
-[FA,IA]=gsort(abs(Area));
-
-  drawlater(); // postpon the drawing here
-  a=gca();
-  old_foreground = a.foreground;
-  pat=xget('pattern');
-  for jj=IA',
-    nl=CS(2,I(jj));
-    lev1=CS(1,I(jj));
-    if (lev1 ~= minz | draw_min),
-      xp=CS(1,I(jj)+(1:nl));  
-      yp=CS(2,I(jj)+(1:nl)); 
-      pat=size(find( nv <= lev1),'*');
-      xset("pattern",pat);
-      xfpoly(xp,yp)
-    end;
-  end
-  
-  if style(1)<>-1 then 
-    contour2d(xx,yy,zz,nv,style,"000",leg,rect,nax);
-  end
-  a.foreground = old_foreground;
-  drawnow(); // draw all now!
+function contourf(x, y, z, nv, style, strf, leg, rect, nax)
+
+  function [I, CS, Area] = findCurvesIndices(xx, yy, zz, nv)
+    [x1, y1] = contour2di(xx, yy, zz, nv);
+    CS = [x1; y1];
+    ii = 1;
+    ncurves = 0;
+    I = [];
+    Area = [];
+
+    while (ii < size(CS, 2))
+      nl = CS(2, ii);
+      ncurves = ncurves + 1;
+      I(ncurves) = ii;
+      xp = CS(1, ii + (1:nl));  // First patch
+      yp = CS(2, ii + (1:nl));
+      Area(ncurves) = sum(diff(xp).*(yp(1:nl - 1) + yp(2:nl)) / 2 );
+      ii = ii + nl + 1;
+    end
+  endfunction
+
+  function plotPatches(Area, I, CS, style, leg, rect, nax)
+    draw_min = 1;
+    H = [];
+    [FA, IA] = gsort(abs(Area));
+
+    // postpon the drawing here
+    drawlater();
+    a = gca();
+    old_foreground = a.foreground;
+    pat = xget('pattern');
+    for jj = IA',
+      nl = CS(2, I(jj));
+      lev1 = CS(1, I(jj));
+      if (lev1 ~= minz | draw_min) then
+        xp = CS(1, I(jj) + (1:nl));
+        yp = CS(2, I(jj) + (1:nl));
+        pat = size(find( nv <= lev1), '*');
+        xset("pattern", pat);
+        xfpoly(xp, yp)
+      end
+    end
+
+    if style(1) <> -1 then
+      contour2d(xx, yy, zz, nv, style, "000", leg, rect, nax);
+    end
+    a.foreground = old_foreground;
+    drawnow(); // draw all now!
+  endfunction
+
+
+  [nout, nin] = argn(0);
+
+  if nin == 0 then   // demo
+    t = -%pi:0.1:%pi;
+    m = sin(t)' * cos(t);
+    contourf(t, t, m);
+    return;
+  end
+
+  if nin <= 0 then
+    x = 1:10;
+  end
+  if nin <= 1 then
+    y = 1:10;
+  end
+  if nin <= 2 then
+    z = rand(size(x,'*'), size(y,'*'));
+  end
+  if nin <= 3 then
+    zmin = min(z);
+    zmax = max(z);
+    nv = zmin + (1:10) * (zmax-zmin)/(11);
+  end
+  if nin <= 5 then
+    strf = "021";
+  end
+  if nin <= 6 then
+    leg = " ";
+  end
+  if nin <= 7 then
+    rect = [0, 0, 1, 1];
+  end
+  if nin <= 8 then
+    nax = [1,10,1,10];
+  end
+  if x == [] then
+    x = 1:size(z, 'r');
+  end
+  if y == [] then
+    y = 1:size(z,'c');
+  end
+
+  if type(x) <> 1 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contourf", 1));
+  end
+
+  if type(y) <> 1 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contourf", 2));
+  end
+
+  if type(z) <> 1 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"), "contourf", 3));
+  end
+
+  if type(nv) <> 1 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"), "contourf", 4));
+  end
+
+  if type(strf) <> 10 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d: String expected.\n"), "contourf", 6));
+  end
+
+  if type(leg) <> 10 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d: String expected.\n"), "contourf", 7));
+  end
+
+  if type(rect) <> 1 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"), "contourf", 8));
+  end
+
+  if type(nax) <> 1 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d:  Real matrix expected.\n"), "contourf", 9));
+  end
+
+
+  nvs = size(nv, '*') ;
+  if nvs == 1 then
+    nvs = nv;
+    zmin = min(z);
+    zmax = max(z);
+    nv = zmin + (1:nvs) * (zmax-zmin) / (nvs+1);
+  end;
+
+  if nin <= 4 then
+    style = -1 * ones(1, nvs);
+  end
+
+  if type(style) <> 1 then
+    error(999, msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"), "contourf", 5));
+  end
+
+  if nin <= 7 then
+    rect = [min(x), min(y), max(x), max(y)];
+  end
+
+  if ~isvector(x) then
+    error(999, msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contourf", 1));
+  end
+
+  if ~isvector(y) then
+    error(999, msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contourf", 2));
+  end
+
+  if size(strf, '*') <> 1 then
+    error(999, msprintf(gettext("%s: Wrong size for input argument #%d: A string expected.\n"), "contourf", 6));
+  end
+
+  if size(leg, '*') <> 1 then
+    error(999, msprintf(gettext("%s: Wrong size for input argument #%d: A string expected.\n"), "contourf", 7));
+  end
+
+  nv1 = nv;
+  [mz, nz] = size(z);
+  minz = min(z);
+  maxz = max(z);
+
+  // Surround the matrix by a very low region to get closed contours, and
+  // replace any NaN with low numbers as well.
+  zz =[%nan * ones(1, nz + 2); ..
+       %nan * ones(mz, 1), z, %nan * ones(mz, 1); ..
+       %nan * ones(1, nz + 2)];
+  kk = find(isnan(zz(:)));
+  zz(kk) = minz - 1e4 * (maxz - minz) + zeros(kk);
+
+  xx = [2 * x(1) - x(2); x(:); 2 * x(mz) - x(mz - 1)];
+  yy = [2 * y(1) - y(2); y(:); 2 * y(nz) - y(nz - 1)];
+
+
+  // Find the indices of curves in the matrix c,
+  // and get the area closed curves in order to draw patches correctly.
+  [I, CS, Area] = findCurvesIndices(xx, yy, zz, nv);
+
+  // case where nv is a vector defining the level curve values
+  lp = xget('lastpattern');
+  if size(nv, '*') > 1 then
+    if size(nv, '*') > lp then
+      write(%io(2), gettext('Colormap too small.'));
+      return;
+    end
+  else
+    if nv > lp then
+      write(%io(2), gettext('Colormap too small.'));
+      return;
+    end
+  end
+
+  min_nv = min(nv);
+  max_nv = max(nv);
+
+  plot2d([min(xx);max(xx)], [min(yy);max(yy)], 0, strf, leg, rect, nax);
+
+  // Plot patches in order of decreasing size. This makes sure that
+  // all the lev1es get drawn, not matter if we are going up a hill or
+  // down into a hole. When going down we shift levels though, you can
+  // tell whether we are going up or down by checking the sign of the
+  // area (since curves are oriented so that the high side is always
+  // the same side). Lowest curve is largest and encloses higher data
+  // always.
+  plotPatches(Area, I, CS, style, leg, rect, nax);
 
 endfunction
 
diff --git a/scilab/modules/graphics/tests/nonreg_tests/bug_10797.dia.ref b/scilab/modules/graphics/tests/nonreg_tests/bug_10797.dia.ref
new file mode 100644 (file)
index 0000000..d181cb4
--- /dev/null
@@ -0,0 +1,50 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - DIGITEO - Allan CORNET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+//
+// <-- Non-regression test for bug 10797 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=10797
+//
+// <-- Short Description -->
+// contour, contour2d, contourf did not check input arguments
+X = 1:10;
+Y = 1:10;
+Z = rand(10, 10);
+NZ = 5;
+rect = [0, 0, 11, 11];
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contour2d", 1);
+assert_checkerror ("contour2d(''X'', Y, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contour2d", 1);
+assert_checkerror ("contour2d(1, Y, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contour2d", 2);
+assert_checkerror ("contour2d(X, ''Y'', Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contour2d", 2);
+assert_checkerror ("contour2d(X, 1, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix or Scilab function expected.\n"), "contour2d", 3);
+assert_checkerror ("contour2d(X, Y, ''Z'', NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contour", 1);
+assert_checkerror ("contour(''X'', Y, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contour", 1);
+assert_checkerror ("contour(1, Y, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contour", 2);
+assert_checkerror ("contour(X, ''Y'', Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contour", 2);
+assert_checkerror ("contour(X, 1, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix or Scilab function expected.\n"), "contour", 3);
+assert_checkerror ("contour(X, Y, ''Z'', NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contourf", 1);
+assert_checkerror ("contourf(''X'', Y, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contourf", 1);
+assert_checkerror ("contourf(1, Y, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contourf", 2);
+assert_checkerror ("contourf(X, ''Y'', Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contourf", 2);
+assert_checkerror ("contourf(X, 1, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"), "contourf", 3);
+assert_checkerror ("contourf(X, Y, ''Z'', NZ , rect);", msgerr);
diff --git a/scilab/modules/graphics/tests/nonreg_tests/bug_10797.tst b/scilab/modules/graphics/tests/nonreg_tests/bug_10797.tst
new file mode 100644 (file)
index 0000000..c4c6641
--- /dev/null
@@ -0,0 +1,54 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - DIGITEO - Allan CORNET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+//
+// <-- Non-regression test for bug 10797 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=10797
+//
+// <-- Short Description -->
+// contour, contour2d, contourf did not check input arguments
+
+X = 1:10;
+Y = 1:10;
+Z = rand(10, 10);
+NZ = 5;
+rect = [0, 0, 11, 11];
+
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contour2d", 1);
+assert_checkerror ("contour2d(''X'', Y, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contour2d", 1);
+assert_checkerror ("contour2d(1, Y, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contour2d", 2);
+assert_checkerror ("contour2d(X, ''Y'', Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contour2d", 2);
+assert_checkerror ("contour2d(X, 1, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix or Scilab function expected.\n"), "contour2d", 3);
+assert_checkerror ("contour2d(X, Y, ''Z'', NZ , rect);", msgerr);
+
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contour", 1);
+assert_checkerror ("contour(''X'', Y, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contour", 1);
+assert_checkerror ("contour(1, Y, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contour", 2);
+assert_checkerror ("contour(X, ''Y'', Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contour", 2);
+assert_checkerror ("contour(X, 1, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix or Scilab function expected.\n"), "contour", 3);
+assert_checkerror ("contour(X, Y, ''Z'', NZ , rect);", msgerr);
+
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contourf", 1);
+assert_checkerror ("contourf(''X'', Y, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contourf", 1);
+assert_checkerror ("contourf(1, Y, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real vector expected.\n"), "contourf", 2);
+assert_checkerror ("contourf(X, ''Y'', Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong size for input argument #%d: Real vector expected.\n"), "contourf", 2);
+assert_checkerror ("contourf(X, 1, Z, NZ , rect);", msgerr);
+msgerr = msprintf(gettext("%s: Wrong type for input argument #%d: Real matrix expected.\n"), "contourf", 3);
+assert_checkerror ("contourf(X, Y, ''Z'', NZ , rect);", msgerr);