1 //
2 //Copyright (C) 2002  Gary Bishop
3 //Copyright (C) 2002, 2004  Alan W. Irwin
4 //Copyright (C) 2004-2010  Andrew Ross
5 //This file is part of PLplot.
6 //
7 //PLplot is free software; you can redistribute it and/or modify
8 //it under the terms of the GNU Library General Public License as published by
9 //the Free Software Foundation; version 2 of the License.
10 //
11 //PLplot is distributed in the hope that it will be useful,
12 //but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //GNU Library General Public License for more details.
15 //
16 //You should have received a copy of the GNU Library General Public License
17 //along with the file PLplot; if not, write to the Free Software
18 //Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
19 //
20 
21 //
22 //A SWIG interface to PLplot for Java. This wrapper does the following:
23 //
24 //   1) it strictly provides the C-API with the usual change of not
25 //      requiring lengths for arrays,
26 //
27 //   2) it attempts to provide the entire API *excluding* callbacks for
28 //      plcont and plshade(s) (for now).
29 //
30 //   3) it works both with the single and double-precision versions of the
31 //      PLplot library.
32 //
33 //This is known to work with swig-1.3.21.
34 //
35 //
36 %module plplotjavac
37 %include typemaps.i
38 
39 %{
40 #include "plplotP.h"
41 %}
42 
43 #ifdef PL_DOUBLE_INTERFACE
44 typedef double         PLFLT;
45 #else
46 typedef float          PLFLT;
47 #endif
48 
49 // This assumes that C int is 32-bit - swig doesn't know about int32_t
50 // Ideally we should have a typemap for it
51 typedef int            PLINT;
52 typedef unsigned int   PLUNICODE;
53 typedef PLINT          PLBOOL;
54 
55 // Set jni version and cache JVM - needed for callbacks
56 %{
57     static JavaVM *cached_jvm = NULL;
58 
JNI_OnLoad(JavaVM * jvm,void * PL_UNUSED (reserved))59     SWIGEXPORT JNIEXPORT jint JNICALL JNI_OnLoad( JavaVM *jvm, void * PL_UNUSED( reserved ) )
60     {
61         cached_jvm = jvm;
62         return JNI_VERSION_1_2;
63     }
64 %}
65 
66 // Simple (input) PLBOOL arguments
67 // Use macro style similar to INPUT_TYPEMAP defined in typemaps.i, but
68 // actually follow what is done in java.swg for bool C type except
69 // change action of typemap(in) from "? true : false;" to "? 1 : 0;" to
70 // be consistent with actual C type of PLBOOL which is PLINT.  If C type
71 // of PLBOOL ever changed to bool, none of this would be necessary, but
72 // such a change would demand using the c99 standard for PLplot which is
73 // not widely implemented yet.
74 //
75 %define PLBOOL_INPUT_TYPEMAP( TYPE, JNITYPE, JTYPE, JNIDESC )
76 %typemap( jni ) TYPE "JNITYPE"
77 %typemap( jtype ) TYPE "JTYPE"
78 %typemap( jstype ) TYPE "JTYPE"
79 
80 %typemap( in ) TYPE
81 %{
82     $1 = $input ? 1 : 0;
83 %}
84 
85 %typemap( javadirectorin ) TYPE "$jniinput"
86 %typemap( javadirectorout ) TYPE "$javacall"
87 
88 %typemap( directorin, descriptor = JNIDESC ) TYPE
89 %{
90     $input = (JNITYPE *) $1;
91 %}
92 
93 %typemap( javain ) TYPE "$javainput"
94 %enddef
95 
96 PLBOOL_INPUT_TYPEMAP( PLBOOL, jboolean, boolean, "Z" );
97 
98 // This renamed macro copied exactly from OUTPUT_TYPEMAP macro
99 // in typemaps.i which handles *OUTPUT types.
100 
101 %define PLBOOL_OUTPUT_TYPEMAP( TYPE, JNITYPE, JTYPE, JAVATYPE, JNIDESC, TYPECHECKTYPE )
102 %typemap( jni ) TYPE * OUTPUT, TYPE & OUTPUT
103 %{
104     JNITYPE ## Array
105 %}
106 %typemap( jtype ) TYPE * OUTPUT, TYPE & OUTPUT "JTYPE[]"
107 %typemap( jstype ) TYPE * OUTPUT, TYPE & OUTPUT "JTYPE[]"
108 %typemap( javain ) TYPE * OUTPUT, TYPE & OUTPUT "$javainput"
109 %typemap( javadirectorin ) TYPE * OUTPUT, TYPE & OUTPUT "$jniinput"
110 %typemap( javadirectorout ) TYPE * OUTPUT, TYPE & OUTPUT "$javacall"
111 
112 %typemap( in ) TYPE * OUTPUT( $*1_ltype temp ), TYPE &OUTPUT( $*1_ltype temp )
113 {
114     if ( !$input )
115     {
116         SWIG_JavaThrowException( jenv, SWIG_JavaNullPointerException, "array null" );
117         return $null;
118     }
119     if ( JCALL1( GetArrayLength, jenv, $input ) == 0 )
120     {
121         SWIG_JavaThrowException( jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element" );
122         return $null;
123     }
124     $1 = &temp;
125 }
126 
127 %typemap( directorin, descriptor = JNIDESC ) TYPE & OUTPUT
128 %{
129     *( ( $&1_ltype )$input ) = &$1;
130 %}
131 
132 %typemap( directorin, descriptor = JNIDESC, warning = "Need to provide TYPE *OUTPUT directorin typemap, TYPE array length is unknown" ) TYPE * OUTPUT
133 {
134 }
135 
136 %typemap( freearg ) TYPE * OUTPUT, TYPE & OUTPUT ""
137 
138 %typemap( argout ) TYPE * OUTPUT, TYPE & OUTPUT
139 {
140     JNITYPE jvalue = (JNITYPE) temp$argnum;
141     JCALL4( Set ## JAVATYPE ## ArrayRegion, jenv, $input, 0, 1, &jvalue );
142 }
143 
144 %typemap( typecheck ) TYPE * INOUT = TYPECHECKTYPE;
145 %typemap( typecheck ) TYPE &INOUT  = TYPECHECKTYPE;
146 %enddef
147 
148 // Copy what is done for C bool type, only use PLBOOL instead.
149 PLBOOL_OUTPUT_TYPEMAP( PLBOOL, jboolean, boolean, Boolean, "[Ljava/lang/Boolean;", jbooleanArray );
150 
151 //**************************
152 //        A trick for docstrings
153 //***************************
154 
155 %define DOC( func, string )
156 %wrapper
157 %{
158     # define _doc_    ## func string
159 %}
160 %enddef
161 
162 // Infrastructure for handling swig compatible plplot API definitions.
163 
164 #ifdef PL_DOUBLE_INTERFACE
165 #define setup_array_1d_PLFLT         setup_array_1d_d
166 #define setup_array_2d_PLFLT         setup_array_2d_d
167 #define jPLFLTArray                  "jdoubleArray"
168 #define jPLFLTbracket                "double[]"
169 #define jPLFLTbracket2               "double[][]"
170 #define GetPLFLTArrayElements        GetDoubleArrayElements
171 #define ReleasePLFLTArrayElements    ReleaseDoubleArrayElements
172 #define jPLFLT                       jdouble
173 #else
174 #define setup_array_1d_PLFLT         setup_array_1d_f
175 #define setup_array_2d_PLFLT         setup_array_2d_f
176 #define jPLFLTArray                  "jfloatArray"
177 #define jPLFLTbracket                "float[]"
178 #define jPLFLTbracket2               "float[][]"
179 #define GetPLFLTArrayElements        GetFloatArrayElements
180 #define ReleasePLFLTArrayElements    ReleaseFloatArrayElements
181 #define jPLFLT                       jfloat
182 #endif
183 
184 %{
185 //--------------------------------------------------------------------------
186 // Array allocation & copy helper routines.  Note because of swig limitations
187 // it is necessary to release the java array memory right after calling these
188 // routines.  Thus it is necessary to allocate and copy the arrays  even if
189 // the java and plplot arrays are of the same type.  Note, because of this
190 // change to Geoffrey's original versions, caller must always free memory
191 // afterwards.  Thus, the must_free_buffers logic is gone as well.
192 //--------------------------------------------------------------------------
193 
194 // 1d array of jbooleans
195 
196     static void
setup_array_1d_b(PLBOOL ** pa,jboolean * adat,int n)197     setup_array_1d_b( PLBOOL **pa, jboolean *adat, int n )
198     {
199         int i;
200         *pa = (PLBOOL *) malloc( (size_t) n * sizeof ( PLBOOL ) );
201         for ( i = 0; i < n; i++ )
202         {
203             ( *pa )[i] = adat[i] ? 1 : 0;
204         }
205     }
206 
207 // 1d array of jints
208 
209     static void
setup_array_1d_i(PLINT ** pa,jint * adat,int n)210     setup_array_1d_i( PLINT **pa, jint *adat, int n )
211     {
212         int i;
213         *pa = (PLINT *) malloc( (size_t) n * sizeof ( PLINT ) );
214         for ( i = 0; i < n; i++ )
215         {
216             ( *pa )[i] = adat[i];
217         }
218     }
219 
220 // 1d array of jfloats
221 
222     static void
setup_array_1d_f(PLFLT ** pa,jfloat * adat,int n)223     setup_array_1d_f( PLFLT **pa, jfloat *adat, int n )
224     {
225         int i;
226         *pa = (PLFLT *) malloc( (size_t) n * sizeof ( PLFLT ) );
227         for ( i = 0; i < n; i++ )
228         {
229             ( *pa )[i] = adat[i];
230         }
231     }
232 
233 // 1d array of jdoubles
234 
235     static void
setup_array_1d_d(PLFLT ** pa,jdouble * adat,int n)236     setup_array_1d_d( PLFLT **pa, jdouble *adat, int n )
237     {
238         int i;
239         *pa = (PLFLT *) malloc( (size_t) n * sizeof ( PLFLT ) );
240         for ( i = 0; i < n; i++ )
241         {
242             ( *pa )[i] = adat[i];
243         }
244     }
245 
246 // 2d array of floats
247 // Here caller must free(a[0]) and free(a) (in that order) afterward
248 
249     static void
setup_array_2d_f(PLFLT *** pa,jfloat ** adat,int nx,int ny)250     setup_array_2d_f( PLFLT ***pa, jfloat **adat, int nx, int ny )
251     {
252         int i, j;
253 
254         *pa        = (PLFLT **) malloc( (size_t) nx * sizeof ( PLFLT * ) );
255         ( *pa )[0] = (PLFLT *) malloc( (size_t) ( nx * ny ) * sizeof ( PLFLT ) );
256 
257         for ( i = 0; i < nx; i++ )
258         {
259             ( *pa )[i] = ( *pa )[0] + i * ny;
260             for ( j = 0; j < ny; j++ )
261                 ( *pa )[i][j] = adat[i][j];
262         }
263     }
264 
265 // 2d array of doubles
266 // Here caller must free(a[0]) and free(a) (in that order) afterward
267 
268     static void
setup_array_2d_d(PLFLT *** pa,jdouble ** adat,int nx,int ny)269     setup_array_2d_d( PLFLT ***pa, jdouble **adat, int nx, int ny )
270     {
271         int i, j;
272 
273         *pa        = (PLFLT **) malloc( (size_t) nx * sizeof ( PLFLT * ) );
274         ( *pa )[0] = (PLFLT *) malloc( (size_t) ( nx * ny ) * sizeof ( PLFLT ) );
275 
276         for ( i = 0; i < nx; i++ )
277         {
278             ( *pa )[i] = ( *pa )[0] + i * ny;
279             for ( j = 0; j < ny; j++ )
280                 ( *pa )[i][j] = adat[i][j];
281         }
282     }
283 
284 // Setup java arrays (for callback functions)
285 
286 // Create a jdoubleArray and fill it from the C PLFLT array dat
287     static jdoubleArray
setup_java_array_1d_PLFLT(JNIEnv * jenv,PLFLT * dat,PLINT n)288     setup_java_array_1d_PLFLT( JNIEnv *jenv, PLFLT *dat, PLINT n )
289     {
290         double       *x;
291         jdoubleArray jadat;
292 #ifdef PL_DOUBLE
293         x = (double *) dat;
294 #else
295         x = (double *) malloc( (size_t) n * sizeof ( double ) );
296         for ( i = 0; i < n; i++ )
297         {
298             x[i] = (double) dat[i];
299         }
300 #endif
301         jadat = ( *jenv )->NewDoubleArray( jenv, n );
302         ( *jenv )->SetDoubleArrayRegion( jenv, jadat, 0, n, x );
303 #ifndef PL_DOUBLE
304         free( x );
305 #endif
306         return jadat;
307     }
308 
309 // Copy back data from jdoubleArray to C PLFLT array then release java array
310     static void
release_java_array_1d_PLFLT(JNIEnv * jenv,jdoubleArray jadat,PLFLT * dat,PLINT n)311     release_java_array_1d_PLFLT( JNIEnv *jenv, jdoubleArray jadat, PLFLT *dat, PLINT n )
312     {
313         PLINT   i;
314         jdouble *jdata = ( *jenv )->GetDoubleArrayElements( jenv, jadat, 0 );
315         for ( i = 0; i < n; i++ )
316         {
317             dat[i] = (PLFLT) jdata[i];
318         }
319         ( *jenv )->ReleaseDoubleArrayElements( jenv, jadat, jdata, 0 );
320     }
321 
322 %}
323 
324 
325 
326 // I hate global variables but this is the best way I can think of to manage consistency
327 //   checking among function arguments.
328 %{
329     static PLINT    Alen = 0;
330     static PLINT    Xlen = 0, Ylen = 0;
331     static PLFLT    **xg;
332     static PLFLT    **yg;
333     static PLcGrid2 *cgrid;
334 %}
335 
336 // The following typemaps take care of marshaling values into and out of PLplot functions. The
337 //Array rules are trickly because of the need for length checking. These rules manage
338 //some global variables (above) to handle consistency checking amoung parameters.
339 //
340 //Naming rules:
341 //        Array           (sets Alen to dim[0])
342 //        ArrayCk         (tests that dim[0] == Alen)
343 //        ArrayCkNull     (tests that dim[0] == Alen or array is null)
344 //        ArrayX          (sets Xlen to dim[0]
345 //        ArrayCkX        (tests dim[0] == Xlen)
346 //        ArrayY          (sets Ylen to dim[1])
347 //        ArrayCkY        (tests dim[1] == Ylen)
348 //        Matrix          (sets Xlen to dim[0], Ylen to dim[1])
349 //        MatrixCk        (test Xlen == dim[0] && Ylen == dim[1])
350 //
351 
352 //--------------------------------------------------------------------------
353 //                         PLINT arrays
354 //--------------------------------------------------------------------------
355 
356 // with preceding count
357 %typemap ( in ) ( PLINT n, const PLINT * Array )
358 {
359     jint *jxdata = ( *jenv )->GetIntArrayElements( jenv, $input, 0 );
360     $1   = ( *jenv )->GetArrayLength( jenv, $input );
361     Alen = $1;
362     setup_array_1d_i( &$2, jxdata, Alen );
363     // Could find no easy way to do this as part of freearg so I modified
364     // the previous function so it ALWAYS mallocs and copies so that
365     // the java array can be released immediately.
366     ( *jenv )->ReleaseIntArrayElements( jenv, $input, jxdata, 0 );
367 }
368 %typemap ( freearg ) ( PLINT n, const PLINT * Array )
369 {
370     free( $2 );
371 }
372 %typemap ( jni ) ( PLINT n, const PLINT * Array ) "jintArray"
373 %typemap ( jtype ) ( PLINT n, const PLINT * Array ) "int[]"
374 %typemap ( jstype ) ( PLINT n, const PLINT * Array ) "int[]"
375 %typemap ( javain ) ( PLINT n, const PLINT * Array ) "$javainput"
376 %typemap ( javaout ) ( PLINT n, const PLINT * Array )
377 {
378     return $jnicall;
379 }
380 
381 // Trailing count and check consistency with previous
382 %typemap ( in ) ( const PLINT * ArrayCk, PLINT n )
383 {
384     jint *jydata = ( *jenv )->GetIntArrayElements( jenv, $input, 0 );
385     if ( ( *jenv )->GetArrayLength( jenv, $input ) != Alen )
386     {
387         printf( "Vectors must be same length.\n" );
388         return;
389     }
390     $2 = ( *jenv )->GetArrayLength( jenv, $input );
391     setup_array_1d_i( &$1, jydata, Alen );
392     ( *jenv )->ReleaseIntArrayElements( jenv, $input, jydata, 0 );
393 }
394 %typemap ( freearg ) ( const PLINT * ArrayCk, PLINT n )
395 {
396     free( $1 );
397 }
398 %typemap ( jni ) ( const PLINT * ArrayCk, PLINT n ) "jintArray"
399 %typemap ( jtype ) ( const PLINT * ArrayCk, PLINT n ) "int[]"
400 %typemap ( jstype ) ( const PLINT * ArrayCk, PLINT n ) "int[]"
401 %typemap ( javain ) ( const PLINT * ArrayCk, PLINT n ) "$javainput"
402 %typemap ( javaout ) ( const PLINT * ArrayCk, PLINT n )
403 {
404     return $jnicall;
405 }
406 
407 // no count but check consistency with previous
408 %typemap( in ) const PLINT * ArrayCk {
409     jint *jydata = ( *jenv )->GetIntArrayElements( jenv, $input, 0 );
410     if ( ( *jenv )->GetArrayLength( jenv, $input ) != Alen )
411     {
412         printf( "Vectors must be same length.\n" );
413         return;
414     }
415     setup_array_1d_i( &$1, jydata, Alen );
416     ( *jenv )->ReleaseIntArrayElements( jenv, $input, jydata, 0 );
417 }
418 %typemap( freearg ) const PLINT * ArrayCk {
419     free( $1 );
420 }
421 %typemap( jni ) const PLINT * ArrayCk "jintArray"
422 %typemap( jtype ) const PLINT * ArrayCk "int[]"
423 %typemap( jstype ) const PLINT * ArrayCk "int[]"
424 %typemap( javain ) const PLINT * ArrayCk "$javainput"
425 %typemap( javaout ) const PLINT * ArrayCk {
426     return $jnicall;
427 }
428 
429 // no count but check consistency with previous or is null
430 %typemap( in ) const PLINT * ArrayCkNull {
431     if ( $input != NULL )
432     {
433         jint *jydata = ( *jenv )->GetIntArrayElements( jenv, $input, 0 );
434         if ( ( *jenv )->GetArrayLength( jenv, $input ) != Alen )
435         {
436             printf( "Vectors must be same length.\n" );
437             return;
438         }
439         setup_array_1d_i( &$1, jydata, Alen );
440         ( *jenv )->ReleaseIntArrayElements( jenv, $input, jydata, 0 );
441     }
442     else
443     {
444         $1 = NULL;
445     }
446 }
447 %typemap( freearg ) const PLINT * ArrayCkNull {
448     if ( $1 != NULL )
449         free( $1 );
450 }
451 %typemap( jni ) const PLINT * ArrayCkNull "jintArray"
452 %typemap( jtype ) const PLINT * ArrayCkNull "int[]"
453 %typemap( jstype ) const PLINT * ArrayCkNull "int[]"
454 %typemap( javain ) const PLINT * ArrayCkNull "$javainput"
455 %typemap( javaout ) const PLINT * ArrayCkNull {
456     return $jnicall;
457 }
458 
459 // Weird case to allow argument to be one shorter than others
460 // This case is used both for PLBOOL and PLINT.  Define PLBOOL version
461 // first.  (AWI thinks this may be necessary because of the above
462 // typedef PLINT PLBOOL;)
463 // Also add version which must be one shorter than others or null.
464 //
465 %typemap( in ) const PLBOOL * ArrayCkMinus1 {
466     jboolean *jydata = ( *jenv )->GetBooleanArrayElements( jenv, $input, 0 );
467     if ( ( *jenv )->GetArrayLength( jenv, $input ) < Alen - 1 )
468     {
469         printf( "Vector must be at least length of others minus 1.\n" );
470         return;
471     }
472     setup_array_1d_b( &$1, jydata, Alen );
473     ( *jenv )->ReleaseBooleanArrayElements( jenv, $input, jydata, 0 );
474 }
475 %typemap( freearg ) const PLBOOL * ArrayCkMinus1 {
476     free( $1 );
477 }
478 %typemap( jni ) const PLBOOL * ArrayCkMinus1 "jbooleanArray"
479 %typemap( jtype ) const PLBOOL * ArrayCkMinus1 "boolean[]"
480 %typemap( jstype ) const PLBOOL * ArrayCkMinus1 "boolean[]"
481 %typemap( javain ) const PLBOOL * ArrayCkMinus1 "$javainput"
482 %typemap( javaout ) const PLBOOL * ArrayCkMinus1 {
483     return $jnicall;
484 }
485 
486 %typemap( in ) const PLBOOL * ArrayCkMinus1Null {
487     if ( $input != NULL )
488     {
489         jboolean *jydata = ( *jenv )->GetBooleanArrayElements( jenv, $input, 0 );
490         if ( ( *jenv )->GetArrayLength( jenv, $input ) < Alen - 1 )
491         {
492             printf( "Vector must be at least length of others minus 1.\n" );
493             return;
494         }
495         setup_array_1d_b( &$1, jydata, Alen );
496         ( *jenv )->ReleaseBooleanArrayElements( jenv, $input, jydata, 0 );
497     }
498     else
499     {
500         $1 = NULL;
501     }
502 }
503 %typemap( freearg ) const PLBOOL * ArrayCkMinus1Null {
504     if ( $1 != NULL )
505         free( $1 );
506 }
507 %typemap( jni ) const PLBOOL * ArrayCkMinus1Null "jbooleanArray"
508 %typemap( jtype ) const PLBOOL * ArrayCkMinus1Null "boolean[]"
509 %typemap( jstype ) const PLBOOL * ArrayCkMinus1Null "boolean[]"
510 %typemap( javain ) const PLBOOL * ArrayCkMinus1Null "$javainput"
511 %typemap( javaout ) const PLBOOL * ArrayCkMinus1Null {
512     return $jnicall;
513 }
514 
515 %typemap( in ) const PLINT * ArrayCkMinus1 {
516     jint *jydata = ( *jenv )->GetIntArrayElements( jenv, $input, 0 );
517     if ( ( *jenv )->GetArrayLength( jenv, $input ) < Alen - 1 )
518     {
519         printf( "Vector must be at least length of others minus 1.\n" );
520         return;
521     }
522     setup_array_1d_i( &$1, jydata, Alen );
523     ( *jenv )->ReleaseIntArrayElements( jenv, $input, jydata, 0 );
524 }
525 %typemap( freearg ) const PLINT * ArrayCkMinus1 {
526     free( $1 );
527 }
528 %typemap( jni ) const PLINT * ArrayCkMinus1 "jintArray"
529 %typemap( jtype ) const PLINT * ArrayCkMinus1 "int[]"
530 %typemap( jstype ) const PLINT * ArrayCkMinus1 "int[]"
531 %typemap( javain ) const PLINT * ArrayCkMinus1 "$javainput"
532 %typemap( javaout ) const PLINT * ArrayCkMinus1 {
533     return $jnicall;
534 }
535 
536 %typemap( in ) const PLINT * ArrayCkMinus1Null {
537     if ( $input != NULL )
538     {
539         jint *jydata = ( *jenv )->GetIntArrayElements( jenv, $input, 0 );
540         if ( ( *jenv )->GetArrayLength( jenv, $input ) < Alen - 1 )
541         {
542             printf( "Vector must be at least length of others minus 1.\n" );
543             return;
544         }
545         setup_array_1d_i( &$1, jydata, Alen );
546         ( *jenv )->ReleaseIntArrayElements( jenv, $input, jydata, 0 );
547     }
548     else
549     {
550         $1 = NULL;
551     }
552 }
553 %typemap( freearg ) const PLINT * ArrayCkMinus1Null {
554     if ( $1 != NULL )
555         free( $1 );
556 }
557 %typemap( jni ) const PLINT * ArrayCkMinus1Null "jintArray"
558 %typemap( jtype ) const PLINT * ArrayCkMinus1Null "int[]"
559 %typemap( jstype ) const PLINT * ArrayCkMinus1Null "int[]"
560 %typemap( javain ) const PLINT * ArrayCkMinus1Null "$javainput"
561 %typemap( javaout ) const PLINT * ArrayCkMinus1Null {
562     return $jnicall;
563 }
564 
565 // No length but remember size to check others
566 %typemap( in ) const PLINT * Array {
567     jint *jydata = ( *jenv )->GetIntArrayElements( jenv, $input, 0 );
568     Alen = ( *jenv )->GetArrayLength( jenv, $input );
569     setup_array_1d_i( &$1, jydata, Alen );
570     ( *jenv )->ReleaseIntArrayElements( jenv, $input, jydata, 0 );
571 }
572 %typemap( freearg ) const PLINT * Array {
573     free( $1 );
574 }
575 %typemap( jni ) const PLINT * Array "jintArray"
576 %typemap( jtype ) const PLINT * Array "int[]"
577 %typemap( jstype ) const PLINT * Array "int[]"
578 %typemap( javain ) const PLINT * Array "$javainput"
579 %typemap( javaout ) const PLINT * Array {
580     return $jnicall;
581 }
582 
583 // Set X and Y length for later consistency checking
584 %typemap( in ) const PLINT * ArrayN {
585     int  i;
586     jint *jydata = ( *jenv )->GetIntArrayElements( jenv, $input, 0 );
587     if ( ( *jenv )->GetArrayLength( jenv, $input ) != Alen )
588     {
589         printf( "Vectors must be same length.\n" );
590         return;
591     }
592     Xlen = ( *jenv )->GetArrayLength( jenv, $input );
593     Ylen = -1;
594     for ( i = 0; i < Xlen; i++ )
595         if ( jydata[i] > Ylen )
596             Ylen = jydata[i];
597     setup_array_1d_i( &$1, jydata, Alen );
598     ( *jenv )->ReleaseIntArrayElements( jenv, $input, jydata, 0 );
599 }
600 %typemap( freearg ) const PLINT * ArrayN {
601     free( $1 );
602 }
603 %typemap( jni ) const PLINT * ArrayN "jintArray"
604 %typemap( jtype ) const PLINT * ArrayN "int[]"
605 %typemap( jstype ) const PLINT * ArrayN "int[]"
606 %typemap( javain ) const PLINT * ArrayN "$javainput"
607 %typemap( javaout ) const PLINT * ArrayN {
608     return $jnicall;
609 }
610 
611 // With trailing count and NULL array option.
612 %typemap ( in ) ( const PLINT * ArrayNull, PLINT n )
613 {
614     if ( $input != NULL )
615     {
616         jint *jydata = ( *jenv )->GetIntArrayElements( jenv, $input, 0 );
617         $2 = ( *jenv )->GetArrayLength( jenv, $input );
618         setup_array_1d_i( &$1, jydata, $2 );
619         ( *jenv )->ReleaseIntArrayElements( jenv, $input, jydata, 0 );
620     }
621     else
622     {
623         $1 = NULL;
624         $2 = 0;
625     }
626 }
627 %typemap ( freearg ) ( const PLINT * ArrayNull, PLINT n )
628 {
629     free( $1 );
630 }
631 %typemap ( jni ) ( const PLINT * ArrayNull, PLINT n ) "jintArray"
632 %typemap ( jtype ) ( const PLINT * ArrayNull, PLINT n ) "int[]"
633 %typemap ( jstype ) ( const PLINT * ArrayNull, PLINT n ) "int[]"
634 %typemap ( javain ) ( const PLINT * ArrayNull, PLINT n ) "$javainput"
635 %typemap ( javaout ) ( const PLINT * ArrayNull, PLINT n )
636 {
637     return $jnicall;
638 }
639 
640 //--------------------------------------------------------------------------
641 //                                 PLFLT Arrays
642 //--------------------------------------------------------------------------
643 
644 //temporary
645 #if 0
646 #ifndef PL_DOUBLE
647 %wrapper
648 %{
649 // some really twisted stuff to allow calling a single precision library from python
650     PyArrayObject* myArray_ContiguousFromObject( PyObject* in, int type, int mindims, int maxdims )
651     {
652         PyArrayObject* tmp = (PyArrayObject *) PyArray_ContiguousFromObject( in, PyArray_FLOAT,
653             mindims, maxdims );
654         if ( !tmp )
655         {
656             // could be an incoming double array which can't be "safely" converted, do it anyway
657             if ( PyArray_Check( in ) )
658             {
659                 PyErr_Clear();
660                 tmp = (PyArrayObject *) PyArray_Cast( (PyArrayObject *) in, PyArray_FLOAT );
661             }
662         }
663         return tmp;
664     }
665 %}
666 #else
667 %wrapper
668 %{
669 #define myArray_ContiguousFromObject    PyArray_ContiguousFromObject
670 %}
671 #endif
672 
673 // temporary
674 #endif
675 // with preceding count
676 %typemap ( in ) ( PLINT n, const PLFLT * Array )
677 {
678     jPLFLT *jxdata = ( *jenv )->GetPLFLTArrayElements( jenv, $input, 0 );
679     $1   = ( *jenv )->GetArrayLength( jenv, $input );
680     Alen = $1;
681     setup_array_1d_PLFLT( &$2, jxdata, Alen );
682     // Could find no easy way to do this as part of freearg so I modified
683     // the previous function so it ALWAYS mallocs and copies so that
684     // the java array can be released immediately.
685     ( *jenv )->ReleasePLFLTArrayElements( jenv, $input, jxdata, 0 );
686 }
687 %typemap ( freearg ) ( PLINT n, const PLFLT * Array )
688 {
689     free( $2 );
690 }
691 %typemap ( jni ) ( PLINT n, const PLFLT * Array ) jPLFLTArray
692 %typemap ( jtype ) ( PLINT n, const PLFLT * Array ) jPLFLTbracket
693 %typemap ( jstype ) ( PLINT n, const PLFLT * Array ) jPLFLTbracket
694 %typemap ( javain ) ( PLINT n, const PLFLT * Array ) "$javainput"
695 %typemap ( javaout ) ( PLINT n, const PLFLT * Array )
696 {
697     return $jnicall;
698 }
699 
700 // trailing count, and check consistency with previous
701 %typemap ( in ) ( const PLFLT * ArrayCk, PLINT n )
702 {
703     jPLFLT *jydata = ( *jenv )->GetPLFLTArrayElements( jenv, $input, 0 );
704     $2 = ( *jenv )->GetArrayLength( jenv, $input );
705     if ( ( *jenv )->GetArrayLength( jenv, $input ) != Alen )
706     {
707         printf( "Vectors must be same length.\n" );
708         return;
709     }
710     setup_array_1d_PLFLT( &$1, jydata, Alen );
711     ( *jenv )->ReleasePLFLTArrayElements( jenv, $input, jydata, 0 );
712 }
713 %typemap ( freearg ) ( const PLFLT * ArrayCk, PLINT n )
714 {
715     free( $1 );
716 }
717 %typemap ( jni ) ( const PLFLT * ArrayCk, PLINT n ) jPLFLTArray
718 %typemap ( jtype ) ( const PLFLT * ArrayCk, PLINT n ) jPLFLTbracket
719 %typemap ( jstype ) ( const PLFLT * ArrayCk, PLINT n ) jPLFLTbracket
720 %typemap ( javain ) ( const PLFLT * ArrayCk, PLINT n ) "$javainput"
721 %typemap ( javaout ) ( const PLFLT * ArrayCk, PLINT n )
722 {
723     return $jnicall;
724 }
725 
726 // no count, but check consistency with previous
727 %typemap( in ) const PLFLT * ArrayCk {
728     jPLFLT *jydata = ( *jenv )->GetPLFLTArrayElements( jenv, $input, 0 );
729     if ( ( *jenv )->GetArrayLength( jenv, $input ) != Alen )
730     {
731         printf( "Vectors must be same length.\n" );
732         return;
733     }
734     setup_array_1d_PLFLT( &$1, jydata, Alen );
735     ( *jenv )->ReleasePLFLTArrayElements( jenv, $input, jydata, 0 );
736 }
737 %typemap( freearg ) const PLFLT * ArrayCk {
738     free( $1 );
739 }
740 %typemap( jni ) const PLFLT * ArrayCk jPLFLTArray
741 %typemap( jtype ) const PLFLT * ArrayCk jPLFLTbracket
742 %typemap( jstype ) const PLFLT * ArrayCk jPLFLTbracket
743 %typemap( javain ) const PLFLT * ArrayCk "$javainput"
744 %typemap( javaout ) const PLFLT * ArrayCk {
745     return $jnicall;
746 }
747 
748 // trailing count, and check consistency with previous
749 %typemap ( in ) ( const PLFLT * ArrayCkNull, PLINT n )
750 {
751     if ( $input != NULL )
752     {
753         jPLFLT *jydata = ( *jenv )->GetPLFLTArrayElements( jenv, $input, 0 );
754         $2 = ( *jenv )->GetArrayLength( jenv, $input );
755         if ( ( *jenv )->GetArrayLength( jenv, $input ) != Alen )
756         {
757             printf( "Vectors must be same length.\n" );
758             return;
759         }
760         setup_array_1d_PLFLT( &$1, jydata, Alen );
761         ( *jenv )->ReleasePLFLTArrayElements( jenv, $input, jydata, 0 );
762     }
763     else
764     {
765         $1 = NULL;
766         $2 = 0;
767     }
768 }
769 %typemap ( freearg ) ( const PLFLT * ArrayCkNull, PLINT n )
770 {
771     if ( $1 != NULL )
772         free( $1 );
773 }
774 %typemap ( jni ) ( const PLFLT * ArrayCkNull, PLINT n ) jPLFLTArray
775 %typemap ( jtype ) ( const PLFLT * ArrayCkNull, PLINT n ) jPLFLTbracket
776 %typemap ( jstype ) ( const PLFLT * ArrayCkNull, PLINT n ) jPLFLTbracket
777 %typemap ( javain ) ( const PLFLT * ArrayCkNull, PLINT n ) "$javainput"
778 %typemap ( javaout ) ( const PLFLT * ArrayCkNull, PLINT n )
779 {
780     return $jnicall;
781 }
782 
783 
784 // no count, but check consistency with previous or NULL
785 %typemap( in ) const PLFLT * ArrayCkNull {
786     if ( $input != NULL )
787     {
788         jPLFLT *jydata = ( *jenv )->GetPLFLTArrayElements( jenv, $input, 0 );
789         if ( ( *jenv )->GetArrayLength( jenv, $input ) != Alen )
790         {
791             printf( "Vectors must be same length.\n" );
792             return;
793         }
794         setup_array_1d_PLFLT( &$1, jydata, Alen );
795         ( *jenv )->ReleasePLFLTArrayElements( jenv, $input, jydata, 0 );
796     }
797     else
798     {
799         $1 = NULL;
800     }
801 }
802 %typemap( freearg ) const PLFLT * ArrayCkNull {
803     if ( $1 != NULL )
804         free( $1 );
805 }
806 %typemap( jni ) const PLFLT * ArrayCkNull jPLFLTArray
807 %typemap( jtype ) const PLFLT * ArrayCkNull jPLFLTbracket
808 %typemap( jstype ) const PLFLT * ArrayCkNull jPLFLTbracket
809 %typemap( javain ) const PLFLT * ArrayCkNull "$javainput"
810 %typemap( javaout ) const PLFLT * ArrayCkNull {
811     return $jnicall;
812 }
813 
814 // set X length for later consistency checking
815 %typemap ( in ) ( const PLFLT * ArrayX, PLINT nx )
816 {
817     jPLFLT *jxdata = ( *jenv )->GetPLFLTArrayElements( jenv, $input, 0 );
818     Xlen = ( *jenv )->GetArrayLength( jenv, $input );
819     $2   = Xlen;
820     setup_array_1d_PLFLT( &$1, jxdata, Xlen );
821     ( *jenv )->ReleasePLFLTArrayElements( jenv, $input, jxdata, 0 );
822 }
823 %typemap ( freearg ) ( const PLFLT * ArrayX, PLINT nx )
824 {
825     free( $1 );
826 }
827 %typemap ( jni ) ( const PLFLT * ArrayX, PLINT nx ) jPLFLTArray
828 %typemap ( jtype ) ( const PLFLT * ArrayX, PLINT nx ) jPLFLTbracket
829 %typemap ( jstype ) ( const PLFLT * ArrayX, PLINT nx ) jPLFLTbracket
830 %typemap ( javain ) ( const PLFLT * ArrayX, PLINT nx ) "$javainput"
831 %typemap ( javaout ) ( const PLFLT * ArrayX, PLINT nx )
832 {
833     return $jnicall;
834 }
835 
836 %typemap( in ) const PLFLT * ArrayX {
837     jPLFLT *jxdata = ( *jenv )->GetPLFLTArrayElements( jenv, $input, 0 );
838     Xlen = ( *jenv )->GetArrayLength( jenv, $input );
839     setup_array_1d_PLFLT( &$1, jxdata, Xlen );
840     ( *jenv )->ReleasePLFLTArrayElements( jenv, $input, jxdata, 0 );
841 }
842 %typemap( freearg ) const PLFLT * ArrayX {
843     free( $1 );
844 }
845 %typemap( jni ) const PLFLT * ArrayX jPLFLTArray
846 %typemap( jtype ) const PLFLT * ArrayX jPLFLTbracket
847 %typemap( jstype ) const PLFLT * ArrayX jPLFLTbracket
848 %typemap( javain ) const PLFLT * ArrayX "$javainput"
849 %typemap( javaout ) const PLFLT * ArrayX {
850     return $jnicall;
851 }
852 
853 // set Y length for later consistency checking
854 %typemap ( in ) ( const PLFLT * ArrayY, PLINT ny )
855 {
856     jPLFLT *jydata = ( *jenv )->GetPLFLTArrayElements( jenv, $input, 0 );
857     Ylen = ( *jenv )->GetArrayLength( jenv, $input );
858     $2   = Ylen;
859     setup_array_1d_PLFLT( &$1, jydata, Ylen );
860     ( *jenv )->ReleasePLFLTArrayElements( jenv, $input, jydata, 0 );
861 }
862 %typemap ( freearg ) ( const PLFLT * ArrayY, PLINT ny )
863 {
864     free( $1 );
865 }
866 %typemap ( jni ) ( const PLFLT * ArrayY, PLINT ny ) jPLFLTArray
867 %typemap ( jtype ) ( const PLFLT * ArrayY, PLINT ny ) jPLFLTbracket
868 %typemap ( jstype ) ( const PLFLT * ArrayY, PLINT ny ) jPLFLTbracket
869 %typemap ( javain ) ( const PLFLT * ArrayY, PLINT ny ) "$javainput"
870 %typemap ( javaout ) ( const PLFLT * ArrayY, PLINT ny )
871 {
872     return $jnicall;
873 }
874 
875 %typemap( in ) const PLFLT * ArrayY {
876     jPLFLT *jydata = ( *jenv )->GetPLFLTArrayElements( jenv, $input, 0 );
877     Ylen = ( *jenv )->GetArrayLength( jenv, $input );
878     setup_array_1d_PLFLT( &$1, jydata, Ylen );
879     ( *jenv )->ReleasePLFLTArrayElements( jenv, $input, jydata, 0 );
880 }
881 %typemap( freearg ) const PLFLT * ArrayY {
882     free( $1 );
883 }
884 %typemap( jni ) const PLFLT * ArrayY jPLFLTArray
885 %typemap( jtype ) const PLFLT * ArrayY jPLFLTbracket
886 %typemap( jstype ) const PLFLT * ArrayY jPLFLTbracket
887 %typemap( javain ) const PLFLT * ArrayY "$javainput"
888 %typemap( javaout ) const PLFLT * ArrayY {
889     return $jnicall;
890 }
891 
892 // with trailing count
893 %typemap ( in ) ( const PLFLT * Array, PLINT n )
894 {
895     jPLFLT *jxdata = ( *jenv )->GetPLFLTArrayElements( jenv, $input, 0 );
896     $2 = ( *jenv )->GetArrayLength( jenv, $input );
897     setup_array_1d_PLFLT( &$1, jxdata, $2 );
898     ( *jenv )->ReleasePLFLTArrayElements( jenv, $input, jxdata, 0 );
899 }
900 %typemap ( freearg ) ( const PLFLT * Array, PLINT n )
901 {
902     free( $1 );
903 }
904 %typemap ( jni ) ( const PLFLT * Array, PLINT n ) jPLFLTArray
905 %typemap ( jtype ) ( const PLFLT * Array, PLINT n ) jPLFLTbracket
906 %typemap ( jstype ) ( const PLFLT * Array, PLINT n ) jPLFLTbracket
907 %typemap ( javain ) ( const PLFLT * Array, PLINT n ) "$javainput"
908 %typemap ( javaout ) ( const PLFLT * Array, PLINT n )
909 {
910     return $jnicall;
911 }
912 
913 // with no trailing count
914 %typemap( in ) const PLFLT * Array {
915     jPLFLT *jxdata = ( *jenv )->GetPLFLTArrayElements( jenv, $input, 0 );
916     Alen = ( *jenv )->GetArrayLength( jenv, $input );
917     setup_array_1d_PLFLT( &$1, jxdata, Alen );
918     ( *jenv )->ReleasePLFLTArrayElements( jenv, $input, jxdata, 0 );
919 }
920 %typemap( freearg ) const PLFLT * Array {
921     free( $1 );
922 }
923 %typemap( jni ) const PLFLT * Array jPLFLTArray
924 %typemap( jtype ) const PLFLT * Array jPLFLTbracket
925 %typemap( jstype ) const PLFLT * Array jPLFLTbracket
926 %typemap( javain ) const PLFLT * Array "$javainput"
927 %typemap( javaout ) const PLFLT * Array {
928     return $jnicall;
929 }
930 
931 
932 // with no trailing count
933 %typemap( in ) const PLFLT * ArrayNull {
934     if ( $input != NULL )
935     {
936         jPLFLT *jxdata = ( *jenv )->GetPLFLTArrayElements( jenv, $input, 0 );
937         Alen = ( *jenv )->GetArrayLength( jenv, $input );
938         setup_array_1d_PLFLT( &$1, jxdata, Alen );
939         ( *jenv )->ReleasePLFLTArrayElements( jenv, $input, jxdata, 0 );
940     }
941     else
942     {
943         $1   = NULL;
944         Alen = 0;
945     }
946 }
947 %typemap( freearg ) const PLFLT * ArrayNull {
948     if ( $1 != NULL )
949         free( $1 );
950 }
951 %typemap( jni ) const PLFLT * ArrayNull jPLFLTArray
952 %typemap( jtype ) const PLFLT * ArrayNull jPLFLTbracket
953 %typemap( jstype ) const PLFLT * ArrayNull jPLFLTbracket
954 %typemap( javain ) const PLFLT * ArrayNull "$javainput"
955 %typemap( javaout ) const PLFLT * ArrayNull {
956     return $jnicall;
957 }
958 
959 // check consistency with X dimension of previous
960 %typemap( in ) const PLFLT * ArrayCkX {
961     jPLFLT *jxdata = ( *jenv )->GetPLFLTArrayElements( jenv, $input, 0 );
962     if ( ( *jenv )->GetArrayLength( jenv, $input ) != Xlen )
963     {
964         printf( "Vectors must be same length.\n" );
965         return;
966     }
967     setup_array_1d_PLFLT( &$1, jxdata, Xlen );
968     ( *jenv )->ReleasePLFLTArrayElements( jenv, $input, jxdata, 0 );
969 }
970 %typemap( freearg ) const PLFLT * ArrayCkX {
971     free( $1 );
972 }
973 %typemap( jni ) const PLFLT * ArrayCkX jPLFLTArray
974 %typemap( jtype ) const PLFLT * ArrayCkX jPLFLTbracket
975 %typemap( jstype ) const PLFLT * ArrayCkX jPLFLTbracket
976 %typemap( javain ) const PLFLT * ArrayCkX "$javainput"
977 %typemap( javaout ) const PLFLT * ArrayCkX {
978     return $jnicall;
979 }
980 
981 // check consistency with Y dimension of previous
982 %typemap( in ) const PLFLT * ArrayCkY {
983     jPLFLT *jydata = ( *jenv )->GetPLFLTArrayElements( jenv, $input, 0 );
984     if ( ( *jenv )->GetArrayLength( jenv, $input ) != Ylen )
985     {
986         printf( "Vectors must be same length.\n" );
987         return;
988     }
989     setup_array_1d_PLFLT( &$1, jydata, Ylen );
990     ( *jenv )->ReleasePLFLTArrayElements( jenv, $input, jydata, 0 );
991 }
992 %typemap( freearg ) const PLFLT * ArrayCkY {
993     free( $1 );
994 }
995 %typemap( jni ) const PLFLT * ArrayCkY jPLFLTArray
996 %typemap( jtype ) const PLFLT * ArrayCkY jPLFLTbracket
997 %typemap( jstype ) const PLFLT * ArrayCkY jPLFLTbracket
998 %typemap( javain ) const PLFLT * ArrayCkY "$javainput"
999 %typemap( javaout ) const PLFLT * ArrayCkY {
1000     return $jnicall;
1001 }
1002 
1003 // 2D array with trailing dimensions, check consistency with previous
1004 %typemap ( in ) ( const PLFLT **MatrixCk, PLINT nx, PLINT ny )
1005 {
1006     jPLFLT  **adat;
1007     jobject *ai;
1008     int     nx = ( *jenv )->GetArrayLength( jenv, $input );
1009     int     ny = -1;
1010     int     i, j;
1011     ai   = (jobject *) malloc( (size_t) nx * sizeof ( jobject ) );
1012     adat = (jPLFLT **) malloc( (size_t) nx * sizeof ( jPLFLT * ) );
1013 
1014     ( *jenv )->EnsureLocalCapacity( jenv, nx );
1015 
1016     for ( i = 0; i < nx; i++ )
1017     {
1018         ai[i]   = ( *jenv )->GetObjectArrayElement( jenv, $input, i );
1019         adat[i] = ( *jenv )->GetPLFLTArrayElements( jenv, ai[i], 0 );
1020 
1021         if ( ny == -1 )
1022             ny = ( *jenv )->GetArrayLength( jenv, ai[i] );
1023         else if ( ny != ( *jenv )->GetArrayLength( jenv, ai[i] ) )
1024         {
1025             printf( "Misshapen a array.\n" );
1026             for ( j = 0; j <= i; j++ )
1027                 ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[j], adat[j], 0 );
1028             free( adat );
1029             free( ai );
1030             return;
1031         }
1032     }
1033 
1034     if ( nx != Xlen || ny != Ylen )
1035     {
1036         printf( "Vectors must match matrix.\n" );
1037         for ( i = 0; i < nx; i++ )
1038             ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[i], adat[i], 0 );
1039         free( adat );
1040         free( ai );
1041         return;
1042     }
1043     setup_array_2d_PLFLT( &$1, adat, nx, ny );
1044     $2 = nx;
1045     $3 = ny;
1046     for ( i = 0; i < nx; i++ )
1047     {
1048         ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[i], adat[i], 0 );
1049         ( *jenv )->DeleteLocalRef( jenv, ai[i] );
1050     }
1051 
1052 
1053     free( adat );
1054     free( ai );
1055 }
1056 %typemap ( freearg ) ( const PLFLT **MatrixCk, PLINT nx, PLINT ny )
1057 {
1058     free( $1[0] );
1059     free( $1 );
1060 }
1061 %typemap ( jni ) ( const PLFLT **MatrixCk, PLINT nx, PLINT ny ) "jobjectArray"
1062 %typemap ( jtype ) ( const PLFLT **MatrixCk, PLINT nx, PLINT ny ) jPLFLTbracket2
1063 %typemap ( jstype ) ( const PLFLT **MatrixCk, PLINT nx, PLINT ny ) jPLFLTbracket2
1064 %typemap ( javain ) ( const PLFLT **MatrixCk, PLINT nx, PLINT ny ) "$javainput"
1065 %typemap ( javaout ) ( const PLFLT **MatrixCk, PLINT nx, PLINT ny )
1066 {
1067     return $jnicall;
1068 }
1069 
1070 // 2D array with trailing dimensions, set the X, Y size for later checking
1071 %typemap ( in ) ( const PLFLT **Matrix, PLINT nx, PLINT ny )
1072 {
1073     jPLFLT  **adat;
1074     jobject *ai;
1075     int     nx = ( *jenv )->GetArrayLength( jenv, $input );
1076     int     ny = -1;
1077     int     i, j;
1078     ai   = (jobject *) malloc( (size_t) nx * sizeof ( jobject ) );
1079     adat = (jPLFLT **) malloc( (size_t) nx * sizeof ( jPLFLT * ) );
1080 
1081     ( *jenv )->EnsureLocalCapacity( jenv, nx );
1082 
1083     for ( i = 0; i < nx; i++ )
1084     {
1085         ai[i]   = ( *jenv )->GetObjectArrayElement( jenv, $input, i );
1086         adat[i] = ( *jenv )->GetPLFLTArrayElements( jenv, ai[i], 0 );
1087 
1088         if ( ny == -1 )
1089             ny = ( *jenv )->GetArrayLength( jenv, ai[i] );
1090         else if ( ny != ( *jenv )->GetArrayLength( jenv, ai[i] ) )
1091         {
1092             printf( "Misshapen a array.\n" );
1093             for ( j = 0; j <= i; j++ )
1094                 ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[j], adat[j], 0 );
1095             free( adat );
1096             free( ai );
1097             return;
1098         }
1099     }
1100 
1101     Xlen = nx;
1102     Ylen = ny;
1103     setup_array_2d_PLFLT( &$1, adat, nx, ny );
1104     $2 = nx;
1105     $3 = ny;
1106     for ( i = 0; i < nx; i++ )
1107     {
1108         ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[i], adat[i], 0 );
1109         ( *jenv )->DeleteLocalRef( jenv, ai[i] );
1110     }
1111 
1112     free( adat );
1113     free( ai );
1114 }
1115 %typemap ( freearg ) ( const PLFLT **Matrix, PLINT nx, PLINT ny )
1116 {
1117     free( $1[0] );
1118     free( $1 );
1119 }
1120 %typemap ( jni ) ( const PLFLT **Matrix, PLINT nx, PLINT ny ) "jobjectArray"
1121 %typemap ( jtype ) ( const PLFLT **Matrix, PLINT nx, PLINT ny ) jPLFLTbracket2
1122 %typemap ( jstype ) ( const PLFLT **Matrix, PLINT nx, PLINT ny ) jPLFLTbracket2
1123 %typemap ( javain ) ( const PLFLT **Matrix, PLINT nx, PLINT ny ) "$javainput"
1124 %typemap ( javaout ) ( const PLFLT **Matrix, PLINT nx, PLINT ny )
1125 {
1126     return $jnicall;
1127 }
1128 
1129 // 2D array with no trailing dimensions, set the X, Y size for later checking
1130 %typemap( in ) const PLFLT * *Matrix {
1131     jPLFLT  **adat;
1132     jobject *ai;
1133     int     nx = ( *jenv )->GetArrayLength( jenv, $input );
1134     int     ny = -1;
1135     int     i, j;
1136     ai   = (jobject *) malloc( (size_t) nx * sizeof ( jobject ) );
1137     adat = (jPLFLT **) malloc( (size_t) nx * sizeof ( jPLFLT * ) );
1138 
1139     ( *jenv )->EnsureLocalCapacity( jenv, nx );
1140 
1141     for ( i = 0; i < nx; i++ )
1142     {
1143         ai[i]   = ( *jenv )->GetObjectArrayElement( jenv, $input, i );
1144         adat[i] = ( *jenv )->GetPLFLTArrayElements( jenv, ai[i], 0 );
1145 
1146         if ( ny == -1 )
1147             ny = ( *jenv )->GetArrayLength( jenv, ai[i] );
1148         else if ( ny != ( *jenv )->GetArrayLength( jenv, ai[i] ) )
1149         {
1150             printf( "Misshapen a array.\n" );
1151             for ( j = 0; j <= i; j++ )
1152                 ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[j], adat[j], 0 );
1153             free( adat );
1154             free( ai );
1155             return;
1156         }
1157     }
1158 
1159     Xlen = nx;
1160     Ylen = ny;
1161     setup_array_2d_PLFLT( &$1, adat, nx, ny );
1162     for ( i = 0; i < nx; i++ )
1163     {
1164         ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[i], adat[i], 0 );
1165         ( *jenv )->DeleteLocalRef( jenv, ai[i] );
1166     }
1167 
1168     free( adat );
1169     free( ai );
1170 }
1171 %typemap( freearg ) const PLFLT * *Matrix {
1172     free( $1[0] );
1173     free( $1 );
1174 }
1175 %typemap( jni ) const PLFLT * *Matrix "jobjectArray"
1176 %typemap( jtype ) const PLFLT * *Matrix jPLFLTbracket2
1177 %typemap( jstype ) const PLFLT * *Matrix jPLFLTbracket2
1178 %typemap( javain ) const PLFLT * *Matrix "$javainput"
1179 %typemap( javaout ) const PLFLT * *Matrix {
1180     return $jnicall;
1181 }
1182 
1183 // 2D array, check for consistency
1184 %typemap( in ) const PLFLT * *MatrixCk {
1185     jPLFLT  **adat;
1186     jobject *ai;
1187     int     nx = ( *jenv )->GetArrayLength( jenv, $input );
1188     int     ny = -1;
1189     int     i, j;
1190     ai   = (jobject *) malloc( (size_t) nx * sizeof ( jobject ) );
1191     adat = (jPLFLT **) malloc( (size_t) nx * sizeof ( jPLFLT * ) );
1192 
1193     ( *jenv )->EnsureLocalCapacity( jenv, nx );
1194 
1195     for ( i = 0; i < nx; i++ )
1196     {
1197         ai[i]   = ( *jenv )->GetObjectArrayElement( jenv, $input, i );
1198         adat[i] = ( *jenv )->GetPLFLTArrayElements( jenv, ai[i], 0 );
1199 
1200         if ( ny == -1 )
1201             ny = ( *jenv )->GetArrayLength( jenv, ai[i] );
1202         else if ( ny != ( *jenv )->GetArrayLength( jenv, ai[i] ) )
1203         {
1204             printf( "Misshapen a array.\n" );
1205             for ( j = 0; j <= i; j++ )
1206                 ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[j], adat[j], 0 );
1207             free( adat );
1208             free( ai );
1209             return;
1210         }
1211     }
1212 
1213     if ( nx != Xlen || ny != Ylen )
1214     {
1215         printf( "Vectors must match matrix.\n" );
1216         for ( i = 0; i < nx; i++ )
1217             ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[i], adat[i], 0 );
1218         free( adat );
1219         free( ai );
1220         return;
1221     }
1222     setup_array_2d_PLFLT( &$1, adat, nx, ny );
1223     for ( i = 0; i < nx; i++ )
1224     {
1225         ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[i], adat[i], 0 );
1226         ( *jenv )->DeleteLocalRef( jenv, ai[i] );
1227     }
1228 
1229     free( adat );
1230     free( ai );
1231 }
1232 %typemap( freearg ) const PLFLT * *MatrixCk {
1233     free( $1[0] );
1234     free( $1 );
1235 }
1236 %typemap( jni ) const PLFLT * *MatrixCk "jobjectArray"
1237 %typemap( jtype ) const PLFLT * *MatrixCk jPLFLTbracket2
1238 %typemap( jstype ) const PLFLT * *MatrixCk jPLFLTbracket2
1239 %typemap( javain ) const PLFLT * *MatrixCk "$javainput"
1240 %typemap( javaout ) const PLFLT * *MatrixCk {
1241     return $jnicall;
1242 }
1243 
1244 // 2D array, check for consistency
1245 // Version with values returned to java
1246 %typemap( in ) PLFLT * *OutMatrixCk {
1247     jobject ai;
1248     PLFLT   **ptr;
1249     int     nx = ( *jenv )->GetArrayLength( jenv, $input );
1250     int     ny = -1;
1251     int     i;
1252 
1253     ( *jenv )->EnsureLocalCapacity( jenv, nx );
1254 
1255     for ( i = 0; i < nx; i++ )
1256     {
1257         ai = ( *jenv )->GetObjectArrayElement( jenv, $input, i );
1258 
1259         if ( ny == -1 )
1260             ny = ( *jenv )->GetArrayLength( jenv, ai );
1261         else if ( ny != ( *jenv )->GetArrayLength( jenv, ai ) )
1262         {
1263             printf( "Misshapen a array.\n" );
1264             return;
1265         }
1266     }
1267 
1268     if ( nx != Xlen || ny != Ylen )
1269     {
1270         printf( "Vectors must match matrix.\n" );
1271         return;
1272     }
1273 
1274     ptr    = (PLFLT **) malloc( (size_t) nx * sizeof ( PLFLT * ) );
1275     ptr[0] = (PLFLT *) malloc( (size_t) nx * ny * sizeof ( PLFLT ) );
1276     for ( i = 0; i < nx; i++ )
1277     {
1278         ptr[i] = ptr[0] + i * ny;
1279     }
1280 
1281     $1 = ptr;
1282 }
1283 %typemap( argout ) PLFLT * *OutMatrixCk {
1284     jPLFLT  **adat;
1285     jobject *ai;
1286     PLFLT   **ptr;
1287     int     i, j;
1288     int     nx = ( *jenv )->GetArrayLength( jenv, $input );
1289     int     ny = -1;
1290 
1291     ptr = $1;
1292 
1293     ai   = (jobject *) malloc( (size_t) nx * sizeof ( jobject ) );
1294     adat = (jPLFLT **) malloc( (size_t) nx * sizeof ( jPLFLT * ) );
1295 
1296     for ( i = 0; i < nx; i++ )
1297     {
1298         ai[i]   = ( *jenv )->GetObjectArrayElement( jenv, $input, i );
1299         adat[i] = ( *jenv )->GetPLFLTArrayElements( jenv, ai[i], 0 );
1300 
1301         if ( ny == -1 )
1302             ny = ( *jenv )->GetArrayLength( jenv, ai[i] );
1303     }
1304     for ( i = 0; i < nx; i++ )
1305     {
1306         for ( j = 0; j < ny; j++ )
1307         {
1308             adat[i][j] = ptr[i][j];
1309         }
1310         ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[i], adat[i], 0 );
1311         ( *jenv )->DeleteLocalRef( jenv, ai[i] );
1312     }
1313 
1314     free( adat );
1315     free( ai );
1316 }
1317 %typemap( freearg ) PLFLT * *OutMatrixCk {
1318     free( $1[0] );
1319     free( $1 );
1320 }
1321 %typemap( jni ) PLFLT * *OutMatrixCk "jobjectArray"
1322 %typemap( jtype ) PLFLT * *OutMatrixCk jPLFLTbracket2
1323 %typemap( jstype ) PLFLT * *OutMatrixCk jPLFLTbracket2
1324 %typemap( javain ) PLFLT * *OutMatrixCk "$javainput"
1325 %typemap( javaout ) PLFLT * *OutMatrixCk {
1326     return $jnicall;
1327 }
1328 
1329 
1330 %{
1331     typedef PLINT ( *defined_func )( PLFLT, PLFLT );
1332     typedef void ( *fill_func )( PLINT, const PLFLT*, const PLFLT* );
1333     typedef void ( *pltr_func )( PLFLT, PLFLT, PLFLT *, PLFLT*, PLPointer );
1334     typedef void ( *ct_func )( PLFLT, PLFLT, PLFLT *, PLFLT*, PLPointer );
1335     typedef void ( *mapform_func )( PLINT, PLFLT *, PLFLT* );
1336     typedef PLFLT ( *f2eval_func )( PLINT, PLINT, PLPointer );
1337     typedef void ( *label_func )( PLINT, PLFLT, char *, PLINT, PLPointer );
1338 %}
1339 
1340 // First of two object arrays, where we check X and Y with previous.
1341 // Note this is the simplified Tcl-like approach to handling the xg
1342 // and yg arrays.  Later we would like to move to true call-back functions
1343 // here instead like is done with the python interface.
1344 %typemap( in ) pltr_func pltr {
1345     jPLFLT  **adat;
1346     jobject *ai;
1347     int     nx = ( *jenv )->GetArrayLength( jenv, $input );
1348     int     ny = -1;
1349     int     i, j;
1350     ai   = (jobject *) malloc( (size_t) nx * sizeof ( jobject ) );
1351     adat = (jPLFLT **) malloc( (size_t) nx * sizeof ( jPLFLT * ) );
1352 
1353     ( *jenv )->EnsureLocalCapacity( jenv, nx );
1354 
1355     for ( i = 0; i < nx; i++ )
1356     {
1357         ai[i]   = ( *jenv )->GetObjectArrayElement( jenv, $input, i );
1358         adat[i] = ( *jenv )->GetPLFLTArrayElements( jenv, ai[i], 0 );
1359 
1360         if ( ny == -1 )
1361             ny = ( *jenv )->GetArrayLength( jenv, ai[i] );
1362         else if ( ny != ( *jenv )->GetArrayLength( jenv, ai[i] ) )
1363         {
1364             printf( "Misshapen a array.\n" );
1365             for ( j = 0; j <= i; j++ )
1366                 ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[j], adat[j], 0 );
1367             free( adat );
1368             free( ai );
1369             return;
1370         }
1371     }
1372 
1373     if ( !( ( nx == Xlen && ny == Ylen ) || ( nx == Xlen && ny == 1 ) ) )
1374     {
1375         printf( "Xlen =%d, nx =%d, Ylen =%d, ny =%d\n", Xlen, nx, Ylen, ny );
1376         printf( "X vector or matrix must match matrix dimensions.\n" );
1377         for ( i = 0; i < nx; i++ )
1378             ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[i], adat[i], 0 );
1379         free( adat );
1380         free( ai );
1381         return;
1382     }
1383     // Store whether second dimension is unity.
1384     Alen = ny;
1385     setup_array_2d_PLFLT( &xg, adat, nx, ny );
1386     for ( i = 0; i < nx; i++ )
1387     {
1388         ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[i], adat[i], 0 );
1389         ( *jenv )->DeleteLocalRef( jenv, ai[i] );
1390     }
1391 
1392     free( adat );
1393     free( ai );
1394     $1 = pltr2;
1395 }
1396 
1397 %typemap( freearg ) pltr_func pltr {
1398     free( xg[0] );
1399     free( xg );
1400 }
1401 %typemap( jni ) pltr_func pltr "jobjectArray"
1402 %typemap( jtype ) pltr_func pltr jPLFLTbracket2
1403 %typemap( jstype ) pltr_func pltr jPLFLTbracket2
1404 %typemap( javain ) pltr_func pltr "$javainput"
1405 %typemap( javaout ) pltr_func pltr {
1406     return $jnicall;
1407 }
1408 
1409 %{
1410     jobject   mapformClass;
1411     jmethodID mapformID;
1412     JNIEnv    *cbenvMapform;
1413 
1414     void mapform_java( PLINT n, PLFLT *x, PLFLT *y );
1415 
1416     // C mapform callback function which calls the java
1417     // mapform function in a PLCallbackMapform object.
mapform_java(PLINT n,PLFLT * x,PLFLT * y)1418     void mapform_java( PLINT n, PLFLT *x, PLFLT *y )
1419     {
1420         jdoubleArray jx = setup_java_array_1d_PLFLT( cbenvMapform, x, n );
1421         jdoubleArray jy = setup_java_array_1d_PLFLT( cbenvMapform, y, n );
1422         ( *cbenvMapform )->CallVoidMethod( cbenvMapform, mapformClass, mapformID, jx, jy );
1423         release_java_array_1d_PLFLT( cbenvMapform, jx, x, n );
1424         release_java_array_1d_PLFLT( cbenvMapform, jy, y, n );
1425     }
1426 %}
1427 
1428 
1429 // Handle function pointers to mapform function using an java class
1430 %typemap( in ) mapform_func mapform {
1431     jobject obj = $input;
1432     if ( obj != NULL )
1433     {
1434         jclass cls = ( *jenv )->GetObjectClass( jenv, obj );
1435         mapformID    = ( *jenv )->GetMethodID( jenv, cls, "mapform", "([D[D)V" );
1436         mapformClass = obj;
1437         cbenvMapform = jenv;
1438         $1           = mapform_java;
1439     }
1440     else
1441     {
1442         $1 = NULL;
1443     }
1444 }
1445 
1446 %typemap( jni ) mapform_func "jobject"
1447 %typemap( jtype ) mapform_func "PLCallbackMapform"
1448 %typemap( jstype ) mapform_func "PLCallbackMapform"
1449 %typemap( javain ) mapform_func mapform "$javainput"
1450 
1451 %{
1452     jobject labelClass    = 0;
1453     jobject labelClassRef = 0;
1454 
1455     void label_java( PLINT axis, PLFLT value, char *string, PLINT len, PLPointer data );
1456 
1457     // C label plotting callback function which calls the java
1458     // label function in a PLCallbackLabel labelClassobelID
1459 // bject.
label_java(PLINT axis,PLFLT value,char * string,PLINT len,PLPointer PL_UNUSED (data))1460     void label_java( PLINT axis, PLFLT value, char *string, PLINT len, PLPointer PL_UNUSED( data ) )
1461     {
1462         jstring    javaString;
1463         const char *nativeString;
1464         jint       jaxis;
1465         jdouble    jvalue;
1466         JNIEnv     *cbenv;
1467         jmethodID  labelID = 0;
1468         jclass     cls;
1469 
1470         jaxis  = (jint) axis;
1471         jvalue = (jdouble) value;
1472 
1473         if ( ( string == NULL ) || ( len == 0 ) )
1474         {
1475             return;
1476         }
1477 
1478         string[0] = '\0';
1479 
1480         if ( cached_jvm == NULL )
1481         {
1482             fprintf( stderr, "Error! NULL jvm\n" );
1483             return;
1484         }
1485         ( *cached_jvm )->GetEnv( cached_jvm, (void **) &cbenv, JNI_VERSION_1_2 );
1486         if ( cbenv == NULL )
1487         {
1488             fprintf( stderr, "Thread not attached\n" );
1489             if ( ( *cached_jvm )->AttachCurrentThread( cached_jvm, (void **) &cbenv, NULL ) != 0 )
1490             {
1491                 fprintf( stderr, "Error attaching to JVM\n" );
1492                 return;
1493             }
1494         }
1495         if ( labelClass == 0 )
1496         {
1497             fprintf( stderr, "Error - callback undefined\n" );
1498             return;
1499         }
1500         cls = ( *cbenv )->GetObjectClass( cbenv, labelClass );
1501         if ( cls == 0 )
1502         {
1503             fprintf( stderr, "Error getting callback class\n" );
1504             return;
1505         }
1506         labelID = ( *cbenv )->GetMethodID( cbenv, cls, "label", "(ID)Ljava/lang/String;" );
1507         if ( labelID != 0 )
1508         {
1509             javaString   = (jstring) ( *cbenv )->CallObjectMethod( cbenv, labelClass, labelID, jaxis, jvalue );
1510             nativeString = ( *cbenv )->GetStringUTFChars( cbenv, javaString, 0 );
1511             strncpy( string, nativeString, (size_t) len );
1512             ( *cbenv )->ReleaseStringUTFChars( cbenv, javaString, nativeString );
1513         }
1514         else
1515         {
1516             fprintf( stderr, "Java callback not found\n" );
1517             string[0] = '\0';
1518         }
1519     }
1520 %}
1521 
1522 
1523 // Handle function pointers to label function using an java class
1524 %typemap( in ) label_func lf {
1525     jobject obj = $input;
1526 
1527     // Delete any old references
1528     if ( labelClass != 0 )
1529     {
1530         ( *jenv )->DeleteGlobalRef( jenv, labelClass );
1531         labelClass = 0;
1532     }
1533     // Need a reference to this object to ensure it is
1534     // valid when we reach the callback
1535     if ( obj != NULL )
1536     {
1537         labelClass = ( *jenv )->NewGlobalRef( jenv, obj );
1538     }
1539     if ( labelClass != 0 )
1540     {
1541         $1 = label_java;
1542     }
1543     else
1544     {
1545         $1 = NULL;
1546     }
1547 }
1548 
1549 %typemap( jni ) label_func lf "jobject"
1550 %typemap( jtype ) label_func lf "PLCallbackLabel"
1551 %typemap( jstype ) label_func lf "PLCallbackLabel"
1552 %typemap( javain ) label_func lf "$javainput"
1553 
1554 %{
1555     jobject ctClass    = 0;
1556     jobject ctClassRef = 0;
1557 
1558     void ct_java( PLFLT x, PLFLT y, PLFLT *xt, PLFLT *yt, PLPointer data );
1559 
1560     // C coordinate transform callback function which calls the java
1561     // coordinate transform function in a PLCallbackCoordTrans object.
ct_java(PLFLT x,PLFLT y,PLFLT * xt,PLFLT * yt,PLPointer data)1562     void ct_java( PLFLT x, PLFLT y, PLFLT *xt, PLFLT *yt, PLPointer data )
1563     {
1564         jdouble      jx, jy;
1565         jdoubleArray jxt, jyt;
1566         jdouble      *xtval;
1567         jdouble      *ytval;
1568         jobject      jdata;
1569         JNIEnv       *cbenv;
1570         jmethodID    ctID = 0;
1571         jclass       cls;
1572 
1573         jx    = (jdouble) x;
1574         jy    = (jdouble) y;
1575         jdata = (jobject) data;
1576 
1577         if ( cached_jvm == NULL )
1578         {
1579             fprintf( stderr, "Error! NULL jvm\n" );
1580             return;
1581         }
1582         ( *cached_jvm )->GetEnv( cached_jvm, (void **) &cbenv, JNI_VERSION_1_2 );
1583         if ( cbenv == NULL )
1584         {
1585             fprintf( stderr, "Thread not attached\n" );
1586             if ( ( *cached_jvm )->AttachCurrentThread( cached_jvm, (void **) &cbenv, NULL ) != 0 )
1587             {
1588                 fprintf( stderr, "Error attaching to JVM\n" );
1589                 return;
1590             }
1591         }
1592         jxt = ( *cbenv )->NewDoubleArray( cbenv, 1 );
1593         jyt = ( *cbenv )->NewDoubleArray( cbenv, 1 );
1594         if ( ctClass == 0 )
1595         {
1596             fprintf( stderr, "Error - callback undefined\n" );
1597             return;
1598         }
1599         cls = ( *cbenv )->GetObjectClass( cbenv, ctClass );
1600         if ( cls == 0 )
1601         {
1602             fprintf( stderr, "Error getting callback class\n" );
1603             return;
1604         }
1605         ctID = ( *cbenv )->GetMethodID( cbenv, cls, "coordTransform", "(DD[D[DLjava/lang/Object;)V" );
1606         if ( ctID != 0 )
1607         {
1608             ( *cbenv )->CallVoidMethod( cbenv, ctClass, ctID, jx, jy, jxt, jyt, jdata );
1609             xtval = ( *cbenv )->GetDoubleArrayElements( cbenv, jxt, JNI_FALSE );
1610             ytval = ( *cbenv )->GetDoubleArrayElements( cbenv, jyt, JNI_FALSE );
1611             *xt   = (PLFLT) xtval[0];
1612             *yt   = (PLFLT) ytval[0];
1613         }
1614         else
1615         {
1616             fprintf( stderr, "Java callback not found\n" );
1617         }
1618     }
1619 %}
1620 
1621 
1622 // Handle function pointers to coordinate transform function using a
1623 // java class
1624 %typemap( in ) ct_func ctf {
1625     jobject obj = $input;
1626 
1627     // Delete any old references
1628     if ( ctClass != 0 )
1629     {
1630         ( *jenv )->DeleteGlobalRef( jenv, ctClass );
1631         ctClass = 0;
1632     }
1633     // Need a reference to this object to ensure it is
1634     // valid when we reach the callback
1635     if ( obj != NULL )
1636     {
1637         ctClass = ( *jenv )->NewGlobalRef( jenv, obj );
1638     }
1639     if ( ctClass != 0 )
1640     {
1641         $1 = ct_java;
1642     }
1643     else
1644     {
1645         $1 = NULL;
1646     }
1647 }
1648 
1649 %typemap( jni ) ct_func ctf "jobject"
1650 %typemap( jtype ) ct_func ctf "PLCallbackCT"
1651 %typemap( jstype ) ct_func ctf "PLCallbackCT"
1652 %typemap( javain ) ct_func ctf "$javainput"
1653 
1654 %typemap( in ) PLPointer data {
1655     $1 = NULL;
1656 }
1657 %typemap( jni ) PLPointer data "jobject"
1658 %typemap( jtype ) PLPointer data "Object"
1659 %typemap( jstype ) PLPointer data "Object"
1660 %typemap( javain ) PLPointer data "$javainput"
1661 
1662 // Second of two object arrays, where we check X and Y with previous object.
1663 %typemap( in ) PLPointer OBJECT_DATA {
1664     jPLFLT  **adat;
1665     jobject *ai;
1666     int     nx = ( *jenv )->GetArrayLength( jenv, $input );
1667     int     ny = -1;
1668     int     i, j;
1669     ai   = (jobject *) malloc( (size_t) nx * sizeof ( jobject ) );
1670     adat = (jPLFLT **) malloc( (size_t) nx * sizeof ( jPLFLT * ) );
1671 
1672     ( *jenv )->EnsureLocalCapacity( jenv, nx );
1673 
1674     for ( i = 0; i < nx; i++ )
1675     {
1676         ai[i]   = ( *jenv )->GetObjectArrayElement( jenv, $input, i );
1677         adat[i] = ( *jenv )->GetPLFLTArrayElements( jenv, ai[i], 0 );
1678 
1679         if ( ny == -1 )
1680             ny = ( *jenv )->GetArrayLength( jenv, ai[i] );
1681         else if ( ny != ( *jenv )->GetArrayLength( jenv, ai[i] ) )
1682         {
1683             printf( "Misshapen a array.\n" );
1684             for ( j = 0; j <= i; j++ )
1685                 ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[j], adat[j], 0 );
1686             free( adat );
1687             free( ai );
1688             return;
1689         }
1690     }
1691 
1692     if ( !( ( nx == Xlen && ny == Ylen ) || ( nx == Ylen && ny == 1 && ny == Alen ) ) )
1693     {
1694         printf( "Xlen =%d, nx =%d, Ylen =%d, Alen =%d, ny =%d\n",
1695             Xlen, nx, Ylen, Alen, ny );
1696         printf( "Y vector or matrix must match matrix dimensions.\n" );
1697         for ( i = 0; i < nx; i++ )
1698             ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[i], adat[i], 0 );
1699         free( adat );
1700         free( ai );
1701         return;
1702     }
1703     setup_array_2d_PLFLT( &yg, adat, nx, ny );
1704     for ( i = 0; i < nx; i++ )
1705     {
1706         ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[i], adat[i], 0 );
1707         ( *jenv )->DeleteLocalRef( jenv, ai[i] );
1708     }
1709 
1710     free( adat );
1711     free( ai );
1712     cgrid     = (PLcGrid2 *) malloc( sizeof ( PLcGrid2 ) );
1713     cgrid->xg = xg;
1714     cgrid->yg = yg;
1715     cgrid->nx = nx;
1716     cgrid->ny = ny;
1717     $1        = cgrid;
1718 }
1719 
1720 %typemap( freearg ) PLPointer OBJECT_DATA {
1721     free( yg[0] );
1722     free( yg );
1723     free( cgrid );
1724 }
1725 %typemap( jni ) PLPointer OBJECT_DATA "jobjectArray"
1726 %typemap( jtype ) PLPointer OBJECT_DATA jPLFLTbracket2
1727 %typemap( jstype ) PLPointer OBJECT_DATA jPLFLTbracket2
1728 %typemap( javain ) PLPointer OBJECT_DATA "$javainput"
1729 %typemap( javaout ) PLPointer OBJECT_DATA {
1730     return $jnicall;
1731 }
1732 
1733 // First of two object arrays, where we check X and Y with previous.
1734 // Note this is the simplified Tcl-like approach to handling the xg
1735 // and yg arrays.  Later we would like to move to true call-back functions
1736 // here instead like is done with the python interface.
1737 // This is the version for plimagefr where size is 1 larger than previous
1738 // array
1739 %typemap( in ) pltr_func pltr_img {
1740     jPLFLT  **adat;
1741     jobject *ai;
1742     int     nx = ( *jenv )->GetArrayLength( jenv, $input );
1743     int     ny = -1;
1744     int     i, j;
1745     ai   = (jobject *) malloc( (size_t) nx * sizeof ( jobject ) );
1746     adat = (jPLFLT **) malloc( (size_t) nx * sizeof ( jPLFLT * ) );
1747 
1748     ( *jenv )->EnsureLocalCapacity( jenv, nx );
1749 
1750     for ( i = 0; i < nx; i++ )
1751     {
1752         ai[i]   = ( *jenv )->GetObjectArrayElement( jenv, $input, i );
1753         adat[i] = ( *jenv )->GetPLFLTArrayElements( jenv, ai[i], 0 );
1754 
1755         if ( ny == -1 )
1756             ny = ( *jenv )->GetArrayLength( jenv, ai[i] );
1757         else if ( ny != ( *jenv )->GetArrayLength( jenv, ai[i] ) )
1758         {
1759             printf( "Misshapen a array.\n" );
1760             for ( j = 0; j <= i; j++ )
1761                 ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[j], adat[j], 0 );
1762             free( adat );
1763             free( ai );
1764             return;
1765         }
1766     }
1767 
1768     if ( !( ( nx == Xlen + 1 && ny == Ylen + 1 ) || ( nx == Xlen + 1 && ny == 1 ) ) )
1769     {
1770         printf( "Xlen =%d, nx =%d, Ylen =%d, ny =%d\n", Xlen, nx, Ylen, ny );
1771         printf( "X vector or matrix must match matrix dimensions.\n" );
1772         for ( i = 0; i < nx; i++ )
1773             ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[i], adat[i], 0 );
1774         free( adat );
1775         free( ai );
1776         return;
1777     }
1778     // Store whether second dimension is unity.
1779     Alen = ny;
1780     setup_array_2d_PLFLT( &xg, adat, nx, ny );
1781     for ( i = 0; i < nx; i++ )
1782     {
1783         ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[i], adat[i], 0 );
1784         ( *jenv )->DeleteLocalRef( jenv, ai[i] );
1785     }
1786 
1787     free( adat );
1788     free( ai );
1789     $1 = pltr2;
1790 }
1791 
1792 %typemap( freearg ) pltr_func pltr_img {
1793     free( xg[0] );
1794     free( xg );
1795 }
1796 %typemap( jni ) pltr_func pltr_img "jobjectArray"
1797 %typemap( jtype ) pltr_func pltr_img jPLFLTbracket2
1798 %typemap( jstype ) pltr_func pltr_img jPLFLTbracket2
1799 %typemap( javain ) pltr_func pltr_img "$javainput"
1800 %typemap( javaout ) pltr_func pltr_img {
1801     return $jnicall;
1802 }
1803 
1804 // Second of two object arrays, where we check X and Y with previous object.
1805 // This is the version for plimagefr where size is 1 larger than previous
1806 // array
1807 %typemap( in ) PLPointer OBJECT_DATA_img {
1808     jPLFLT  **adat;
1809     jobject *ai;
1810     int     nx = ( *jenv )->GetArrayLength( jenv, $input );
1811     int     ny = -1;
1812     int     i, j;
1813     ai   = (jobject *) malloc( (size_t) nx * sizeof ( jobject ) );
1814     adat = (jPLFLT **) malloc( (size_t) nx * sizeof ( jPLFLT * ) );
1815 
1816     ( *jenv )->EnsureLocalCapacity( jenv, nx );
1817 
1818     for ( i = 0; i < nx; i++ )
1819     {
1820         ai[i]   = ( *jenv )->GetObjectArrayElement( jenv, $input, i );
1821         adat[i] = ( *jenv )->GetPLFLTArrayElements( jenv, ai[i], 0 );
1822 
1823         if ( ny == -1 )
1824             ny = ( *jenv )->GetArrayLength( jenv, ai[i] );
1825         else if ( ny != ( *jenv )->GetArrayLength( jenv, ai[i] ) )
1826         {
1827             printf( "Misshapen a array.\n" );
1828             for ( j = 0; j <= i; j++ )
1829                 ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[j], adat[j], 0 );
1830             free( adat );
1831             free( ai );
1832             return;
1833         }
1834     }
1835 
1836     if ( !( ( nx == Xlen + 1 && ny == Ylen + 1 ) || ( nx == Ylen + 1 && ny == 1 && ny == Alen ) ) )
1837     {
1838         printf( "Xlen =%d, nx =%d, Ylen =%d, Alen =%d, ny =%d\n",
1839             Xlen, nx, Ylen, Alen, ny );
1840         printf( "Y vector or matrix must match matrix dimensions.\n" );
1841         for ( i = 0; i < nx; i++ )
1842             ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[i], adat[i], 0 );
1843         free( adat );
1844         free( ai );
1845         return;
1846     }
1847     setup_array_2d_PLFLT( &yg, adat, nx, ny );
1848     for ( i = 0; i < nx; i++ )
1849     {
1850         ( *jenv )->ReleasePLFLTArrayElements( jenv, ai[i], adat[i], 0 );
1851         ( *jenv )->DeleteLocalRef( jenv, ai[i] );
1852     }
1853 
1854     free( adat );
1855     free( ai );
1856     cgrid     = (PLcGrid2 *) malloc( sizeof ( PLcGrid2 ) );
1857     cgrid->xg = xg;
1858     cgrid->yg = yg;
1859     cgrid->nx = nx;
1860     cgrid->ny = ny;
1861     $1        = cgrid;
1862 }
1863 
1864 %typemap( freearg ) PLPointer OBJECT_DATA_img {
1865     free( yg[0] );
1866     free( yg );
1867     free( cgrid );
1868 }
1869 %typemap( jni ) PLPointer OBJECT_DATA_img "jobjectArray"
1870 %typemap( jtype ) PLPointer OBJECT_DATA_img jPLFLTbracket2
1871 %typemap( jstype ) PLPointer OBJECT_DATA_img jPLFLTbracket2
1872 %typemap( javain ) PLPointer OBJECT_DATA_img "$javainput"
1873 %typemap( javaout ) PLPointer OBJECT_DATA_img {
1874     return $jnicall;
1875 }
1876 
1877 // Do not specify defined function or fill function from java.  Instead
1878 // specify NULL and plfill defaults in the interface C code.
1879 %typemap( in, numinputs = 0 ) defined_func df {
1880     $1 = NULL;
1881 }
1882 %typemap( in, numinputs = 0 ) fill_func ff {
1883     $1 = plfill;
1884 }
1885 
1886 //**************************
1887 //        String returning functions
1888 //        Adopt method in SWIG-1.3.21/Examples/java/typemap/example.i
1889 //***************************
1890 
1891 // Define the types to use in the generated JNI C code and Java code
1892 %typemap( jni ) char *OUTPUT "jobject"
1893 %typemap( jtype ) char *OUTPUT "StringBuffer"
1894 %typemap( jstype ) char *OUTPUT "StringBuffer"
1895 
1896 // How to convert Java(JNI) type to requested C type
1897 %typemap( in ) char *OUTPUT {
1898     $1 = NULL;
1899     if ( $input != NULL )
1900     {
1901         // Get the String from the StringBuffer
1902         jmethodID setLengthID;
1903         jclass    sbufClass = ( *jenv )->GetObjectClass( jenv, $input );
1904         // Take a copy of the C string as the typemap is for a non const C string
1905         jmethodID capacityID = ( *jenv )->GetMethodID( jenv, sbufClass, "capacity", "()I" );
1906         jint      capacity   = ( *jenv )->CallIntMethod( jenv, $input, capacityID );
1907         $1 = (char *) malloc( (size_t) ( capacity + 1 ) );
1908 
1909         // Zero the original StringBuffer, so we can replace it with the result
1910         setLengthID = ( *jenv )->GetMethodID( jenv, sbufClass, "setLength", "(I)V" );
1911         ( *jenv )->CallVoidMethod( jenv, $input, setLengthID, (jint) 0 );
1912     }
1913 }
1914 
1915 
1916 // How to convert the C type to the Java(JNI) type
1917 %typemap( argout ) char *OUTPUT {
1918     if ( $1 != NULL )
1919     {
1920         // Append the result to the empty StringBuffer
1921         jstring   newString      = ( *jenv )->NewStringUTF( jenv, $1 );
1922         jclass    sbufClass      = ( *jenv )->GetObjectClass( jenv, $input );
1923         jmethodID appendStringID = ( *jenv )->GetMethodID( jenv, sbufClass, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;" );
1924         ( *jenv )->CallObjectMethod( jenv, $input, appendStringID, newString );
1925 
1926         // Clean up the string object, no longer needed
1927         free( $1 );
1928         $1 = NULL;
1929     }
1930 }
1931 // Prevent the default freearg typemap from being used
1932 %typemap( freearg ) char *OUTPUT ""
1933 
1934 // Convert the jstype to jtype typemap type
1935 %typemap( javain ) char *OUTPUT "$javainput"
1936 
1937 // Character arrays:
1938 
1939 %typemap ( jni ) ( int *p_argc, char **argv ) "jobjectArray"
1940 %typemap ( jtype ) ( int *p_argc, char **argv ) "String[]"
1941 %typemap ( jstype ) ( int *p_argc, char **argv ) "String[]"
1942 %typemap ( javain ) ( int *p_argc, char **argv ) "$javainput"
1943 %typemap ( javaout ) ( int *p_argc, char **argv )
1944 {
1945     return $jnicall;
1946 }
1947 %typemap ( in ) ( int *p_argc, char **argv ) ( int size )
1948 {
1949     int i = 0;
1950     size = (int) ( ( *jenv )->GetArrayLength( jenv, $input ) );
1951     $1   = &size;
1952     $2   = (char **) malloc( (size_t) ( size + 1 ) * sizeof ( char * ) );
1953     // make a copy of each string
1954     for ( i = 0; i < size; i++ )
1955     {
1956         jstring    j_string   = (jstring) ( *jenv )->GetObjectArrayElement( jenv, $input, i );
1957         const char * c_string = (const char *) ( *jenv )->GetStringUTFChars( jenv, j_string, 0 );
1958 // Commented out version straight from swig documentation, but I think
1959 // it is wrong.
1960 //    $2[i] = malloc(strlen((c_string)+1)*sizeof(const char *));
1961         $2[i] = malloc( ( strlen( c_string ) + 1 ) * sizeof ( char * ) );
1962         strcpy( $2[i], c_string );
1963         ( *jenv )->ReleaseStringUTFChars( jenv, j_string, c_string );
1964         ( *jenv )->DeleteLocalRef( jenv, j_string );
1965     }
1966     $2[i] = 0;
1967 }
1968 
1969 // This cleans up the memory we malloc'd before the function call
1970 %typemap ( freearg ) ( int *p_argc, char **argv )
1971 {
1972     int i;
1973 // Commented out version straight from swig documentation, but I think
1974 // it is wrong.
1975 // for (i=0; i<size$argnum-1; i++)
1976     for ( i = 0; i < size$argnum; i++ )
1977         free( $2[i] );
1978     free( $2 );
1979 }
1980 
1981 %typemap ( jni ) ( const char *legline[4] ) "jobjectArray"
1982 %typemap ( jtype ) ( const char *legline[4] ) "String[]"
1983 %typemap ( jstype ) ( const char *legline[4] ) "String[]"
1984 %typemap ( javain ) ( const char *legline[4] ) "$javainput"
1985 %typemap ( javaout ) ( const char *legline[4] )
1986 {
1987     return $jnicall;
1988 }
1989 %typemap ( in ) ( const char *legline[4] )
1990 {
1991     int i    = 0;
1992     int size = ( *jenv )->GetArrayLength( jenv, $input );
1993     if ( size != 4 )
1994     {
1995         printf( "legline must be an array of length 4\n" );
1996         return;
1997     }
1998     $1 = (char **) malloc( 4 * sizeof ( char * ) );
1999     // make a copy of each string
2000     for ( i = 0; i < 4; i++ )
2001     {
2002         jstring    j_string   = (jstring) ( *jenv )->GetObjectArrayElement( jenv, $input, i );
2003         const char * c_string = (const char *) ( *jenv )->GetStringUTFChars( jenv, j_string, 0 );
2004         $1[i] = malloc( ( strlen( c_string ) + 1 ) * sizeof ( const char * ) );
2005         strcpy( $1[i], c_string );
2006         ( *jenv )->ReleaseStringUTFChars( jenv, j_string, c_string );
2007         ( *jenv )->DeleteLocalRef( jenv, j_string );
2008     }
2009 }
2010 
2011 // This cleans up the memory we malloc'd before the function call
2012 %typemap ( freearg ) ( const char *legline[4] )
2013 {
2014     int i;
2015     for ( i = 0; i < 4; i++ )
2016         free( $1[i] );
2017     free( $1 );
2018 }
2019 
2020 %typemap ( in ) ( const char **ArrayCk )
2021 {
2022     int i = 0;
2023     if ( $input != NULL )
2024     {
2025         int size = ( *jenv )->GetArrayLength( jenv, $input );
2026         if ( size != Alen )
2027         {
2028             printf( "Arrays must be the same length\n" );
2029             return;
2030         }
2031         $1 = (char **) malloc( (size_t) Alen * sizeof ( char * ) );
2032         // make a copy of each string
2033         for ( i = 0; i < Alen; i++ )
2034         {
2035             jstring    j_string   = (jstring) ( *jenv )->GetObjectArrayElement( jenv, $input, i );
2036             const char * c_string = (const char *) ( *jenv )->GetStringUTFChars( jenv, j_string, 0 );
2037             $1[i] = malloc( ( strlen( c_string ) + 1 ) * sizeof ( const char * ) );
2038             strcpy( $1[i], c_string );
2039             ( *jenv )->ReleaseStringUTFChars( jenv, j_string, c_string );
2040             ( *jenv )->DeleteLocalRef( jenv, j_string );
2041         }
2042     }
2043     else
2044     {
2045         $1 = NULL;
2046     }
2047 }
2048 
2049 // This cleans up the memory we malloc'd before the function call
2050 %typemap ( freearg ) ( const char **ArrayCk )
2051 {
2052     int i;
2053     if ( $1 != NULL )
2054     {
2055         for ( i = 0; i < Alen; i++ )
2056             free( $1[i] );
2057         free( $1 );
2058     }
2059 }
2060 %typemap ( jni ) ( const char **ArrayCk ) "jobjectArray"
2061 %typemap ( jtype ) ( const char **ArrayCk ) "String[]"
2062 %typemap ( jstype ) ( const char **ArrayCk ) "String[]"
2063 %typemap ( javain ) ( const char **ArrayCk ) "$javainput"
2064 %typemap ( javaout ) ( const char **ArrayCk )
2065 {
2066     return $jnicall;
2067 }
2068 
2069 %typemap ( in ) ( PLINT n, const char **Array )
2070 {
2071     int i = 0;
2072     if ( $input != NULL )
2073     {
2074         int size = ( *jenv )->GetArrayLength( jenv, $input );
2075         Alen = size;
2076         $1   = size;
2077         $2   = (char **) malloc( (size_t) Alen * sizeof ( char * ) );
2078         // make a copy of each string
2079         for ( i = 0; i < Alen; i++ )
2080         {
2081             jstring    j_string   = (jstring) ( *jenv )->GetObjectArrayElement( jenv, $input, i );
2082             const char * c_string = (const char *) ( *jenv )->GetStringUTFChars( jenv, j_string, 0 );
2083             $2[i] = malloc( ( strlen( c_string ) + 1 ) * sizeof ( const char * ) );
2084             strcpy( $2[i], c_string );
2085             ( *jenv )->ReleaseStringUTFChars( jenv, j_string, c_string );
2086             ( *jenv )->DeleteLocalRef( jenv, j_string );
2087         }
2088     }
2089     else
2090     {
2091         $1 = 0;
2092         $2 = NULL;
2093     }
2094 }
2095 
2096 // This cleans up the memory we malloc'd before the function call
2097 %typemap ( freearg ) ( PLINT n, const char **Array )
2098 {
2099     int i;
2100     if ( $2 != NULL )
2101     {
2102         for ( i = 0; i < Alen; i++ )
2103             free( $2[i] );
2104         free( $2 );
2105     }
2106 }
2107 %typemap ( jni ) ( PLINT n, const char **Array ) "jobjectArray"
2108 %typemap ( jtype ) ( PLINT n, const char **Array ) "String[]"
2109 %typemap ( jstype ) ( PLINT n, const char **Array ) "String[]"
2110 %typemap ( javain ) ( PLINT n, const char **Array ) "$javainput"
2111 %typemap ( javaout ) ( PLINT n, const char **Array )
2112 {
2113     return $jnicall;
2114 }
2115 
2116 #if 0
2117 %typemap( in ) PLGraphicsIn * gin( PLGraphicsIn tmp )
2118 {
2119     if ( !PySequence_Check( $input ) || PySequence_Size( $input ) != 2 )
2120     {
2121         PyErr_SetString( PyExc_ValueError, "Expecting a sequence of 2 numbers." );
2122         return NULL;
2123     }
2124     $1     = &tmp;
2125     $1->dX = PyFloat_AsDouble( PySequence_Fast_GET_ITEM( $input, 0 ) );
2126     $1->dY = PyFloat_AsDouble( PySequence_Fast_GET_ITEM( $input, 1 ) );
2127 }
2128 %typemap( argout ) PLGraphicsIn * gin {
2129     PyObject *o;
2130     o         = PyFloat_FromDouble( $1->wX );
2131     resultobj = t_output_helper( resultobj, o );
2132     o         = PyFloat_FromDouble( $1->wY );
2133     resultobj = t_output_helper( resultobj, o );
2134 }
2135 #endif
2136 
2137 // swig compatible PLplot API definitions from here on.
2138 %include plplotcapi.i
2139