Coverity: graphics module resource leaks fixed
[scilab.git] / scilab / modules / graphics / sci_gateway / c / sci_plot3d.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2006 - INRIA - Fabrice Leray
4  * Copyright (C) 2006 - INRIA - Jean-Baptiste Silvy
5  * Copyright (C) 2008 - INRIA - Sylvestre LEDRU (nicer default plot3d)
6  *
7  * Copyright (C) 2012 - 2016 - Scilab Enterprises
8  *
9  * This file is hereby licensed under the terms of the GNU GPL v2.0,
10  * pursuant to article 5.3.4 of the CeCILL v.2.1.
11  * This file was originally licensed under the terms of the CeCILL v2.1,
12  * and continues to be available under such terms.
13  * For more information, see the COPYING file which you should have received
14  * along with this program.
15  *
16  */
17
18 /*------------------------------------------------------------------------*/
19 /* file: sci_plot3d.c                                                     */
20 /* desc : interface for plot3d (and plot3d1) routine                      */
21 /*------------------------------------------------------------------------*/
22
23 #include <stdio.h>
24 #include <string.h>
25 #include "gw_graphics.h"
26 #include "api_scilab.h"
27 #include "BuildObjects.h"
28 #include "GetCommandArg.h"
29 #include "sci_malloc.h"
30 #include "sciCall.h"
31 #include "localization.h"
32 #include "Scierror.h"
33 #include "DefaultCommandArg.h"
34
35 /*--------------------------------------------------------------------------*/
36 int sci_plot3d(char * fname, void *pvApiCtx)
37 {
38     SciErr sciErr;
39     static double  ebox_def [6] = { 0, 1, 0, 1, 0, 1};
40     double *ebox = ebox_def;
41     static int iflag_def[3] = {2, 2, 4};
42     int *iflag = iflag_def;
43     double  alpha_def = 35.0 , theta_def = 45.0;
44     double *alpha = &alpha_def, *theta = &theta_def;
45     int m1 = 0, n1 = 0,  m2 = 0, n2 = 0, m3 = 0, n3 = 0;
46     int m3n = 0, n3n = 0, m3l = 0;
47
48     int izcol = 0,  isfac = 0;
49     double *zcol = NULL;
50     int mustFree = 0;
51
52     static rhs_opts opts[] =
53     {
54         { -1, "alpha", -1, 0, 0, NULL},
55         { -1, "ebox", -1, 0, 0, NULL},
56         { -1, "flag", -1, 0, 0, NULL},
57         { -1, "leg", -1, 0, 0, NULL},
58         { -1, "theta", -1, 0, 0, NULL},
59         { -1, NULL, -1, 0, 0, NULL}
60     };
61
62     char * legend = NULL;
63
64     int* piAddr1  = NULL;
65     int* piAddr2  = NULL;
66     int* piAddr3  = NULL;
67     int* piAddr31 = NULL;
68     int* piAddr32 = NULL;
69
70     double* l1  = NULL;
71     double* l2  = NULL;
72     double* l3  = NULL;
73     double* l3n = NULL;
74     BOOL freeLegend = FALSE;
75
76     /*
77     ** This overload the function to call demo script
78     ** the demo script is called %_<fname>
79     */
80     if (nbInputArgument(pvApiCtx) <= 0)
81     {
82         sci_demo(fname, pvApiCtx);
83         return 0;
84     }
85
86     if (nbInputArgument(pvApiCtx) == 2)
87     {
88         Scierror(77, _("%s: Wrong number of input argument(s).\n"), fname);
89         return -1;
90     }
91
92     CheckInputArgument(pvApiCtx, 1, 8);
93
94     if (getOptionals(pvApiCtx, fname, opts) == 0)
95     {
96         ReturnArguments(pvApiCtx);
97         return 0;
98     }
99
100     if (nbInputArgument(pvApiCtx) != 1 && FirstOpt(pvApiCtx) < 4)
101     {
102         Scierror(999, _("%s: Misplaced optional argument: #%d must be at position %d.\n"), fname, 1, 4);
103         return -1;
104     }
105
106     //get variable address
107     sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr1);
108     if (sciErr.iErr)
109     {
110         printError(&sciErr, 0);
111         return 1;
112     }
113
114     // Retrieve a matrix of double at position 1.
115     sciErr = getMatrixOfDouble(pvApiCtx, piAddr1, &m1, &n1, &l1);
116     if (sciErr.iErr)
117     {
118         Scierror(202, _("%s: Wrong type for argument #%d: A real expected.\n"), fname, 1);
119         printError(&sciErr, 0);
120         return 1;
121     }
122
123     if (nbInputArgument(pvApiCtx) == 1)
124     {
125         int i;
126
127         if (m1 * n1 == 0)
128         {
129             AssignOutputVariable(pvApiCtx, 1) = 0;
130             ReturnArguments(pvApiCtx);
131             return 0;
132         }
133
134         if (m1 == 1 || n1 == 1)
135         {
136             Scierror(999, _("%s: Wrong size for input argument #%d.\n"), fname, 1);
137             return 1;
138         }
139
140         l3 = l1;
141         m3 = m1;
142         n3 = n1;
143         m1 = 1;
144         n1 = m3;
145         m2 = 1;
146         n2 = n3;
147         l1 = (double *)MALLOC(sizeof(double) * n1);
148         for (i = 0; i < n1; ++i)
149         {
150             l1[i] = i + 1;
151         }
152         l2 = (double *)MALLOC(sizeof(double) * n2);
153         for (i = 0; i < n2; ++i)
154         {
155             l2[i] = i + 1;
156         }
157
158         mustFree = 1;
159     }
160
161     if (nbInputArgument(pvApiCtx) >= 3)
162     {
163         //get variable address
164         sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddr2);
165         if (sciErr.iErr)
166         {
167             printError(&sciErr, 0);
168             return 1;
169         }
170
171         // Retrieve a matrix of double at position 2.
172         sciErr = getMatrixOfDouble(pvApiCtx, piAddr2, &m2, &n2, &l2);
173         if (sciErr.iErr)
174         {
175             Scierror(202, _("%s: Wrong type for argument #%d: A real expected.\n"), fname, 2);
176             printError(&sciErr, 0);
177             return 1;
178         }
179
180         if (m1 * n1 == 0)
181         {
182             AssignOutputVariable(pvApiCtx, 1) = 0;
183             ReturnArguments(pvApiCtx);
184             return 0;
185         }
186
187         /*     third argument can be a matrix z or a list list(z,zcol) */
188         sciErr = getVarAddressFromPosition(pvApiCtx, 3, &piAddr3);
189         if (sciErr.iErr)
190         {
191             printError(&sciErr, 0);
192             return 1;
193         }
194
195         switch (getInputArgumentType(pvApiCtx, 3))
196         {
197             case sci_matrix :
198                 //get variable address
199                 sciErr = getVarAddressFromPosition(pvApiCtx, 3, &piAddr3);
200                 if (sciErr.iErr)
201                 {
202                     printError(&sciErr, 0);
203                     return 1;
204                 }
205
206                 // Retrieve a matrix of double at position 3.
207                 sciErr = getMatrixOfDouble(pvApiCtx, piAddr3, &m3, &n3, &l3);
208                 if (sciErr.iErr)
209                 {
210                     Scierror(202, _("%s: Wrong type for argument #%d: A real expected.\n"), fname, 3);
211                     printError(&sciErr, 0);
212                     return 1;
213                 }
214
215                 izcol = 0;
216                 break;
217             case sci_list :
218                 izcol = 1;
219                 /* z = list(z,colors) */
220                 sciErr = getListItemNumber(pvApiCtx, piAddr3, &m3l);
221                 if (sciErr.iErr)
222                 {
223                     Scierror(202, _("%s: Wrong type for argument #%d: A real expected.\n"), fname, 3);
224                     printError(&sciErr, 0);
225                     return 1;
226                 }
227
228                 if (m3l != 2)
229                 {
230                     Scierror(999, _("%s: Wrong size for input argument #%d: List of size %d expected.\n"),
231                              fname, 2, m3l, 2);
232                     return 1;
233                 }
234
235                 sciErr = getListItemAddress(pvApiCtx, piAddr3, 1, &piAddr31);
236                 if (sciErr.iErr)
237                 {
238                     printError(&sciErr, 0);
239                     return 1;
240                 }
241
242                 sciErr = getMatrixOfDouble(pvApiCtx, piAddr31, &m3, &n3, &l3); /* z */
243                 if (sciErr.iErr)
244                 {
245                     Scierror(202, _("%s: Wrong type for argument #%d: A real expected.\n"), fname, 3);
246                     printError(&sciErr, 0);
247                     return 1;
248                 }
249
250                 sciErr = getListItemAddress(pvApiCtx, piAddr3, 2, &piAddr32);
251                 if (sciErr.iErr)
252                 {
253                     printError(&sciErr, 0);
254                     return 1;
255                 }
256
257                 sciErr = getMatrixOfDouble(pvApiCtx, piAddr32, &m3n, &n3n, &l3n); /* z */
258                 if (sciErr.iErr)
259                 {
260                     Scierror(202, _("%s: Wrong type for argument #%d: A real expected.\n"), fname, 3);
261                     printError(&sciErr, 0);
262                     return 1;
263                 }
264
265                 zcol  = (l3n);
266                 if (m3n * n3n != n3 &&  m3n * n3n != m3 * n3)
267                 {
268                     Scierror(999, _("%s: Wrong size for input argument #%d: %d or %d expected.\n"), fname, 3, n3, m3 * n3);
269                     return 1;
270                 }
271                 /*
272                  *   Added by E Segre 4/5/2000. In the case where zcol is a
273                  *   matrix of the same size as z, we set izcol to 2. This
274                  *   value is later transmitted to the C2F(fac3dg) routine,
275                  *   which has been modified to do the interpolated shading
276                  *    (see the file SCI/modules/graphics/src/c/Plo3d.c
277                  */
278                 if (m3n * n3n == m3 * n3)
279                 {
280                     izcol = 2 ;
281                 }
282                 break;
283             default :
284                 OverLoad(3);
285                 return 0;
286         }
287     }
288
289     if (m1 * n1 == m3 * n3 && m1 * n1 == m2 * n2 && m1 * n1 != 1)
290     {
291         if (! (m1 == m2 && m2 == m3 && n1 == n2 && n2 == n3))
292         {
293             Scierror(999, _("%s: Wrong value for input arguments #%d, #%d and #%d: Incompatible length.\n"), fname, 1, 2, 3);
294             return 1;
295         }
296     }
297     else
298     {
299         if (m2 * n2 != n3)
300         {
301             Scierror(999, _("%s: Wrong value for input arguments #%d and #%d: Incompatible length.\n"), fname, 2, 3);
302             return 1;
303         }
304
305         if (m1 * n1 != m3)
306         {
307             Scierror(999, _("%s: Wrong value for input arguments #%d and #%d: Incompatible length.\n"), fname, 1, 3);
308             return 1;
309         }
310
311         if (m1 * n1 <= 1 || m2 * n2 <= 1)
312         {
313             Scierror(999, _("%s: Wrong size for input arguments #%d and #%d: %s expected.\n"), fname, 2, 3, ">= 2");
314             return 1;
315         }
316     }
317
318     if (m1 * n1 == 0 || m2 * n2 == 0 || m3 * n3 == 0)
319     {
320         AssignOutputVariable(pvApiCtx, 1) = 0;
321         ReturnArguments(pvApiCtx);
322         return 0;
323     }
324
325     iflag_def[1] = 8;
326
327     if (get_optional_double_arg(pvApiCtx, fname, 4, "theta", &theta, 1, opts) == 0)
328     {
329         return 0;
330     }
331     if (get_optional_double_arg(pvApiCtx, fname, 5, "alpha", &alpha, 1, opts) == 0)
332     {
333         return 0;
334     }
335     if (get_labels_arg(pvApiCtx, fname, 6, opts, &legend) == 0)
336     {
337         return 0;
338     }
339     freeLegend = !isDefLegend(legend);
340     if (get_optional_int_arg(pvApiCtx, fname, 7, "flag", &iflag, 3, opts) == 0)
341     {
342         if (freeLegend)
343         {
344             freeAllocatedSingleString(legend);
345         }
346         return 0;
347     }
348     if (get_optional_double_arg(pvApiCtx, fname, 8, "ebox", &ebox, 6, opts) == 0)
349     {
350         if (freeLegend)
351         {
352             freeAllocatedSingleString(legend);
353         }
354         return 0;
355     }
356
357
358     getOrCreateDefaultSubwin();
359
360     /******************** 24/05/2002 ********************/
361     if (m1 * n1 == m3 * n3 && m1 * n1 == m2 * n2 && m1 * n1 != 1) /* NG beg */
362     {
363         isfac = 1;
364     }
365     else
366     {
367         isfac = 0;
368     }
369
370
371     Objplot3d (fname, &isfac, &izcol, (l1), (l2), (l3), zcol, &m3, &n3, theta, alpha, legend, iflag, ebox, &m1, &n1, &m2, &n2, &m3, &n3, &m3n, &n3n); /*Adding F.Leray 12.03.04 and 19.03.04*/
372
373     if (mustFree)
374     {
375         FREE(l1);
376         FREE(l2);
377     }
378
379     if (freeLegend)
380     {
381         freeAllocatedSingleString(legend);
382     }
383     AssignOutputVariable(pvApiCtx, 1) = 0;
384     ReturnArguments(pvApiCtx);
385     return 0;
386
387 }
388 /*--------------------------------------------------------------------------*/