* Bug #14159 fixed - Matplot crashed Scilab on boolean input.
[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 "int.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         return Overload::call(L"%_Matplot", in, _iRetCount, out);
69     }
70
71     if (in.size() > 5)
72     {
73         Scierror(999, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "Matplot", 1, 5);
74         return types::Function::Error;
75     }
76
77     if (in[0]->isDouble())
78     {
79         types::Double *pIn = in[0]->getAs<types::Double>();
80         l1 = (void*) pIn->get();
81         if (pIn->getDims() > 2)
82         {
83             dims = pIn->getDimsArray();
84             if (pIn->getDims() > 3 || (dims[2] != 1 && dims[2] != 3 && dims[2] != 4))
85             {
86                 Scierror(999, _("%s: Wrong type for input argument #%d: A real or integer expected.\n"), "Matplot", 1);
87                 return types::Function::Error;
88             }
89
90             m1 = dims[0];
91             n1 = dims[1];
92             if (dims[2] == 1)
93             {
94                 plottype = buildMatplotType(MATPLOT_HM1_Double, MATPLOT_FORTRAN, MATPLOT_GRAY);
95             }
96             else if (dims[2] == 3)
97             {
98                 plottype = buildMatplotType(MATPLOT_HM3_Double, MATPLOT_FORTRAN, MATPLOT_RGB);
99             }
100             else
101             {
102                 plottype = buildMatplotType(MATPLOT_HM4_Double, MATPLOT_FORTRAN, MATPLOT_RGBA);
103             }
104         }
105         else
106         {
107             m1 = pIn->getRows();
108             n1 = pIn->getCols();
109             plottype = buildMatplotType(MATPLOT_Double, MATPLOT_FORTRAN, MATPLOT_INDEX);
110         }
111     }
112     else if (in[0]->isInt8())
113     {
114         types::Int8 *pIn = in[0]->getAs<types::Int8>();
115         l1 = (void*) pIn->get();
116         if (pIn->getDims() > 2)
117         {
118             dims = pIn->getDimsArray();
119             if (pIn->getDims() > 3 || (dims[2] != 1 && dims[2] != 3 && dims[2] != 4))
120             {
121                 Scierror(999, _("%s: Wrong type for input argument #%d: A real or integer expected.\n"), "Matplot", 1);
122                 return types::Function::Error;
123             }
124
125             m1 = dims[0];
126             n1 = dims[1];
127             if (dims[2] == 1)
128             {
129                 plottype = buildMatplotType(MATPLOT_HM1_Char, MATPLOT_FORTRAN, MATPLOT_GRAY);
130             }
131             else if (dims[2] == 3)
132             {
133                 plottype = buildMatplotType(MATPLOT_HM3_Char, MATPLOT_FORTRAN, MATPLOT_RGB);
134             }
135             else
136             {
137                 plottype = buildMatplotType(MATPLOT_HM4_Char, MATPLOT_FORTRAN, MATPLOT_RGBA);
138             }
139         }
140         else
141         {
142             m1 = pIn->getRows();
143             n1 = pIn->getCols();
144             plottype = buildMatplotType(MATPLOT_Char, MATPLOT_FORTRAN, MATPLOT_RGB_332);
145         }
146     }
147     else if (in[0]->isUInt8())
148     {
149         types::UInt8 *pIn = in[0]->getAs<types::UInt8>();
150         l1 = (void*) pIn->get();
151         if (pIn->getDims() > 2)
152         {
153             dims = pIn->getDimsArray();
154             if (pIn->getDims() > 3 || (dims[2] != 1 && dims[2] != 3 && dims[2] != 4))
155             {
156                 Scierror(999, _("%s: Wrong type for input argument #%d: A real or integer expected.\n"), "Matplot", 1);
157                 return types::Function::Error;
158             }
159
160             m1 = dims[0];
161             n1 = dims[1];
162             if (dims[2] == 1)
163             {
164                 plottype = buildMatplotType(MATPLOT_HM1_UChar, MATPLOT_FORTRAN, MATPLOT_GRAY);
165             }
166             else if (dims[2] == 3)
167             {
168                 plottype = buildMatplotType(MATPLOT_HM3_UChar, MATPLOT_FORTRAN, MATPLOT_RGB);
169             }
170             else
171             {
172                 plottype = buildMatplotType(MATPLOT_HM4_UChar, MATPLOT_FORTRAN, MATPLOT_RGBA);
173             }
174         }
175         else
176         {
177             m1 = pIn->getRows();
178             n1 = pIn->getCols();
179             plottype = buildMatplotType(MATPLOT_UChar, MATPLOT_FORTRAN, MATPLOT_GRAY);
180         }
181     }
182     else if (in[0]->isInt16())
183     {
184         types::Int16 *pIn = in[0]->getAs<types::Int16>();
185         l1 = (void*) pIn->get();
186         m1 = pIn->getRows();
187         n1 = pIn->getCols();
188         plottype = buildMatplotType(MATPLOT_Short, MATPLOT_FORTRAN, MATPLOT_RGB_444);
189     }
190     else if (in[0]->isUInt16())
191     {
192         types::UInt16 *pIn = in[0]->getAs<types::UInt16>();
193         l1 = (void*) pIn->get();
194         m1 = pIn->getRows();
195         n1 = pIn->getCols();
196         plottype = buildMatplotType(MATPLOT_UShort, MATPLOT_FORTRAN, MATPLOT_RGBA_4444);
197     }
198     else if ((in[0]->isInt32()) || (in[0]->isInt64()))
199     {
200         types::Int32 *pIn = in[0]->getAs<types::Int32>();
201         l1 = (void*) pIn->get();
202         m1 = pIn->getRows();
203         n1 = pIn->getCols();
204         plottype = buildMatplotType(MATPLOT_Int, MATPLOT_FORTRAN, MATPLOT_RGB);
205     }
206     else if ((in[0]->isUInt32()) || (in[0]->isUInt64()))
207     {
208         types::UInt32 *pIn = in[0]->getAs<types::UInt32>();
209         l1 = (void*) pIn->get();
210         m1 = pIn->getRows();
211         n1 = pIn->getCols();
212         plottype = buildMatplotType(MATPLOT_UInt, MATPLOT_FORTRAN, MATPLOT_RGBA);
213     }
214     else
215     {
216         Scierror(999, _("%s: Wrong type for input argument #%d: A real or integer expected.\n"), "Matplot", 1);
217         return types::Function::Error;
218     }
219
220     if (in.size() > 1)
221     {
222         if (in[1]->isString() == false)
223         {
224             Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), "Matplot1", 2);
225             return types::Function::Error;
226         }
227
228         strf =  wide_string_to_UTF8(in[1]->getAs<types::String>()->get(0));
229         bFREE = true;
230         if (in.size() > 2)
231         {
232             if (in[2]->isDouble() == false)
233             {
234                 if (bFREE)
235                 {
236                     FREE(strf);
237                 }
238                 Scierror(999, _("%s: Wrong type for input argument #%d: A real expected.\n"), "Matplot1", 3);
239                 return types::Function::Error;
240             }
241
242             rect =  in[2]->getAs<types::Double>()->get();
243             if (in.size() > 3)
244             {
245                 if (in[3]->isDouble() == false)
246                 {
247                     if (bFREE)
248                     {
249                         FREE(strf);
250                     }
251                     Scierror(999, _("%s: Wrong type for input argument #%d: A real expected.\n"), "Matplot1", 4);
252                     return types::Function::Error;
253                 }
254
255                 types::Double* pDbl = in[3]->getAs<types::Double>();
256                 double* pdbl = pDbl->get();
257                 int iSize = pDbl->getSize();
258                 nax = new int[iSize];
259                 for (int i = 0; i < iSize; i++)
260                 {
261                     nax[i] = (int)pdbl[i];
262                 }
263
264                 flagNax = TRUE;
265             }
266         }
267     }
268
269     if (opt.size() > 4)
270     {
271         if (bFREE)
272         {
273             FREE(strf);
274         }
275
276         Scierror(999, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "Matplot", 1, 5);
277         return types::Function::Error;
278     }
279
280     // get optional argument if necessary
281     for (int i = 0; i < opt.size(); i++)
282     {
283         if (opt[i].first == L"strf")
284         {
285             if (opt[i].second->isString() == false)
286             {
287                 if (bFREE)
288                 {
289                     FREE(strf);
290                 }
291
292                 if (nax)
293                 {
294                     delete[] nax;
295                 }
296
297                 if (frameflag)
298                 {
299                     delete[] frameflag;
300                 }
301
302                 if (axesflag)
303                 {
304                     delete[] axesflag;
305                 }
306                 Scierror(999, _("%s: Wrong type for input argument #%ls: A string expected.\n"), "Matplot1", opt[i].first.c_str());
307                 return types::Function::Error;
308             }
309
310             if (strf)
311             {
312                 continue;
313             }
314
315             strf =  wide_string_to_UTF8(opt[i].second->getAs<types::String>()->get(0));
316             bFREE = true;
317         }
318         else
319         {
320             if (opt[i].second->isDouble() == false)
321             {
322                 if (bFREE)
323                 {
324                     FREE(strf);
325                 }
326
327                 if (nax)
328                 {
329                     delete[] nax;
330                 }
331
332                 if (frameflag)
333                 {
334                     delete[] frameflag;
335                 }
336
337                 if (axesflag)
338                 {
339                     delete[] axesflag;
340                 }
341                 Scierror(999, _("%s: Wrong type for input argument #%ls: A matrix expected.\n"), "Matplot1", opt[i].first.c_str());
342                 return types::Function::Error;
343             }
344
345             types::Double* pDbl = opt[i].second->getAs<types::Double>();
346             double* pdbl = pDbl->get();
347             int iSize = pDbl->getSize();
348
349             if (opt[i].first == L"rect" && rect == NULL)
350             {
351                 rect = pdbl;
352             }
353             else if (opt[i].first == L"nax" && nax == NULL)
354             {
355                 nax = new int[iSize];
356                 for (int i = 0; i < iSize; i++)
357                 {
358                     nax[i] = (int)pdbl[i];
359                 }
360                 flagNax = TRUE;
361             }
362             else if (opt[i].first == L"frameflag" && frameflag == NULL)
363             {
364                 frameflag = new int[iSize];
365                 for (int i = 0; i < iSize; i++)
366                 {
367                     frameflag[i] = (int)pdbl[i];
368                 }
369             }
370             else if (opt[i].first == L"axesflag" && axesflag == NULL)
371             {
372                 axesflag = new int[iSize];
373                 for (int i = 0; i < iSize; i++)
374                 {
375                     axesflag[i] = (int)pdbl[i];
376                 }
377             }
378         }
379     }
380
381     getOrCreateDefaultSubwin();
382
383     if (strf == NULL)
384     {
385         reinitDefStrfN();
386
387         strcpy(strfl, DEFSTRFN);
388         strf = strfl;
389
390         if (!isDefRect(rect))
391         {
392             strfl[1] = '7';
393         }
394
395         if (frameflag != &frame_def)
396         {
397             strfl[1] = (char)(*frame + 48);
398         }
399
400         if (axesflag != &axes_def)
401         {
402             strfl[2] = (char)(*axes + 48);
403         }
404     }
405
406     ObjmatplotImage(l1, &m1, &n1, strf, rect, nax, flagNax, plottype);
407
408     if (bFREE)
409     {
410         FREE(strf);
411     }
412
413     if (nax)
414     {
415         delete[] nax;
416     }
417
418     if (frameflag)
419     {
420         delete[] frameflag;
421     }
422
423     if (axesflag)
424     {
425         delete[] axesflag;
426     }
427
428     return types::Function::OK;
429 }
430 /*--------------------------------------------------------------------------*/