1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2006 - INRIA - Allan CORNET
4 * Copyright (C) 2012 - INRIA - Serge STEER
5 *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14 *
15 */
16 #include "callfftw.h"
17 /*--------------------------------------------------------------------------*/
18 #include "dynamiclibrary.h"
19 #include "getshortpathname.h"
20 #include "sci_malloc.h"
21 #include "charEncoding.h"
22 /*--------------------------------------------------------------------------*/
23 typedef void (*PROC_FFTW_EXECUTE_SPLIT_DFT)     (const fftw_plan p, double *ri, double *ii, double *ro, double *io);
24 typedef void (*PROC_FFTW_EXECUTE_SPLIT_DFT_C2R) (const fftw_plan p, double *ri, double *ii, double *ro);
25 typedef void (*PROC_FFTW_EXECUTE_SPLIT_DFT_R2C) (const fftw_plan p, double *ri,             double *ro, double *io);
26 typedef void (*PROC_FFTW_EXECUTE_SPLIT_DFT_R2R) (const fftw_plan p, double *ri,             double *ro);
27 typedef fftw_plan (*PROC_FFTW_PLAN_GURU_SPLIT_DFT) (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ii, double *ro, double *io, unsigned flags);
28 typedef fftw_plan (*PROC_FFTW_PLAN_GURU_SPLIT_DFT_C2R) (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ii, double *ro, unsigned flags);
29 typedef fftw_plan (*PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2C) (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ro, double *io, unsigned flags);
30 typedef fftw_plan (*PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2R) (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ro, fftw_r2r_kind *kind, unsigned flags);
31 typedef void (*PROC_FFTW_DESTROY_PLAN) (fftw_plan p);
32 typedef char *(*PROC_FFTW_EXPORT_WISDOM_TO_STRING) (void);
33 typedef int (*PROC_FFTW_IMPORT_WISDOM_FROM_STRING) (const char *input_string);
34 typedef void (*PROC_FFTW_FORGET_WISDOM) (void);
35 /*--------------------------------------------------------------------------*/
36 static DynLibHandle hinstLib = NULL;
37 static PROC_FFTW_EXECUTE_SPLIT_DFT       MY_FFTW_EXECUTE_SPLIT_DFT       = NULL;
38 static PROC_FFTW_EXECUTE_SPLIT_DFT_C2R   MY_FFTW_EXECUTE_SPLIT_DFT_C2R   = NULL;
39 static PROC_FFTW_EXECUTE_SPLIT_DFT_R2C   MY_FFTW_EXECUTE_SPLIT_DFT_R2C   = NULL;
40 static PROC_FFTW_EXECUTE_SPLIT_DFT_R2R   MY_FFTW_EXECUTE_SPLIT_DFT_R2R   = NULL;
41 static PROC_FFTW_PLAN_GURU_SPLIT_DFT     MY_FFTW_PLAN_GURU_SPLIT_DFT     = NULL;
42 static PROC_FFTW_PLAN_GURU_SPLIT_DFT_C2R MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R = NULL;
43 static PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2C MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C = NULL;
44 static PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2R MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R = NULL;
45 static PROC_FFTW_DESTROY_PLAN            MY_FFTW_DESTROY_PLAN            = NULL;
46 static PROC_FFTW_EXPORT_WISDOM_TO_STRING MY_FFTW_EXPORT_WISDOM_TO_STRING = NULL;
47 static PROC_FFTW_IMPORT_WISDOM_FROM_STRING MY_FFTW_IMPORT_WISDOM_FROM_STRING = NULL;
48 static PROC_FFTW_FORGET_WISDOM MY_FFTW_FORGET_WISDOM = NULL;
49 /*--------------------------------------------------------------------------*/
IsLoadedFFTW(void)50 BOOL IsLoadedFFTW(void)
51 {
52     if ( (MY_FFTW_EXECUTE_SPLIT_DFT) && (MY_FFTW_PLAN_GURU_SPLIT_DFT) && (MY_FFTW_DESTROY_PLAN) &&
53             (MY_FFTW_EXPORT_WISDOM_TO_STRING) && (MY_FFTW_IMPORT_WISDOM_FROM_STRING) &&
54             (MY_FFTW_FORGET_WISDOM) )
55     {
56         return TRUE;
57     }
58     return FALSE;
59 }
60 /*--------------------------------------------------------------------------*/
LoadFFTWLibrary(const char * libraryname)61 BOOL LoadFFTWLibrary(const char* libraryname)
62 {
63 
64     if (libraryname == NULL)
65     {
66         return FALSE;
67     }
68     if (hinstLib == NULL)
69     {
70 #ifdef _MSC_VER
71         {
72             wchar_t * wclibraryname = to_wide_string(libraryname);
73             if (wclibraryname)
74             {
75                 hinstLib = LoadDynLibraryW(wclibraryname);
76                 FREE(wclibraryname);
77                 wclibraryname = NULL;
78             }
79         }
80 #else
81         hinstLib = LoadDynLibrary(libraryname);
82 #endif
83         MY_FFTW_EXECUTE_SPLIT_DFT        = NULL;
84         MY_FFTW_EXECUTE_SPLIT_DFT_C2R    = NULL;
85         MY_FFTW_EXECUTE_SPLIT_DFT_R2C    = NULL;
86         MY_FFTW_EXECUTE_SPLIT_DFT_R2R    = NULL;
87 
88         MY_FFTW_PLAN_GURU_SPLIT_DFT      = NULL;
89         MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R  = NULL;
90         MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C  = NULL;
91         MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R  = NULL;
92 
93         MY_FFTW_DESTROY_PLAN             = NULL;
94 
95         MY_FFTW_EXPORT_WISDOM_TO_STRING  = NULL;
96         MY_FFTW_IMPORT_WISDOM_FROM_STRING = NULL;
97         MY_FFTW_FORGET_WISDOM            = NULL;
98 
99         MY_FFTW_EXECUTE_SPLIT_DFT     = (PROC_FFTW_EXECUTE_SPLIT_DFT)     GetDynLibFuncPtr(hinstLib, "fftw_execute_split_dft");
100         MY_FFTW_EXECUTE_SPLIT_DFT_C2R = (PROC_FFTW_EXECUTE_SPLIT_DFT_C2R) GetDynLibFuncPtr(hinstLib, "fftw_execute_split_dft_c2r");
101         MY_FFTW_EXECUTE_SPLIT_DFT_R2C = (PROC_FFTW_EXECUTE_SPLIT_DFT_R2C) GetDynLibFuncPtr(hinstLib, "fftw_execute_split_dft_r2c");
102         MY_FFTW_EXECUTE_SPLIT_DFT_R2R = (PROC_FFTW_EXECUTE_SPLIT_DFT_R2R) GetDynLibFuncPtr(hinstLib, "fftw_execute_r2r");
103 
104         MY_FFTW_PLAN_GURU_SPLIT_DFT     = (PROC_FFTW_PLAN_GURU_SPLIT_DFT)     GetDynLibFuncPtr(hinstLib, "fftw_plan_guru_split_dft");
105         MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R = (PROC_FFTW_PLAN_GURU_SPLIT_DFT_C2R) GetDynLibFuncPtr(hinstLib, "fftw_plan_guru_split_dft_c2r");
106         MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C = (PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2C) GetDynLibFuncPtr(hinstLib, "fftw_plan_guru_split_dft_r2c");
107         MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R = (PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2R) GetDynLibFuncPtr(hinstLib, "fftw_plan_guru_r2r");
108 
109 
110         MY_FFTW_DESTROY_PLAN = (PROC_FFTW_DESTROY_PLAN) GetDynLibFuncPtr(hinstLib, "fftw_destroy_plan");
111 
112         MY_FFTW_EXPORT_WISDOM_TO_STRING   = (PROC_FFTW_EXPORT_WISDOM_TO_STRING)   GetDynLibFuncPtr(hinstLib, "fftw_export_wisdom_to_string");
113         MY_FFTW_IMPORT_WISDOM_FROM_STRING = (PROC_FFTW_IMPORT_WISDOM_FROM_STRING) GetDynLibFuncPtr(hinstLib, "fftw_import_wisdom_from_string");
114         MY_FFTW_FORGET_WISDOM             = (PROC_FFTW_FORGET_WISDOM) GetDynLibFuncPtr(hinstLib, "fftw_forget_wisdom");
115     }
116 
117     return IsLoadedFFTW();
118 }
119 /*--------------------------------------------------------------------------*/
DisposeFFTWLibrary(void)120 BOOL DisposeFFTWLibrary(void)
121 {
122     BOOL fFreeResult;
123 
124     if (hinstLib)
125     {
126         fFreeResult = FreeDynLibrary(hinstLib);
127         hinstLib = NULL;
128     }
129 
130     if (MY_FFTW_EXECUTE_SPLIT_DFT)
131     {
132         MY_FFTW_EXECUTE_SPLIT_DFT = NULL;
133     }
134     if (MY_FFTW_EXECUTE_SPLIT_DFT_C2R)
135     {
136         MY_FFTW_EXECUTE_SPLIT_DFT_C2R = NULL;
137     }
138     if (MY_FFTW_EXECUTE_SPLIT_DFT_R2C)
139     {
140         MY_FFTW_EXECUTE_SPLIT_DFT_R2C = NULL;
141     }
142     if (MY_FFTW_EXECUTE_SPLIT_DFT_R2R)
143     {
144         MY_FFTW_EXECUTE_SPLIT_DFT_R2R = NULL;
145     }
146 
147     if (MY_FFTW_PLAN_GURU_SPLIT_DFT)
148     {
149         MY_FFTW_PLAN_GURU_SPLIT_DFT = NULL;
150     }
151     if (MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R)
152     {
153         MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R = NULL;
154     }
155     if (MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C)
156     {
157         MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C = NULL;
158     }
159     if (MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R)
160     {
161         MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R = NULL;
162     }
163 
164     if (MY_FFTW_DESTROY_PLAN)
165     {
166         MY_FFTW_DESTROY_PLAN = NULL;
167     }
168 
169     if (MY_FFTW_EXPORT_WISDOM_TO_STRING)
170     {
171         MY_FFTW_EXPORT_WISDOM_TO_STRING     = NULL;
172     }
173     if (MY_FFTW_IMPORT_WISDOM_FROM_STRING)
174     {
175         MY_FFTW_IMPORT_WISDOM_FROM_STRING = NULL;
176     }
177     if (MY_FFTW_FORGET_WISDOM)
178     {
179         MY_FFTW_FORGET_WISDOM                         = NULL;
180     }
181 
182     if ( !MY_FFTW_EXECUTE_SPLIT_DFT       && !MY_FFTW_EXECUTE_SPLIT_DFT_C2R     &&
183             !MY_FFTW_EXECUTE_SPLIT_DFT_R2C   && !MY_FFTW_EXECUTE_SPLIT_DFT_R2R     &&
184             !MY_FFTW_PLAN_GURU_SPLIT_DFT     && !MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R   &&
185             !MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C && !MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R   &&
186             !MY_FFTW_DESTROY_PLAN            &&
187             !MY_FFTW_EXPORT_WISDOM_TO_STRING && !MY_FFTW_IMPORT_WISDOM_FROM_STRING &&
188             !MY_FFTW_FORGET_WISDOM )
189     {
190         return TRUE;
191     }
192 
193     return FALSE;
194 }
195 /*--------------------------------------------------------------------------*/
call_fftw_execute_split_dft(const fftw_plan p,double * ri,double * ii,double * ro,double * io)196 void call_fftw_execute_split_dft (const fftw_plan p, double *ri, double *ii, double *ro, double *io)
197 {
198     if (MY_FFTW_EXECUTE_SPLIT_DFT)
199     {
200         (MY_FFTW_EXECUTE_SPLIT_DFT)(p, ri, ii, ro, io);
201     }
202 }
203 /*--------------------------------------------------------------------------*/
call_fftw_execute_split_dft_c2r(const fftw_plan p,double * ri,double * ii,double * ro)204 void call_fftw_execute_split_dft_c2r (const fftw_plan p, double *ri, double *ii, double *ro)
205 {
206     if (MY_FFTW_EXECUTE_SPLIT_DFT_C2R)
207     {
208         (MY_FFTW_EXECUTE_SPLIT_DFT_C2R)(p, ri, ii, ro);
209     }
210 }
211 /*--------------------------------------------------------------------------*/
call_fftw_execute_split_dft_r2c(const fftw_plan p,double * ri,double * ro,double * io)212 void call_fftw_execute_split_dft_r2c (const fftw_plan p, double *ri, double *ro, double *io)
213 {
214     if (MY_FFTW_EXECUTE_SPLIT_DFT_R2C)
215     {
216         (MY_FFTW_EXECUTE_SPLIT_DFT_R2C)(p, ri, ro, io);
217     }
218 }
219 /*--------------------------------------------------------------------------*/
call_fftw_execute_split_dft_r2r(const fftw_plan p,double * ri,double * ro)220 void call_fftw_execute_split_dft_r2r (const fftw_plan p, double *ri, double *ro)
221 {
222     if (MY_FFTW_EXECUTE_SPLIT_DFT_R2R)
223     {
224         (MY_FFTW_EXECUTE_SPLIT_DFT_R2R)(p, ri, ro);
225     }
226 }
227 /*--------------------------------------------------------------------------*/
call_fftw_plan_guru_split_dft(int rank,const fftw_iodim * dims,int howmany_rank,const fftw_iodim * howmany_dims,double * ri,double * ii,double * ro,double * io,unsigned flags)228 fftw_plan call_fftw_plan_guru_split_dft (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ii, double *ro, double *io, unsigned flags)
229 {
230     if (MY_FFTW_PLAN_GURU_SPLIT_DFT)
231     {
232         return (fftw_plan)(MY_FFTW_PLAN_GURU_SPLIT_DFT)(rank, dims, howmany_rank, howmany_dims, ri, ii, ro, io, flags);
233     }
234     else
235     {
236         return NULL;
237     }
238 }
239 /*--------------------------------------------------------------------------*/
call_fftw_plan_guru_split_dft_c2r(int rank,const fftw_iodim * dims,int howmany_rank,const fftw_iodim * howmany_dims,double * ri,double * ii,double * ro,unsigned flags)240 fftw_plan call_fftw_plan_guru_split_dft_c2r (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ii, double *ro,  unsigned flags)
241 {
242     if (MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R)
243     {
244         return (fftw_plan)(MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R)(rank, dims, howmany_rank, howmany_dims, ri, ii, ro, flags);
245     }
246     else
247     {
248         return NULL;
249     }
250 }
251 /*--------------------------------------------------------------------------*/
call_fftw_plan_guru_split_dft_r2c(int rank,const fftw_iodim * dims,int howmany_rank,const fftw_iodim * howmany_dims,double * ri,double * ro,double * io,unsigned flags)252 fftw_plan call_fftw_plan_guru_split_dft_r2c (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ro, double *io, unsigned flags)
253 {
254     if (MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C)
255     {
256         return (fftw_plan)(MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C)(rank, dims, howmany_rank, howmany_dims, ri, ro, io, flags);
257     }
258     else
259     {
260         return NULL;
261     }
262 }
263 /*--------------------------------------------------------------------------*/
call_fftw_plan_guru_split_dft_r2r(int rank,const fftw_iodim * dims,int howmany_rank,const fftw_iodim * howmany_dims,double * ri,double * ro,fftw_r2r_kind * kind,unsigned flags)264 fftw_plan call_fftw_plan_guru_split_dft_r2r (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ro, fftw_r2r_kind *kind, unsigned flags)
265 {
266     if (MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R)
267     {
268         return (fftw_plan)(MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R)(rank, dims, howmany_rank, howmany_dims, ri, ro, kind, flags);
269     }
270     else
271     {
272         return NULL;
273     }
274 }
275 
276 /*--------------------------------------------------------------------------*/
call_fftw_destroy_plan(fftw_plan p)277 void call_fftw_destroy_plan (fftw_plan p)
278 {
279     if (MY_FFTW_DESTROY_PLAN)
280     {
281         (MY_FFTW_DESTROY_PLAN)(p);
282     }
283 }
284 /*--------------------------------------------------------------------------*/
call_fftw_export_wisdom_to_string(void)285 char *call_fftw_export_wisdom_to_string (void)
286 {
287     if (MY_FFTW_EXPORT_WISDOM_TO_STRING)
288     {
289         return (char *)(MY_FFTW_EXPORT_WISDOM_TO_STRING)();
290     }
291     return NULL;
292 }
293 /*--------------------------------------------------------------------------*/
call_fftw_import_wisdom_from_string(const char * input_string)294 int call_fftw_import_wisdom_from_string (const char *input_string)
295 {
296     if (MY_FFTW_IMPORT_WISDOM_FROM_STRING)
297     {
298         return (int)(MY_FFTW_IMPORT_WISDOM_FROM_STRING)(input_string);
299     }
300     return 0;
301 }
302 /*--------------------------------------------------------------------------*/
call_fftw_forget_wisdom(void)303 void call_fftw_forget_wisdom (void)
304 {
305     if (MY_FFTW_FORGET_WISDOM)
306     {
307         (MY_FFTW_FORGET_WISDOM)();
308     }
309 }
310 /*--------------------------------------------------------------------------*/
311