fix 'some' memory leaks @startup
[scilab.git] / scilab / modules / graphics / sci_gateway / cpp / sci_matplot.cpp
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) 2014 - Scilab Enterprises - Anais AUBERT
6  *
7  * This file must be used under the terms of the CeCILL.
8  * This source file is licensed as described in the file COPYING, which
9  * you should have received as part of this distribution.  The terms
10  * are also available at
11  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
12  *
13  */
14
15 /*------------------------------------------------------------------------*/
16 /* file: sci_matplot.h                                                    */
17 /* desc : interface for matplot routine                                   */
18 /*------------------------------------------------------------------------*/
19
20 #include "graphics_gw.hxx"
21 #include "function.hxx"
22 #include "double.hxx"
23 #include "string.hxx"
24 #include "graphichandle.hxx"
25 #include "overload.hxx"
26 #include "execvisitor.hxx"
27
28 extern "C"
29 {
30 #include <string.h>
31 #include "gw_graphics.h"
32 #include "GetCommandArg.h"
33 #include "DefaultCommandArg.h"
34 #include "BuildObjects.h"
35 #include "sciCall.h"
36 #include "api_scilab.h"
37 #include "localization.h"
38 #include "Scierror.h"
39 #include "Matplot.h"
40 }
41
42 /*--------------------------------------------------------------------------*/
43 types::Function::ReturnValue sci_matplot(types::typed_list &in, types::optional_list &opt, int _iRetCount, types::typed_list &out)
44 {
45     int m1 = 0;
46     int n1 = 0;
47     int *dims = NULL;
48     int frame_def = 8;
49     int *frame = &frame_def;
50     int axes_def = 1;
51     int *axes = &axes_def;
52     int *frameflag = NULL;
53     int *axesflag  = NULL;
54
55     char* strf      = NULL ;
56     char strfl[4];
57     double* rect    = NULL ;
58     int* nax        = NULL ;
59     BOOL flagNax    = FALSE;
60
61     void* l1 = NULL;
62     int plottype = -1;
63
64     bool bFREE = false;
65
66     if (in.size() < 1)
67     {
68         ast::ExecVisitor exec;
69         return Overload::call(L"%_Matplot", in, _iRetCount, out, &exec);
70
71     }
72     else if (in.size() > 5)
73     {
74         Scierror(999, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "Matplot", 1, 5);
75         return types::Function::Error;
76     }
77
78     if (in[0]->isDouble())
79     {
80         types::Double *pIn = in[0]->getAs<types::Double>();
81         l1 = (void*) pIn->get();
82         if (pIn->getDims() > 2)
83         {
84
85             dims = pIn->getDimsArray();
86             if (pIn->getDims() > 3 || (dims[2] != 1 && dims[2] != 3 && dims[2] != 4))
87             {
88                 Scierror(999, _("%s: Wrong type for input argument #%d: A real or integer expected.\n"), "Matplot", 1);
89                 return types::Function::Error;
90             }
91
92             m1 = dims[0];
93             n1 = dims[1];
94             if (dims[2] == 1)
95             {
96                 plottype = buildMatplotType(MATPLOT_HM1_Double, MATPLOT_FORTRAN, MATPLOT_GRAY);
97             }
98             else if (dims[2] == 3)
99             {
100                 plottype = buildMatplotType(MATPLOT_HM3_Double, MATPLOT_FORTRAN, MATPLOT_RGB);
101             }
102             else
103             {
104                 plottype = buildMatplotType(MATPLOT_HM4_Double, MATPLOT_FORTRAN, MATPLOT_RGBA);
105             }
106         }
107         else
108         {
109             m1 = pIn->getRows();
110             n1 = pIn->getCols();
111             plottype = buildMatplotType(MATPLOT_Double, MATPLOT_FORTRAN, MATPLOT_INDEX);
112         }
113     }
114     else if (in[0]->isInt8())
115     {
116         types::Int8 *pIn = in[0]->getAs<types::Int8>();
117         l1 = (void*) pIn->get();
118         if (pIn->getDims() > 2)
119         {
120
121             dims = pIn->getDimsArray();
122             if (pIn->getDims() > 3 || (dims[2] != 1 && dims[2] != 3 && dims[2] != 4))
123             {
124                 Scierror(999, _("%s: Wrong type for input argument #%d: A real or integer expected.\n"), "Matplot", 1);
125                 return types::Function::Error;
126             }
127
128             m1 = dims[0];
129             n1 = dims[1];
130             if (dims[2] == 1)
131             {
132                 plottype = buildMatplotType(MATPLOT_HM1_Char, MATPLOT_FORTRAN, MATPLOT_GRAY);
133             }
134             else if (dims[2] == 3)
135             {
136                 plottype = buildMatplotType(MATPLOT_HM1_Char, MATPLOT_FORTRAN, MATPLOT_RGB);
137             }
138             else
139             {
140                 plottype = buildMatplotType(MATPLOT_HM1_Char, MATPLOT_FORTRAN, MATPLOT_RGBA);
141             }
142         }
143         else
144         {
145             m1 = pIn->getRows();
146             n1 = pIn->getCols();
147             plottype = buildMatplotType(MATPLOT_Char, MATPLOT_FORTRAN, MATPLOT_INDEX);
148         }
149     }
150     else if (in[0]->isUInt8())
151     {
152         types::UInt8 *pIn = in[0]->getAs<types::UInt8>();
153         l1 = (void*) pIn->get();
154         if (pIn->getDims() > 2)
155         {
156
157             dims = pIn->getDimsArray();
158             if (pIn->getDims() > 3 || (dims[2] != 1 && dims[2] != 3 && dims[2] != 4))
159             {
160                 Scierror(999, _("%s: Wrong type for input argument #%d: A real or integer expected.\n"), "Matplot", 1);
161                 return types::Function::Error;
162             }
163
164             m1 = dims[0];
165             n1 = dims[1];
166             if (dims[2] == 1)
167             {
168                 plottype = buildMatplotType(MATPLOT_HM1_UChar, MATPLOT_FORTRAN, MATPLOT_GRAY);
169             }
170             else if (dims[2] == 3)
171             {
172                 plottype = buildMatplotType(MATPLOT_HM1_UChar, MATPLOT_FORTRAN, MATPLOT_RGB);
173             }
174             else
175             {
176                 plottype = buildMatplotType(MATPLOT_HM1_UChar, MATPLOT_FORTRAN, MATPLOT_RGBA);
177             }
178         }
179         else
180         {
181             m1 = pIn->getRows();
182             n1 = pIn->getCols();
183             plottype = buildMatplotType(MATPLOT_UChar, MATPLOT_FORTRAN, MATPLOT_INDEX);
184         }
185     }
186     else if (in[0]->isInt16())
187     {
188         types::Int16 *pIn = in[0]->getAs<types::Int16>();
189         l1 = (void*) pIn->get();
190         m1 = pIn->getRows();
191         n1 = pIn->getCols();
192         plottype = buildMatplotType(MATPLOT_Short, MATPLOT_FORTRAN, MATPLOT_INDEX);
193     }
194     else if (in[0]->isUInt16())
195     {
196         types::UInt16 *pIn = in[0]->getAs<types::UInt16>();
197         l1 = (void*) pIn->get();
198         m1 = pIn->getRows();
199         n1 = pIn->getCols();
200         plottype = buildMatplotType(MATPLOT_UShort, MATPLOT_FORTRAN, MATPLOT_INDEX);
201     }
202     else if ((in[0]->isInt32()) || (in[0]->isInt64()))
203     {
204         types::Int32 *pIn = in[0]->getAs<types::Int32>();
205         l1 = (void*) pIn->get();
206         m1 = pIn->getRows();
207         n1 = pIn->getCols();
208         plottype = buildMatplotType(MATPLOT_Int, MATPLOT_FORTRAN, MATPLOT_INDEX);
209     }
210     else if ((in[0]->isUInt32()) || (in[0]->isUInt64()))
211     {
212         types::UInt32 *pIn = in[0]->getAs<types::UInt32>();
213         l1 = (void*) pIn->get();
214         m1 = pIn->getRows();
215         n1 = pIn->getCols();
216         plottype = buildMatplotType(MATPLOT_UInt, MATPLOT_FORTRAN, MATPLOT_INDEX);
217     }
218
219     if (in.size() > 1)
220     {
221         if (in[1]->isString() == false)
222         {
223             Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), "Matplot1", 2);
224             return types::Function::Error;
225
226         }
227         strf =  wide_string_to_UTF8(in[1]->getAs<types::String>()->get(0));
228         bFREE = true;
229         if (in.size() > 2)
230         {
231             if (in[2]->isDouble() == false)
232             {
233                 Scierror(999, _("%s: Wrong type for input argument #%d: A real expected.\n"), "Matplot1", 3);
234                 return types::Function::Error;
235
236             }
237
238             rect =  in[2]->getAs<types::Double>()->get();
239             if (in.size() > 3)
240             {
241                 if (in[3]->isDouble() == false)
242                 {
243                     Scierror(999, _("%s: Wrong type for input argument #%d: A real expected.\n"), "Matplot1", 4);
244                     return types::Function::Error;
245
246                 }
247
248                 types::Double* pDbl = in[3]->getAs<types::Double>();
249                 double* pdbl = pDbl->get();
250                 int iSize = pDbl->getSize();
251                 nax = new int[iSize];
252                 for (int i = 0; i < iSize; i++)
253                 {
254                     nax[i] = (int)pdbl[i];
255                 }
256
257                 flagNax = TRUE;
258             }
259         }
260     }
261
262     if (opt.size() > 4)
263     {
264         Scierror(999, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "Matplot", 1, 5);
265         return types::Function::Error;
266     }
267
268     // get optional argument if necessary
269     for (int i = 0; i < opt.size(); i++)
270     {
271         if (opt[i].first == L"strf")
272         {
273             if (opt[i].second->isString() == false)
274             {
275                 Scierror(999, _("%s: Wrong type for input argument #%ls: A string expected.\n"), "Matplot1", opt[i].first.c_str());
276                 return types::Function::Error;
277             }
278
279             if (strf)
280             {
281                 continue;
282             }
283
284             strf =  wide_string_to_UTF8(opt[i].second->getAs<types::String>()->get(0));
285             bFREE = true;
286         }
287         else
288         {
289             if (opt[i].second->isDouble() == false)
290             {
291                 Scierror(999, _("%s: Wrong type for input argument #%ls: A matrix expected.\n"), "Matplot1", opt[i].first.c_str());
292                 return types::Function::Error;
293             }
294
295             types::Double* pDbl = opt[i].second->getAs<types::Double>();
296             double* pdbl = pDbl->get();
297             int iSize = pDbl->getSize();
298
299             if (opt[i].first == L"rect" && rect == NULL)
300             {
301                 rect = pdbl;
302             }
303             else if (opt[i].first == L"nax" && nax == NULL)
304             {
305                 nax = new int[iSize];
306                 for (int i = 0; i < iSize; i++)
307                 {
308                     nax[i] = (int)pdbl[i];
309                 }
310                 flagNax = TRUE;
311             }
312             else if (opt[i].first == L"frameflag" && frameflag == NULL)
313             {
314                 frameflag = new int[iSize];
315                 for (int i = 0; i < iSize; i++)
316                 {
317                     frameflag[i] = (int)pdbl[i];
318                 }
319             }
320             else if (opt[i].first == L"axesflag" && axesflag == NULL)
321             {
322                 axesflag = new int[iSize];
323                 for (int i = 0; i < iSize; i++)
324                 {
325                     axesflag[i] = (int)pdbl[i];
326                 }
327             }
328         }
329     }
330
331     getOrCreateDefaultSubwin();
332
333     if (strf == NULL)
334     {
335         reinitDefStrfN();
336
337         strcpy(strfl, DEFSTRFN);
338         strf = strfl;
339
340         if (!isDefRect(rect))
341         {
342             strfl[1] = '7';
343         }
344
345         if (frameflag != &frame_def)
346         {
347             strfl[1] = (char)(*frame + 48);
348         }
349
350         if (axesflag != &axes_def)
351         {
352             strfl[2] = (char)(*axes + 48);
353         }
354     }
355
356     ObjmatplotImage(l1, &m1, &n1, strf, rect, nax, flagNax, plottype);
357
358     if (bFREE)
359     {
360         FREE(strf);
361     }
362
363     if (nax)
364     {
365         delete[] nax;
366     }
367
368     if (frameflag)
369     {
370         delete[] frameflag;
371     }
372
373     if (axesflag)
374     {
375         delete[] axesflag;
376     }
377
378     return types::Function::OK;
379 }
380 /*--------------------------------------------------------------------------*/