1 /*
2
3 AST.xs
4
5 Copyright (C) 2004-2005 Tim Jenness. All Rights Reserved.
6
7 This program is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free Software
9 Foundation; either version 2 of the License, or (at your option) any later
10 version.
11
12 This program is distributed in the hope that it will be useful,but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
14 PARTICULAR PURPOSE. See the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License along with
17 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 Place,Suite 330, Boston, MA 02111-1307, USA
19
20 */
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 #include "EXTERN.h" /* std perl include */
26 #include "perl.h" /* std perl include */
27 #include "XSUB.h" /* XSUB include */
28 #include "ppport.h"
29 #ifdef __cplusplus
30 }
31 #endif
32
33 /* for some reason ppport.h does not currently have CopFILE defined */
34 #ifndef CopFILE
35 #define CopFILE(s) "<unknown>"
36 #endif
37 #ifndef CopLINE
38 #define CopLINE(s) -1
39 #endif
40
41 /* typedef some common types so that the typemap can bless constants
42 into correct namespaces */
43
44 #include <limits.h>
45
46 typedef int StatusType;
47 typedef int WcsMapType;
48
49 #include "ast.h"
50 #include "grf.h"
51
52 /* Older versions of AST can require Fortran, so we add dummy main
53 needed by, eg, g95 */
54 #if ( AST_MAJOR_VERS < 4 )
MAIN_()55 void MAIN_ () {}
MAIN__()56 void MAIN__ () {}
57 #endif
58
59
60 /* The following definitions are required for backwards compatible
61 Since AST version 2 does not have these.
62 */
63
64 #if ( AST_MAJOR_VERS >= 2 )
65 # define HASSPECFRAME
66 # define HASSPECMAP
67 # define HASSPECADD
68 # define HASSETREFPOS
69 # define HASGETREFPOS
70 # define HASGETACTIVEUNIT
71 # define HASSETACTIVEUNIT
72 #else
73 typedef void AstSpecFrame;
74 typedef void AstSpecMap;
75 #endif
76
77 #if ( AST_MAJOR_VERS >= 3 )
78 #define HASPOLYMAP
79 #define HASGRISMMAP
80 #define HASSHIFTMAP
81 #define HASRATE
82 #else
83 typedef void AstPolyMap;
84 typedef void AstGrismMap;
85 typedef void AstShiftMap;
86 #endif
87
88 #if ( (AST_MAJOR_VERS == 3 && AST_MINOR_VERS >= 1) || AST_MAJOR_VERS >= 4 )
89 #define HASXMLCHAN
90 #else
91 typedef void AstXmlChan;
92 #endif
93
94 #if ( (AST_MAJOR_VERS == 5 && AST_MINOR_VERS >= 2) || AST_MAJOR_VERS >= 6 )
95 #define HASSTCSCHAN
96 #else
97 typedef void AstStcsChan;
98 #endif
99
100 #if ( (AST_MAJOR_VERS == 3 && AST_MINOR_VERS >= 2) || AST_MAJOR_VERS >= 4 )
101 #define HASTRANMAP
102 #define HASPUTCARDS
103 #define HASESCAPES
104 #else
105 typedef void AstTranMap;
106 #endif
107
108 #if ( (AST_MAJOR_VERS == 3 && AST_MINOR_VERS >= 4) || AST_MAJOR_VERS >= 4 )
109 #define HASDSBSPECFRAME
110 #else
111 typedef void AstDSBSpecFrame;
112 #endif
113
114 #if ( (AST_MAJOR_VERS == 3 && AST_MINOR_VERS >= 5) || AST_MAJOR_VERS >= 4 )
115 #define HASLINEARAPPROX
116 #define HASSETFITS
117 #define HASRATEMAP
118 #define HASKEYMAP
119 #define HASFLUXFRAME
120 #define HASSPECFLUXFRAME
121 #define HASREGION
122 #else
123 typedef void AstRateMap;
124 typedef void AstKeyMap;
125 typedef void AstFluxFrame;
126 typedef void AstSpecFluxFrame;
127 typedef void AstRegion;
128 typedef void AstBox;
129 typedef void AstCircle;
130 typedef void AstEllipse;
131 typedef void AstNullRegion;
132 typedef void AstPolygon;
133 typedef void AstInterval;
134 typedef void CmpRegion;
135 #endif
136
137 #if ( (AST_MAJOR_VERS == 3 && AST_MINOR_VERS >= 7) || AST_MAJOR_VERS >= 4 )
138 #define HASTIMEFRAME
139 #define HASTIMEMAP
140 #else
141 typedef void AstTimeFrame;
142 typedef void AstTimeMap;
143 #endif
144
145 /* between v3.0 and v3.4 astRate returned the second derivative */
146 #if ( AST_MAJOR_VERS == 3 && AST_MINOR_VERS < 5 )
147 #define RATE_HAS_SECOND_DERIVATIVE 1
148 #endif
149
150 #if ( (AST_MAJOR_VERS == 4 && AST_MINOR_VERS >= 1) || AST_MAJOR_VERS >= 5 )
151 #define HASMAPSPLIT
152 #else
153 #endif
154
155 #if ( (AST_MAJOR_VERS == 5 && AST_MINOR_VERS >= 3) || AST_MAJOR_VERS >= 6 )
156 #define HASMAPPUTU
157 #define HASHASATTRIBUTE
158 #else
159 #endif
160
161 #if ( (AST_MAJOR_VERS == 5 && AST_MINOR_VERS >= 4) || AST_MAJOR_VERS >= 6 )
162 #define HASKEYMAPSHORT
163 #else
164 #endif
165
166 #if ( (AST_MAJOR_VERS == 7 && AST_MINOR_VERS >= 2) || AST_MAJOR_VERS >= 8 )
167 #define HASMAPDEFINED
168 #else
169 #endif
170
171
172 /* Helper functions */
173 #include "arrays.h"
174 #include "astTypemap.h"
175
pack1Dchar(AV * avref)176 static char ** pack1Dchar( AV * avref ) {
177 int i;
178 SV ** elem;
179 char ** outarr;
180 int len;
181 STRLEN linelen;
182
183 /* number of elements */
184 len = av_len( avref ) + 1;
185 /* Temporary storage */
186 outarr = get_mortalspace( len,'v');
187
188 for (i=0; i<len; i++) {
189 elem = av_fetch( avref, i, 0);
190 if (elem == NULL ) {
191 /* undef */
192 } else {
193 outarr[i] = SvPV( *elem, linelen);
194 }
195 }
196 return outarr;
197 }
198
pack1DAstObj(AV * avref)199 static AstObject ** pack1DAstObj( AV * avref ) {
200 int i;
201 SV ** elem;
202 AstObject ** outarr;
203 int len;
204
205 /* number of elements */
206 len = av_len( avref ) + 1;
207 /* Temporary storage - array of pointers */
208 outarr = get_mortalspace( len,'v');
209
210 for (i=0; i<len; i++) {
211 elem = av_fetch( avref, i, 0);
212 if (elem == NULL ) {
213 /* undef */
214 } else {
215 /* Now need to convert this SV** to an AstObject */
216 if (sv_derived_from(*elem, "Starlink::AST")) {
217 IV tmpiv = extractAstIntPointer( *elem );
218 outarr[i] = INT2PTR(AstObject *,tmpiv);
219 } else {
220 Perl_croak( aTHX_ "Array contains non-Starlink::AST variables");
221 }
222 }
223 }
224 return outarr;
225 }
226
227 /* This routine should throw an exception of a different
228 class depending on the value of the AST status. For
229 now we croak with the error message.
230
231 We deliberately try to stay in C here rather than
232 add to the complexity by calling out into perl.
233 */
234
astThrowException(int status,AV * errorstack)235 static void astThrowException ( int status, AV* errorstack ) {
236 size_t i;
237 size_t nelem;
238
239 SV * errsv = sv_2mortal( newSVpvn("", 0) );
240
241 nelem = av_len( errorstack );
242 for (i = 0; i <= nelem; i++ ) {
243 SV ** elem = av_fetch( errorstack, i, 0);
244 if (elem != NULL ) {
245 sv_catpv( errsv, "- ");
246 sv_catsv( errsv, (SV*)*elem);
247 if (i != nelem) sv_catpv( errsv, "\n");
248 }
249 }
250 Perl_croak( aTHX_ "%s", SvPV_nolen( errsv ) );
251 }
252
253 /* Callbacks */
254
255 /* sourceWrap is called by the fitschan constructor immediately and not
256 by the Read method. This means that there are no worries about
257 reference counting or keeping copies of the function around.
258 */
259
sourceWrap(const char * (* source)(),int * status)260 static char *sourceWrap( const char *(*source)(), int *status ) {
261 dSP;
262 SV * cb;
263 SV * myobject;
264 SV * retsv;
265 int count;
266 STRLEN len;
267 char * line;
268 char * retval = NULL;
269
270 /* Return directly if ast status is set. */
271 if ( !astOK ) return NULL;
272 if ( source == NULL ) {
273 astError( AST__INTER, "source function called without Perl callback");
274 return NULL;
275 }
276
277 /* Need to cast the source argument to a SV* and extract the callback from the object */
278 myobject = (SV*) source;
279 cb = getPerlObjectAttr( myobject, "_source" );
280 if (cb == NULL) {
281 astError( AST__INTER, "Callback in channel 'source' not defined!");
282 return NULL;
283 }
284 cb = SvRV( cb );
285
286 /* call the callback with the supplied line */
287 ENTER;
288 SAVETMPS;
289
290 PUSHMARK(sp);
291 PUTBACK;
292
293 count = call_sv( cb, G_NOARGS | G_SCALAR | G_EVAL );
294
295 ReportPerlError( AST__INTER );
296
297 SPAGAIN ;
298
299 if (astOK) {
300 if (count != 1) {
301 astError( AST__INTER, "Returned more than one arg from channel source");
302 } else {
303 retsv = POPs;
304
305 if (SvOK(retsv)) {
306 line = SvPV(retsv, len);
307
308 /* The sourceWrap function must return the line in memory
309 allocated using the AST memory allocator */
310 retval = astMalloc( len + 1 );
311 if ( retval != NULL ) {
312 strcpy( retval, line );
313 }
314 } else {
315 retval = NULL;
316 }
317 }
318 }
319
320 PUTBACK;
321 FREETMPS;
322 LEAVE;
323
324 return retval;
325 }
326
sinkWrap(void (* sink)(const char *),const char * line,int * status)327 static void sinkWrap( void (*sink)(const char *), const char *line, int *status ) {
328 dSP;
329 SV * cb;
330 SV * myobject;
331
332 /* Return directly if ast status is set. */
333 if ( !astOK ) return;
334
335 /* Need to cast the sink argument to a SV* */
336 myobject = (SV*) sink;
337
338 cb = getPerlObjectAttr( myobject, "_sink" );
339
340 if (cb == NULL) {
341 astError( AST__INTER, "Callback in channel 'sink' not defined!");
342 return;
343 }
344
345
346 /* call the callback with the supplied line */
347 ENTER;
348 SAVETMPS;
349
350 PUSHMARK(sp);
351 XPUSHs( sv_2mortal( newSVpv( (char*)line, strlen(line) )));
352 PUTBACK;
353
354 call_sv( SvRV(cb), G_DISCARD | G_VOID | G_EVAL );
355
356 ReportPerlError( AST__INTER );
357
358 FREETMPS;
359 LEAVE;
360
361 }
362
363
364 /* Need to allocate a mutex to prevent threads accessing
365 the AST simultaneously. May need to protect this from
366 non-threaded perl */
367
368 #ifdef USE_ITHREADS
369 static perl_mutex AST_mutex;
370 #endif
371
372 /* An array to store the messages coming from the error system */
373 AV* ErrBuff;
374
375 /* We need to make sure that ast routines are called in a thread-safe
376 manner since the underlying AST library is not thread-safe because
377 of the error system. Use Mark's JNIAST technique */
378
379 #define ASTCALL(code) \
380 STMT_START { \
381 int my_xsstatus_val = 0; \
382 int *my_xsstatus = &my_xsstatus_val; \
383 int *old_ast_status; \
384 AV* local_err; \
385 MUTEX_LOCK(&AST_mutex); \
386 My_astClearErrMsg(); \
387 old_ast_status = astWatch( my_xsstatus ); \
388 code \
389 astWatch( old_ast_status ); \
390 /* Need to remove the MUTEX before we croak [but must copy the error buffer] */ \
391 My_astCopyErrMsg( &local_err, *my_xsstatus ); \
392 MUTEX_UNLOCK(&AST_mutex); \
393 if ( *my_xsstatus != 0 ) { \
394 astThrowException( *my_xsstatus, local_err ); \
395 } \
396 } STMT_END;
397
398
399 /* When we call plot routines, we need to register the plot object
400 in a global variable so that the plotting infrastructure can get
401 at the callbacks */
402
403 #define PLOTCALL(grfobject,code) \
404 ASTCALL( \
405 Perl_storeGrfObject( grfobject ); \
406 code \
407 Perl_clearGrfObject(); \
408 )
409
410 /* This is the error handler.
411 Store error messages in an array. Need to worry about thread-local storage
412 very soon.
413
414 This symbol must be available to the AST routines as we are deliberately
415 replacing the AST error handler.
416 */
417
astPutErr_(int status,const char * message)418 void astPutErr_ ( int status, const char * message ) {
419 /* the av_clear decrements the refcnt of the SV entries */
420 av_push(ErrBuff, newSVpv((char*)message, 0) );
421 }
422
My_astClearErrMsg()423 static void My_astClearErrMsg () {
424 av_clear( ErrBuff );
425 }
426
427 /* routine to copy the error messages from the global array to a private
428 array so that we can release the Mutex before the exception is thrown.
429 Creates a new mortal AV and populates it.
430
431 This is required because astPutErr can only use the static version
432 of the array.
433
434 Does not try to do anything if status is 0
435 */
436
My_astCopyErrMsg(AV ** newbuff,int status)437 static void My_astCopyErrMsg ( AV ** newbuff, int status ) {
438 size_t i;
439 size_t nelem;
440 if (status == 0) return;
441
442 *newbuff = newAV();
443 sv_2mortal((SV*)*newbuff);
444 nelem = av_len( ErrBuff );
445 for (i = 0; i <= nelem ; i++ ) {
446 SV ** elem = av_fetch( ErrBuff, i, 0);
447 if (elem != NULL ) {
448 SvREFCNT_inc( *elem ); /* Storing it in a new place so inc reference count */
449 av_push( *newbuff, *elem);
450 }
451 }
452
453 /* And we no longer need the error array contents */
454 My_astClearErrMsg();
455
456 }
457
458 /* Since you can not put CPP code within CPP code inside XS we need
459 to provide a special wrapper routine for astRate */
myAstRate(AstMapping * this,double * cat,int ax1,int ax2,double * d2)460 static void myAstRate ( AstMapping * this, double * cat, int ax1, int ax2,
461 double * d2) {
462 double RETVAL;
463 dXSARGS;
464
465 #if RATE_HAS_SECOND_DERIVATIVE
466 ASTCALL(
467 RETVAL = astRate( this, cat, ax1, ax2, d2 );
468 )
469 #else
470 ASTCALL(
471 RETVAL = astRate( this, cat, ax1, ax2 );
472 )
473 #endif
474 if ( RETVAL != AST__BAD ) {
475 XPUSHs(sv_2mortal(newSVnv(RETVAL)));
476 #ifdef RATE_HAS_SECOND_DERIVATIVE
477 XPUSHs(sv_2mortal(newSVnv(*d2)));
478 #endif
479 } else {
480 XSRETURN_EMPTY;
481 }
482 }
483
484
485 MODULE = Starlink::AST PACKAGE = Starlink::AST
486
487 PROTOTYPES: DISABLE
488
489 BOOT:
490 MUTEX_INIT(&AST_mutex);
491 ErrBuff = newAV();
492
493 double
494 AST__BAD()
495 CODE:
496 #ifdef AST__BAD
497 RETVAL = AST__BAD;
498 #else
499 Perl_croak(aTHX_ "Constant AST__BAD not defined\n");
500 #endif
501 OUTPUT:
502 RETVAL
503
504 int
505 AST__CURRENT()
506 CODE:
507 #ifdef AST__CURRENT
508 RETVAL = AST__CURRENT;
509 #else
510 Perl_croak(aTHX_ "Constant AST__CURRENT not defined\n");
511 #endif
512 OUTPUT:
513 RETVAL
514
515 int
516 AST__NOFRAME()
517 CODE:
518 #ifdef AST__NOFRAME
519 RETVAL = AST__NOFRAME;
520 #else
521 Perl_croak(aTHX_ "Constant AST__NOFRAME not defined\n");
522 #endif
523 OUTPUT:
524 RETVAL
525
526 int
527 AST__BASE()
528 CODE:
529 #ifdef AST__BASE
530 RETVAL = AST__BASE;
531 #else
532 Perl_croak(aTHX_ "Constant AST__BASE not defined\n");
533 #endif
534 OUTPUT:
535 RETVAL
536
537 int
538 AST__ALLFRAMES()
539 CODE:
540 #ifdef AST__ALLFRAMES
541 RETVAL = AST__ALLFRAMES;
542 #else
543 Perl_croak(aTHX_ "Constant AST__ALLFRAMES not defined\n");
544 #endif
545 OUTPUT:
546 RETVAL
547
548 MODULE = Starlink::AST PACKAGE = Starlink::AST PREFIX = ast
549
550
551 void
552 astBegin()
553 CODE:
554 ASTCALL(
555 astBegin;
556 )
557
558
559 void
560 astEnd()
561 CODE:
562 ASTCALL(
563 astEnd;
564 )
565
566 bool
567 astEscapes( new_value )
568 bool new_value
569 CODE:
570 #ifndef HASESCAPES
571 Perl_croak(aTHX_ "astEscapes: Please upgrade to AST V3.2 or greater");
572 #else
573 RETVAL = astEscapes( new_value );
574 #endif
575 OUTPUT:
576 RETVAL
577
578 # Can be called as class method or function
579
580 int
581 astVersion( ... )
582 CODE:
583 #if ( AST_MAJOR_VERS >= 2 )
584 ASTCALL(
585 RETVAL = astVersion;
586 )
587 #else
588 Perl_croak(aTHX_ "astVersion: Please upgrade to AST V2.x or greater");
589 #endif
590 OUTPUT:
591 RETVAL
592
593 void
594 astIntraReg()
595 CODE:
596 Perl_croak(aTHX_ "astIntraReg Not yet implemented\n");
597
598 # The following functions are associated with AST internal status
599 # They can only be called from within an AST callback (eg the
600 # graphics system since they do not MUTEX and they do not switch
601 # the internal status variable.
602
603 # Note the use of _ in name
604
605 # No need to make this private but we need to make sure
606 # this is called from within a mutex (so a callback is okay)
607 # Call is as _OK. but without changing the current status integer
608
609 bool
610 ast_OK()
611 CODE:
612 RETVAL = astOK;
613 OUTPUT:
614 RETVAL
615
616 # Called only from within AST callbacks. No MUTEX locking.
617
618 void
619 ast_Error( status, message)
620 StatusType status
621 char * message
622 CODE:
623 astError( status, "%s", message);
624
625
626 # Call only from within an AST callback
627
628 void
629 ast_ClearStatus()
630 CODE:
631 astClearStatus;
632
633 void
634 ast_SetStatus( status )
635 StatusType status
636 CODE:
637 astSetStatus( status );
638
639 StatusType
640 ast_Status()
641 CODE:
642 RETVAL = astStatus;
643 OUTPUT:
644 RETVAL
645
646 MODULE = Starlink::AST PACKAGE = Starlink::AST::Status
647
648 # Translate status values
649 int
650 value( this )
651 StatusType this
652 CODE:
653 RETVAL = this;
654 OUTPUT:
655 RETVAL
656
657 MODULE = Starlink::AST PACKAGE = Starlink::AST::Frame
658
659 AstFrame *
660 new( class, naxes, options )
661 char * class
662 int naxes
663 char * options
664 CODE:
665 ASTCALL(
666 RETVAL = astFrame( naxes, options );
667 )
668 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
669 OUTPUT:
670 RETVAL
671
672 MODULE = Starlink::AST PACKAGE = Starlink::AST::FrameSet
673
674 AstFrameSet *
675 new( class, frame, options )
676 char * class
677 AstFrame * frame
678 char * options
679 CODE:
680 ASTCALL(
681 RETVAL = astFrameSet( frame, options );
682 )
683 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
684 OUTPUT:
685 RETVAL
686
687 MODULE = Starlink::AST PACKAGE = Starlink::AST::CmpFrame
688
689 AstCmpFrame *
690 new( class, frame1, frame2, options )
691 char * class
692 AstFrame * frame1
693 AstFrame * frame2
694 char * options
695 CODE:
696 ASTCALL(
697 RETVAL = astCmpFrame( frame1, frame2, options );
698 )
699 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
700 OUTPUT:
701 RETVAL
702
703 MODULE = Starlink::AST PACKAGE = Starlink::AST::FluxFrame
704
705 AstFluxFrame *
706 new( class, specval, specfrm, options )
707 char * class
708 double specval
709 AstSpecFrame * specfrm
710 char * options
711 CODE:
712 #ifndef HASKEYMAP
713 Perl_croak(aTHX_ "astFluxFrame: Please upgrade to AST V3.5 or newer");
714 #else
715 ASTCALL(
716 RETVAL = astFluxFrame( specval, specfrm, options );
717 )
718 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
719 #endif
720 OUTPUT:
721 RETVAL
722
723 MODULE = Starlink::AST PACKAGE = Starlink::AST::SpecFluxFrame
724
725 AstSpecFluxFrame *
726 new( class, frame1, frame2, options )
727 char * class
728 AstSpecFrame * frame1
729 AstFluxFrame * frame2
730 char * options
731 CODE:
732 #ifndef HASSPECFLUXFRAME
733 Perl_croak(aTHX_ "astSpecFluxFrame: Please upgrade to AST V3.5 or newer");
734 #else
735 ASTCALL(
736 RETVAL = astSpecFluxFrame( frame1, frame2, options );
737 )
738 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
739 #endif
740 OUTPUT:
741 RETVAL
742
743 MODULE = Starlink::AST PACKAGE = Starlink::AST::CmpMap
744
745 AstCmpMap *
746 new( class, map1, map2, series, options )
747 char * class
748 AstMapping * map1
749 AstMapping * map2
750 int series
751 char * options
752 CODE:
753 ASTCALL(
754 RETVAL = astCmpMap( map1, map2, series, options );
755 )
756 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
757 OUTPUT:
758 RETVAL
759
760 MODULE = Starlink::AST PACKAGE = Starlink::AST::Channel
761
762 # Need to add proper support for the callbacks. Currently rely on the
763 # returned object to keep a reference to the callback.
764
765 # Note that we use inheritance here so we have to switch on the basis
766 # of the supplied class. Things will get difficult if people start
767 # adding their own subclasses since I am only looking at substring
768 # matches.
769
770 SV *
771 _new( class, sourcefunc, sinkfunc, options )
772 char * class
773 SV * sourcefunc
774 SV * sinkfunc
775 char * options;
776 PREINIT:
777 SV ** value;
778 SV * sink = NULL;
779 SV * source = NULL;
780 AstChannel * channel;
781 AstFitsChan * fitschan;
782 AstXmlChan * xmlchan;
783 AstStcsChan * stcschan;
784 bool has_source = 0;
785 bool has_sink = 0;
786 CODE:
787 /* create the object without a pointer */
788 RETVAL = createPerlObject( class, NULL );
789
790 /* Decide whether to register a callback with the sink/source.
791 Do this rather than always registering callback for efficiency reasons
792 and because I am not sure if the presence of a callback affects the
793 behaviour of the channel. */
794
795 /* First see whether we were given valid callbacks */
796 if (SvOK(sourcefunc) && SvROK(sourcefunc) &&
797 SvTYPE(SvRV(sourcefunc)) == SVt_PVCV) has_source = 1;
798 if (SvOK(sinkfunc) && SvROK(sinkfunc) &&
799 SvTYPE(SvRV(sinkfunc)) == SVt_PVCV) has_sink = 1;
800
801 if ( has_source || has_sink) {
802 /* Take a reference to the object but do not increment the REFCNT. We
803 Want this to be freed when the perl object disappears. */
804 /* only take one reference */
805
806 /* For sink functions we have to keep them around in the object
807 since they are called when the object is annulled. */
808 SV * rv = newRV_noinc( SvRV( RETVAL ));
809 if (has_sink) {
810 /* Store reference to object */
811 sink = rv;
812 /* and store the actual sink callback in the object */
813 setPerlObjectAttr( RETVAL, "_sink", newRV_inc( SvRV(sinkfunc) ));
814 }
815
816 /* In some cases the source routine is called after this constructor
817 returns. We therefore need to store the source function in the object
818 as well. */
819 if (has_source) {
820 /* Store reference to object */
821 source = rv;
822 /* and store the actual sink callback in the object */
823 setPerlObjectAttr( RETVAL, "_source", newRV_inc( SvRV(sourcefunc) ));
824 }
825
826 }
827
828 /* Need to use astChannelFor style interface so that we can register
829 a fixed callback and a reference to a CV */
830 if ( strstr( class, "Channel") != NULL) {
831 ASTCALL(
832 channel = astChannelFor( (const char *(*)()) source, sourceWrap,
833 (void (*)( const char * )) sink, sinkWrap, options );
834 )
835 if (astOK) setPerlAstObject( RETVAL, (AstObject*)channel );
836 } else if (strstr( class, "FitsChan") != NULL) {
837 ASTCALL(
838 fitschan = astFitsChanFor( (const char *(*)()) source, sourceWrap,
839 (void (*)( const char * )) sink, sinkWrap, options );
840 )
841 if (astOK) setPerlAstObject( RETVAL, (AstObject*)fitschan );
842 } else if (strstr( class, "XmlChan") != NULL ) {
843 #ifndef HASXMLCHAN
844 Perl_croak(aTHX_ "XmlChan: Please upgrade to AST V3.1 or greater");
845 #else
846 ASTCALL(
847 xmlchan = astXmlChanFor( (const char *(*)()) source, sourceWrap,
848 (void (*)( const char * )) sink, sinkWrap, options );
849 )
850 if (astOK) setPerlAstObject( RETVAL, (AstObject*)xmlchan );
851 #endif
852 } else if (strstr( class, "StcsChan") != NULL ) {
853 #ifndef HASSTCSCHAN
854 Perl_croak(aTHX_ "StcsChan: Please upgrade to AST V5.2 or greater");
855 #else
856 ASTCALL(
857 stcschan = astStcsChanFor( (const char *(*)()) source, sourceWrap,
858 (void (*)( const char * )) sink, sinkWrap, options );
859 )
860 if (astOK) setPerlAstObject( RETVAL, (AstObject*)stcschan );
861 #endif
862 } else {
863 Perl_croak(aTHX_ "Channel of class %s not recognized.", class );
864 }
865 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
866 OUTPUT:
867 RETVAL
868
869
870 MODULE = Starlink::AST PACKAGE = Starlink::AST::GrismMap
871
872 AstGrismMap *
873 new( class, options )
874 char * class
875 char * options
876 CODE:
877 #ifndef HASGRISMMAP
878 Perl_croak(aTHX_ "GrismMap: Please upgrade to AST V3.x or greater");
879 #else
880 ASTCALL(
881 RETVAL = astGrismMap( options );
882 )
883 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
884 #endif
885 OUTPUT:
886 RETVAL
887
888 MODULE = Starlink::AST PACKAGE = Starlink::AST::IntraMap
889
890 AstIntraMap *
891 new( class, name, nin, nout, options )
892 char * class
893 char * name
894 int nin
895 int nout
896 char * options
897 CODE:
898 ASTCALL(
899 RETVAL = astIntraMap( name, nin, nout, options );
900 )
901 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
902 OUTPUT:
903 RETVAL
904
905 MODULE = Starlink::AST PACKAGE = Starlink::AST::LutMap
906
907 AstLutMap *
908 new( class, lut, start, inc, options )
909 char * class
910 AV* lut
911 double start
912 double inc
913 char * options
914 PREINIT:
915 int nlut;
916 double * clut;
917 CODE:
918 nlut = av_len( lut ) + 1;
919 clut = pack1D( newRV_noinc((SV*)lut), 'd' );
920 ASTCALL(
921 RETVAL = astLutMap( nlut, clut, start, inc, options );
922 )
923 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
924 OUTPUT:
925 RETVAL
926
927 MODULE = Starlink::AST PACKAGE = Starlink::AST::MathMap
928
929 AstMathMap *
930 new( class, nin, nout, fwd, inv, options )
931 char * class
932 int nin
933 int nout
934 AV* fwd
935 AV* inv
936 char * options
937 PREINIT:
938 int nfwd;
939 int ninv;
940 SV** elem;
941 int i;
942 char ** cfwd;
943 char ** cinv;
944 CODE:
945 nfwd = av_len( fwd ) + 1;
946 ninv = av_len( inv ) + 1;
947 cfwd = pack1Dchar( fwd );
948 cinv = pack1Dchar( inv );
949 RETVAL = astMathMap( nin, nout, nfwd, (const char **)cfwd,
950 ninv, (const char**)cinv, options );
951 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
952 OUTPUT:
953 RETVAL
954
955 MODULE = Starlink::AST PACKAGE = Starlink::AST::MatrixMap
956
957 # Note that form is derived from the size of matrix
958
959 AstMatrixMap *
new(class,nin,nout,matrix,options)960 new( class, nin, nout, matrix, options )
961 char * class
962 int nin
963 int nout
964 AV* matrix
965 char * options
966 PREINIT:
967 int len;
968 int form;
969 double * cmatrix;
970 CODE:
971 len = av_len( matrix ) + 1;
972 /* determine form from number of elements */
973 if (len == 0) {
974 form = 2;
975 } else if (len == nin || len == nout ) {
976 form = 1;
977 } else if ( len == (nin * nout ) ) {
978 form = 0;
979 } else {
980 Perl_croak(aTHX_ "MatrixMap: matrix len not consistent with nout/nin");
981 }
982 cmatrix = pack1D(newRV_noinc((SV*)matrix), 'd');
983 ASTCALL(
984 RETVAL = astMatrixMap( nin, nout, form, cmatrix, options );
985 )
986 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
987 OUTPUT:
988 RETVAL
989
990 MODULE = Starlink::AST PACKAGE = Starlink::AST::Plot
991
992 AstPlot *
993 _new( class, frame, graphbox, basebox, options )
994 char * class
995 AstFrame * frame
996 AV* graphbox
997 AV* basebox
998 char * options
999 PREINIT:
1000 int len;
1001 float * cgraphbox;
1002 double * cbasebox;
1003 CODE:
1004 len = av_len( graphbox ) + 1;
1005 if ( len != 4 ) Perl_croak(aTHX_ "GraphBox must contain 4 values" );
1006 len = av_len( basebox ) + 1;
1007 if ( len != 4 ) Perl_croak(aTHX_ "BaseBox must contain 4 values" );
1008 cbasebox = pack1D( newRV_noinc((SV*)basebox), 'd');
1009 cgraphbox = pack1D( newRV_noinc((SV*)graphbox), 'f');
1010 ASTCALL(
1011 RETVAL = astPlot( frame, cgraphbox, cbasebox, options );
1012 )
1013 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1014 OUTPUT:
1015 RETVAL
1016
1017 MODULE = Starlink::AST PACKAGE = Starlink::AST::PcdMap
1018
1019 AstPcdMap *
new(class,disco,pcdcen,options)1020 new( class, disco, pcdcen, options )
1021 char * class
1022 double disco
1023 AV* pcdcen
1024 char * options
1025 PREINIT:
1026 int len;
1027 double * cpcdcen;
1028 CODE:
1029 len = av_len( pcdcen ) + 1;
1030 if (len != 2 ) {
1031 Perl_croak(aTHX_ "Must supply two values to PcdCen");
1032 }
1033 cpcdcen = pack1D(newRV_noinc((SV*)pcdcen), 'd');
1034 ASTCALL(
1035 RETVAL = astPcdMap( disco, cpcdcen, options );
1036 )
1037 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1038 OUTPUT:
1039 RETVAL
1040
1041 MODULE = Starlink::AST PACKAGE = Starlink::AST::PermMap
1042
1043 AstPermMap *
1044 new( class, inperm, outperm, constant, options )
1045 char * class
1046 AV* inperm
1047 AV* outperm
1048 AV* constant
1049 char * options
1050 PREINIT:
1051 int len;
1052 int * coutperm;
1053 int * cinperm;
1054 double * cconstant;
1055 int nin;
1056 int nout;
1057 CODE:
1058 nin = av_len( inperm ) + 1;
1059 if (nin == 0 ) {
1060 /* no values */
1061 cinperm = NULL;
1062 } else {
1063 cinperm = pack1D(newRV_noinc((SV*)inperm), 'i' );
1064 }
1065 nout = av_len( outperm ) + 1;
1066 if (nout == 0 ) {
1067 /* no values */
1068 coutperm = NULL;
1069 } else {
1070 coutperm = pack1D(newRV_noinc((SV*)outperm), 'i' );
1071 }
1072 len = av_len( constant ) + 1;
1073 if (len == 0 ) {
1074 /* no values */
1075 cconstant = NULL;
1076 } else {
1077 cconstant = pack1D(newRV_noinc((SV*)constant), 'd' );
1078 }
1079 ASTCALL(
1080 RETVAL = astPermMap(nin, cinperm, nout, coutperm, cconstant, options );
1081 )
1082 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1083 OUTPUT:
1084 RETVAL
1085
1086 MODULE = Starlink::AST PACKAGE = Starlink::AST::PolyMap
1087
1088 AstPolyMap *
1089 new( class )
1090 CODE:
1091 #ifndef HASPOLYMAP
1092 Perl_croak(aTHX_ "PolyMap: Please upgrade to AST V3.x or greater");
1093 #else
1094 Perl_croak(aTHX_ "PolyMap not yet implemented");
1095 #endif
1096
1097 MODULE = Starlink::AST PACKAGE = Starlink::AST::ShiftMap
1098
1099 AstShiftMap *
1100 new( class, shift, options )
1101 char * class
1102 AV* shift
1103 char * options
1104 PREINIT:
1105 int ncoord;
1106 double * cshift;
1107 CODE:
1108 #ifndef HASSHIFTMAP
1109 Perl_croak(aTHX_ "ShiftMap: Please upgrade to AST V3.x or greater");
1110 #else
1111 ncoord = av_len( shift ) + 1;
1112 cshift = pack1D(newRV_noinc((SV*)shift), 'd');
1113 ASTCALL(
1114 RETVAL = astShiftMap( ncoord, cshift, options);
1115 )
1116 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1117 #endif
1118 OUTPUT:
1119 RETVAL
1120
1121 MODULE = Starlink::AST PACKAGE = Starlink::AST::SkyFrame
1122
1123 AstSkyFrame *
1124 new( class, options )
1125 char * class
1126 char * options
1127 CODE:
1128 ASTCALL(
1129 RETVAL = astSkyFrame( options );
1130 )
1131 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1132 OUTPUT:
1133 RETVAL
1134
1135 MODULE = Starlink::AST PACKAGE = Starlink::AST::SpecFrame
1136
1137 AstSpecFrame *
1138 new( class, options )
1139 char * class
1140 char * options
1141 CODE:
1142 #ifndef HASSPECFRAME
1143 Perl_croak(aTHX_ "SpecFrame: Please upgrade to AST V2.x or greater");
1144 #else
1145 ASTCALL(
1146 RETVAL = astSpecFrame( options );
1147 )
1148 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1149 #endif
1150 OUTPUT:
1151 RETVAL
1152
1153 MODULE = Starlink::AST PACKAGE = Starlink::AST::DSBSpecFrame
1154
1155 AstDSBSpecFrame *
1156 new( class, options )
1157 char * class
1158 char * options
1159 CODE:
1160 #ifndef HASDSBSPECFRAME
1161 Perl_croak(aTHX_ "DSBSpecFrame: Please upgrade to AST V3.4 or greater");
1162 #else
1163 ASTCALL(
1164 RETVAL = astDSBSpecFrame( options );
1165 )
1166 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1167 #endif
1168 OUTPUT:
1169 RETVAL
1170
1171 MODULE = Starlink::AST PACKAGE = Starlink::AST::TimeFrame
1172
1173 AstTimeFrame *
1174 new( class, options )
1175 char * class
1176 char * options
1177 CODE:
1178 #ifndef HASTIMEFRAME
1179 Perl_croak(aTHX_ "TimeFrame: Please upgrade to AST V3.7 or greater");
1180 #else
1181 ASTCALL(
1182 RETVAL = astTimeFrame( options );
1183 )
1184 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1185 #endif
1186 OUTPUT:
1187 RETVAL
1188
1189 MODULE = Starlink::AST PACKAGE = Starlink::AST::SlaMap
1190
1191 AstSlaMap *
1192 new( class, flags, options )
1193 char * class
1194 int flags
1195 char * options
1196 CODE:
1197 ASTCALL(
1198 RETVAL = astSlaMap( flags, options );
1199 )
1200 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1201 OUTPUT:
1202 RETVAL
1203
1204 MODULE = Starlink::AST PACKAGE = Starlink::AST::SphMap
1205
1206 AstSphMap *
1207 new( class, options )
1208 char * class
1209 char * options
1210 CODE:
1211 ASTCALL(
1212 RETVAL = astSphMap( options );
1213 )
1214 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1215 OUTPUT:
1216 RETVAL
1217
1218 MODULE = Starlink::AST PACKAGE = Starlink::AST::SpecMap
1219
1220 AstSpecMap *
1221 new( class, nin, flags, options )
1222 char * class
1223 int nin
1224 int flags
1225 char * options
1226 CODE:
1227 #ifndef HASSPECMAP
1228 Perl_croak(aTHX_ "SpecMap: Please upgrade to AST V2.x or greater");
1229 #else
1230 ASTCALL(
1231 RETVAL = astSpecMap( nin, flags, options );
1232 )
1233 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1234 #endif
1235 OUTPUT:
1236 RETVAL
1237
1238 MODULE = Starlink::AST PACKAGE = Starlink::AST::TimeMap
1239
1240 AstTimeMap *
1241 new( flags, options )
1242 int flags
1243 char * options
1244 CODE:
1245 #ifndef HASTIMEMAP
1246 Perl_croak(aTHX_ "TimeMap: Please upgrade to AST V3.7 or greater");
1247 #else
1248 ASTCALL(
1249 RETVAL = astTimeMap( flags, options );
1250 )
1251 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1252 #endif
1253 OUTPUT:
1254 RETVAL
1255
1256 MODULE = Starlink::AST PACKAGE = Starlink::AST::TranMap
1257
1258 AstTranMap *
1259 new( class, map1, map2, options )
1260 char * class
1261 AstMapping * map1
1262 AstMapping * map2
1263 char * options
1264 CODE:
1265 #ifndef HASTRANMAP
1266 Perl_croak(aTHX_ "TranMap: Please upgrade to AST V3.2 or greater");
1267 #else
1268 ASTCALL(
1269 RETVAL = astTranMap( map1, map2, options );
1270 )
1271 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1272 #endif
1273 OUTPUT:
1274 RETVAL
1275
1276 MODULE = Starlink::AST PACKAGE = Starlink::AST::UnitMap
1277
1278 AstUnitMap *
1279 new( class, ncoord, options )
1280 char * class
1281 int ncoord
1282 char * options
1283 CODE:
1284 ASTCALL(
1285 RETVAL = astUnitMap( ncoord, options );
1286 )
1287 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1288 OUTPUT:
1289 RETVAL
1290
1291 MODULE = Starlink::AST PACKAGE = Starlink::AST::WcsMap
1292
1293 AstWcsMap *
1294 new( class, ncoord, type, lonax, latax, options )
1295 char * class
1296 int ncoord
1297 WcsMapType type
1298 int lonax
1299 int latax
1300 char * options
1301 CODE:
1302 ASTCALL(
1303 RETVAL = astWcsMap( ncoord, type, lonax, latax,options );
1304 )
1305 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1306 OUTPUT:
1307 RETVAL
1308
1309 MODULE = Starlink::AST PACKAGE = Starlink::AST::WinMap
1310
1311 # we derive ncoord from the input array dimensions
1312
1313 AstWinMap *
1314 new( class, ina, inb, outa, outb, options )
1315 char * class
1316 AV* ina
1317 AV* inb
1318 AV* outa
1319 AV* outb
1320 char * options
1321 CODE:
1322 /* minimal arg checking - lazy XXXX */
1323 RETVAL = astWinMap( av_len(ina)+1, pack1D(newRV_noinc((SV*)ina),'d'),
1324 pack1D(newRV_noinc((SV*)inb),'d'),
1325 pack1D(newRV_noinc((SV*)outa),'d'),
1326 pack1D(newRV_noinc((SV*)outb),'d'),options );
1327 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1328 OUTPUT:
1329 RETVAL
1330
1331 MODULE = Starlink::AST PACKAGE = Starlink::AST::ZoomMap
1332
1333 AstZoomMap *
1334 new( class, ncoord, zoom, options )
1335 char * class
1336 int ncoord
1337 double zoom
1338 char * options
1339 CODE:
1340 ASTCALL(
1341 RETVAL = astZoomMap( ncoord, zoom, options );
1342 )
1343 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1344 OUTPUT:
1345 RETVAL
1346
1347
1348 MODULE = Starlink::AST PACKAGE = Starlink::AST PREFIX = ast
1349
1350 void
1351 astClear( this, attrib )
1352 AstObject * this
1353 char * attrib
1354 CODE:
1355 ASTCALL(
1356 astClear( this, attrib );
1357 )
1358
1359 # Store flag in the object when annulled so that the object destructor
1360 # does not cause a second annul.
1361
1362 void
1363 astAnnul( this )
1364 AstObject * this
1365 PREINIT:
1366 SV* arg = ST(0);
1367 CODE:
1368 ASTCALL(
1369 this = astAnnul( this );
1370 )
1371 setPerlObjectAttr( arg, "_annul",newSViv(1));
1372
1373
1374 AstObject *
1375 ast_Clone( this )
1376 AstObject * this
1377 CODE:
1378 ASTCALL(
1379 RETVAL = astClone( this );
1380 )
1381 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1382 OUTPUT:
1383 RETVAL
1384
1385 AstObject *
1386 ast_Copy( this )
1387 AstObject * this
1388 CODE:
1389 ASTCALL(
1390 RETVAL = astCopy( this );
1391 )
1392 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1393 OUTPUT:
1394 RETVAL
1395
1396 # Note that we do not return a NULL object
1397
1398 void
1399 astDelete( this )
1400 AstObject * this
1401 CODE:
1402 ASTCALL(
1403 this = astDelete( this );
1404 )
1405
1406 void
1407 astExempt( this )
1408 AstObject * this
1409 CODE:
1410 ASTCALL(
1411 astExempt( this );
1412 )
1413
1414 void
1415 astExport( this )
1416 AstObject * this
1417 CODE:
1418 ASTCALL(
1419 astExport( this );
1420 )
1421
1422 int
1423 astHasAttribute( this, attrib )
1424 AstObject * this
1425 char * attrib
1426 CODE:
1427 #ifndef HASHASATTRIBUTE
1428 Perl_croak(aTHX_ "astHasAttribute: Please upgrade to AST V5.3 or newer");
1429 #else
1430 ASTCALL(
1431 RETVAL = astHasAttribute( this, attrib );
1432 )
1433 #endif
1434 OUTPUT:
1435 RETVAL
1436
1437 const char *
1438 astGetC( this, attrib )
1439 AstObject * this
1440 char * attrib
1441 PREINIT:
1442 SV * arg = ST(0);
1443 CODE:
1444 if (astIsAPlot(this)) {
1445 PLOTCALL( arg,
1446 RETVAL = astGetC( this, attrib );
1447 )
1448 } else {
1449 ASTCALL(
1450 RETVAL = astGetC( this, attrib );
1451 )
1452 }
1453 OUTPUT:
1454 RETVAL
1455
1456 # Float is just an alias for double
1457
1458 double
1459 astGetD( this, attrib )
1460 AstObject * this
1461 char * attrib
1462 ALIAS:
1463 astGetF = 1
1464 PREINIT:
1465 SV * arg = ST(0);
1466 CODE:
1467 if (astIsAPlot(this)) {
1468 PLOTCALL( arg,
1469 RETVAL = astGetD( this, attrib );
1470 )
1471 } else {
1472 ASTCALL(
1473 RETVAL = astGetD( this, attrib );
1474 )
1475 }
1476 OUTPUT:
1477 RETVAL
1478
1479 int
1480 astGetI( this, attrib )
1481 AstObject * this
1482 char * attrib
1483 ALIAS:
1484 astGetL = 1
1485 PREINIT:
1486 SV * arg = ST(0);
1487 CODE:
1488 if (astIsAPlot(this)) {
1489 PLOTCALL( arg,
1490 RETVAL = astGetI( this, attrib );
1491 )
1492 } else {
1493 ASTCALL(
1494 RETVAL = astGetI( this, attrib );
1495 )
1496 }
1497 OUTPUT:
1498 RETVAL
1499
1500 # Need to decide later whether the astIsA functions need to be
1501 # implemented since Perl can do that - XXXX
1502
1503
1504
1505 # sprintf behaviour is left to the enclosing perl layer
1506
1507 void
1508 ast_Set(this, settings )
1509 AstObject * this
1510 char * settings
1511 CODE:
1512 ASTCALL(
1513 astSet(this, settings );
1514 )
1515
1516 void
1517 astSetC( this, attrib, value )
1518 AstObject * this
1519 char * attrib
1520 char * value
1521 CODE:
1522 ASTCALL(
1523 astSetC( this, attrib, value );
1524 )
1525
1526 # Float is just an alias for double
1527
1528 void
1529 astSetD( this, attrib, value )
1530 AstObject * this
1531 char * attrib
1532 double value
1533 ALIAS:
1534 astSetF = 1
1535 CODE:
1536 ASTCALL(
1537 astSetD( this, attrib, value );
1538 )
1539
1540
1541 void
1542 astSetI( this, attrib, value )
1543 AstObject * this
1544 char * attrib
1545 int value
1546 ALIAS:
1547 astSetL = 1
1548 CODE:
1549 ASTCALL(
1550 astSetI( this, attrib, value );
1551 )
1552
1553 void
1554 astShow( this )
1555 AstObject * this
1556 CODE:
1557 ASTCALL(
1558 astShow( this );
1559 )
1560
1561 bool
1562 astTest( this, attrib )
1563 AstObject * this
1564 char * attrib
1565 CODE:
1566 ASTCALL(
1567 RETVAL = astTest( this, attrib );
1568 )
1569 OUTPUT:
1570 RETVAL
1571
1572 # Use annul as automatic destructor
1573 # For automatic destructor we do not want to throw an exception
1574 # on error. So do not use ASTCALL. Do a manual printf to stderr and continue.
1575 # Does nothing if a key _annul is present in the object and is true.
1576 # This condition is usually met if the user has manually called the Annull
1577 # method on the object.
1578
1579 void
1580 astDESTROY( obj )
1581 SV * obj
1582 PREINIT:
1583 int my_xsstatus_val = 0;
1584 int *my_xsstatus = &my_xsstatus_val;
1585 int *old_ast_status;
1586 int i;
1587 SV ** elem;
1588 SV * flag;
1589 char one[3] = "! ";
1590 char two[3] = "!!";
1591 char * pling;
1592 AV* local_err;
1593 char * s = CopFILE( PL_curcop );
1594 STRLEN msglen;
1595 IV mytmp;
1596 AstObject * this;
1597 CODE:
1598 /* see if we have annulled already */
1599 flag = getPerlObjectAttr( obj, "_annul");
1600 if (flag == NULL || ! SvTRUE(flag) ) {
1601 /* DESTROY always seems to insert stub code for SVREF not what is in */
1602 /* the typemap file. Do it manually */
1603 mytmp = extractAstIntPointer( obj );
1604 this = INT2PTR( AstObject *, mytmp );
1605
1606 MUTEX_LOCK(&AST_mutex);
1607 My_astClearErrMsg();
1608 old_ast_status = astWatch( my_xsstatus );
1609 this = astAnnul( this );
1610 astWatch( old_ast_status );
1611 My_astCopyErrMsg( &local_err, *my_xsstatus );
1612 MUTEX_UNLOCK(&AST_mutex);
1613 if (*my_xsstatus != 0 ) {
1614 for (i=0; i <= av_len( local_err ); i++ ) {
1615 pling = ( i == 0 ? two : one );
1616 elem = av_fetch( local_err, i, 0 );
1617 if (elem != NULL ) {
1618 PerlIO_printf( PerlIO_stderr(), "%s %s\n", pling,
1619 SvPV( *elem, msglen ));
1620 }
1621 }
1622 if (!s) s = "(none)";
1623 PerlIO_printf( PerlIO_stderr(),
1624 "! (in cleanup from file %s:%" IVdf ")\n",
1625 s, (IV) CopLINE(PL_curcop));
1626 }
1627 }
1628
1629 MODULE = Starlink::AST PACKAGE = Starlink::AST::KeyMap
1630
1631 int
1632 AST__BADTYPE()
1633 CODE:
1634 #ifdef AST__BADTYPE
1635 RETVAL = AST__BADTYPE;
1636 #else
1637 Perl_croak(aTHX_ "Constant AST__BADTYPE not defined\n");
1638 #endif
1639 OUTPUT:
1640 RETVAL
1641
1642 int
1643 AST__INTTYPE()
1644 CODE:
1645 #ifdef AST__INTTYPE
1646 RETVAL = AST__INTTYPE;
1647 #else
1648 Perl_croak(aTHX_ "Constant AST__INTTYPE not defined\n");
1649 #endif
1650 OUTPUT:
1651 RETVAL
1652
1653 int
1654 AST__SINTTYPE()
1655 CODE:
1656 #ifdef AST__SINTTYPE
1657 RETVAL = AST__SINTTYPE;
1658 #else
1659 Perl_croak(aTHX_ "Constant AST__SINTTYPE not defined\n");
1660 #endif
1661 OUTPUT:
1662 RETVAL
1663
1664 int
1665 AST__DOUBLETYPE()
1666 CODE:
1667 #ifdef AST__DOUBLETYPE
1668 RETVAL = AST__DOUBLETYPE;
1669 #else
1670 Perl_croak(aTHX_ "Constant AST__DOUBLETYPE not defined\n");
1671 #endif
1672 OUTPUT:
1673 RETVAL
1674
1675 int
1676 AST__FLOATTYPE()
1677 CODE:
1678 #ifdef AST__FLOATTYPE
1679 RETVAL = AST__DOUBLETYPE;
1680 #else
1681 Perl_croak(aTHX_ "Constant AST__FLOATTYPE not defined\n");
1682 #endif
1683 OUTPUT:
1684 RETVAL
1685
1686 int
1687 AST__STRINGTYPE()
1688 CODE:
1689 #ifdef AST__STRINGTYPE
1690 RETVAL = AST__STRINGTYPE;
1691 #else
1692 Perl_croak(aTHX_ "Constant AST__STRINGTYPE not defined\n");
1693 #endif
1694 OUTPUT:
1695 RETVAL
1696
1697 int
1698 AST__OBJECTTYPE()
1699 CODE:
1700 #ifdef AST__OBJECTTYPE
1701 RETVAL = AST__OBJECTTYPE;
1702 #else
1703 Perl_croak(aTHX_ "Constant AST__OBJECTTYPE not defined\n");
1704 #endif
1705 OUTPUT:
1706 RETVAL
1707
1708 int
1709 AST__UNDEFTYPE()
1710 CODE:
1711 #ifdef AST__UNDEFTYPE
1712 RETVAL = AST__UNDEFTYPE;
1713 #else
1714 Perl_croak(aTHX_ "Constant AST__UNDEFTYPE not defined\n");
1715 #endif
1716 OUTPUT:
1717 RETVAL
1718
1719 MODULE = Starlink::AST PACKAGE = Starlink::AST::KeyMap PREFIX = ast
1720
1721 AstKeyMap *
1722 new( class, options )
1723 char * class
1724 char * options
1725 CODE:
1726 #ifndef HASKEYMAP
1727 Perl_croak(aTHX_ "AstKeyMap: Please upgrade to AST V3.5 or newer");
1728 #else
1729 ASTCALL(
1730 RETVAL = astKeyMap( options );
1731 )
1732 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
1733 #endif
1734 OUTPUT:
1735 RETVAL
1736
1737 void
1738 astMapPutU( this, key, comment )
1739 AstKeyMap * this
1740 char * key
1741 char * comment
1742 CODE:
1743 #ifndef HASMAPPUTU
1744 Perl_croak(aTHX_ "astMapPutU: Please upgrade to AST V5.3 or newer");
1745 #else
1746 ASTCALL(
1747 astMapPutU( this, key, comment);
1748 )
1749 #endif
1750
1751 void
1752 astMapPut0D( this, key, value, comment)
1753 AstKeyMap * this
1754 char * key
1755 double value
1756 char * comment
1757 CODE:
1758 #ifndef HASKEYMAP
1759 Perl_croak(aTHX_ "astMapPut0D: Please upgrade to AST V3.5 or newer");
1760 #else
1761 ASTCALL(
1762 astMapPut0D( this, key, value, comment);
1763 )
1764 #endif
1765
1766 void
1767 astMapPut0I( this, key, value, comment)
1768 AstKeyMap * this
1769 char * key
1770 int value
1771 char * comment
1772 CODE:
1773 #ifndef HASKEYMAP
1774 Perl_croak(aTHX_ "astMapPut0I: Please upgrade to AST V3.5 or newer");
1775 #else
1776 ASTCALL(
1777 astMapPut0I( this, key, value, comment);
1778 )
1779 #endif
1780
1781 void
1782 astMapPut0S( this, key, value, comment)
1783 AstKeyMap * this
1784 char * key
1785 int value
1786 char * comment
1787 CODE:
1788 #ifndef HASKEYMAPSHORT
1789 Perl_croak(aTHX_ "astMapPut0S: Please upgrade to AST V5.4 or newer");
1790 #else
1791 if ( value < SHRT_MIN || value > SHRT_MAX ) {
1792 Perl_croak( aTHX_ "astMapPut0S: Supplied short value (%d) is out of range",
1793 value );
1794 }
1795 ASTCALL(
1796 astMapPut0S( this, key, value, comment);
1797 )
1798 #endif
1799
1800 void
1801 astMapPut0C( this, key, value, comment)
1802 AstKeyMap * this
1803 char * key
1804 char * value
1805 char * comment
1806 CODE:
1807 #ifndef HASKEYMAP
1808 Perl_croak(aTHX_ "astMapPut0C: Please upgrade to AST V3.5 or newer");
1809 #else
1810 ASTCALL(
1811 astMapPut0C( this, key, value, comment);
1812 )
1813 #endif
1814
1815 void
1816 astMapPut0A( this, key, value, comment)
1817 AstKeyMap * this
1818 char * key
1819 AstObject * value
1820 char * comment
1821 CODE:
1822 #ifndef HASKEYMAP
1823 Perl_croak(aTHX_ "astMapPut0A: Please upgrade to AST V3.5 or newer");
1824 #else
1825 ASTCALL(
1826 astMapPut0A( this, key, value, comment);
1827 )
1828 #endif
1829
1830 void
1831 astMapPut1D( this, key, values, comment)
1832 AstKeyMap * this
1833 char * key
1834 AV * values
1835 char * comment
1836 PREINIT:
1837 int size;
1838 double * val;
1839 CODE:
1840 #ifndef HASKEYMAP
1841 Perl_croak(aTHX_ "astMapPut1D: Please upgrade to AST V3.5 or newer");
1842 #else
1843 size = av_len(values) + 1;
1844 val = pack1D( newRV_noinc((SV*)values),'d');
1845 ASTCALL(
1846 astMapPut1D( this, key, size, val, comment);
1847 )
1848 #endif
1849
1850 void
1851 astMapPut1I( this, key, values, comment)
1852 AstKeyMap * this
1853 char * key
1854 AV * values
1855 char * comment
1856 PREINIT:
1857 int size;
1858 int * val;
1859 CODE:
1860 #ifndef HASKEYMAP
1861 Perl_croak(aTHX_ "astMapPut1I: Please upgrade to AST V3.5 or newer");
1862 #else
1863 size = av_len(values) + 1;
1864 val = pack1D( newRV_noinc((SV*)values),'i');
1865 ASTCALL(
1866 astMapPut1I( this, key, size, val, comment);
1867 )
1868 #endif
1869
1870 void
1871 astMapPut1S( this, key, values, comment)
1872 AstKeyMap * this
1873 char * key
1874 AV * values
1875 char * comment
1876 PREINIT:
1877 int size;
1878 int i;
1879 short * val;
1880 CODE:
1881 #ifndef HASKEYMAPSHORT
1882 Perl_croak(aTHX_ "astMapPut1S: Please upgrade to AST V5.4 or newer");
1883 #else
1884 size = av_len(values) + 1;
1885 for (i=0; i<size;i++) {
1886 SV ** element = av_fetch( values, i, 0 );
1887 if (element) {
1888 IV ival = 0;
1889 if (SvROK(*element)) {
1890 Perl_croak( aTHX_ "Can not store reference in short keymap" );
1891 }
1892 ival = SvIV(*element);
1893 if (ival < SHRT_MIN || ival > SHRT_MAX) {
1894 Perl_croak( aTHX_ "MapPut1S: Value of element %d (%ld) is out of range for a short",
1895 i, (long)ival );
1896 }
1897 }
1898 }
1899 val = pack1D( newRV_noinc((SV*)values),'s');
1900 ASTCALL(
1901 astMapPut1S( this, key, size, val, comment);
1902 )
1903 #endif
1904
1905 void
1906 astMapPut1C( this, key, values, comment)
1907 AstKeyMap * this
1908 char * key
1909 AV * values
1910 char * comment
1911 PREINIT:
1912 int size;
1913 char ** val;
1914 CODE:
1915 #ifndef HASKEYMAP
1916 Perl_croak(aTHX_ "astMapPut1C: Please upgrade to AST V3.5 or newer");
1917 #else
1918 size = av_len(values) + 1;
1919 val = pack1Dchar( values );
1920 ASTCALL(
1921 astMapPut1C( this, key, size, (const char **)val, comment);
1922 )
1923 #endif
1924
1925 void
1926 astMapPut1A( this, key, values, comment)
1927 AstKeyMap * this
1928 char * key
1929 AV * values
1930 char * comment
1931 PREINIT:
1932 int size;
1933 AstObject ** val;
1934 CODE:
1935 #ifndef HASKEYMAP
1936 Perl_croak(aTHX_ "astMapPut1A: Please upgrade to AST V3.5 or newer");
1937 #else
1938 size = av_len(values) + 1;
1939 val = pack1DAstObj( values );
1940 ASTCALL(
1941 astMapPut1A( this, key, size, val, comment);
1942 )
1943 #endif
1944
1945 void
1946 astMapGet0D( this, key )
1947 AstKeyMap * this
1948 char * key
1949 PREINIT:
1950 double RETVAL;
1951 int status;
1952 PPCODE:
1953 #ifndef HASKEYMAP
1954 Perl_croak(aTHX_ "astMapGet0D: Please upgrade to AST V3.5 or newer");
1955 #else
1956 ASTCALL(
1957 status = astMapGet0D( this, key, &RETVAL );
1958 )
1959 if (status != 0) {
1960 XPUSHs(sv_2mortal(newSVnv(RETVAL)));
1961 } else {
1962 XSRETURN_EMPTY;
1963 }
1964 #endif
1965
1966 # Short ints are handled by "I" interface because Perl will always
1967 # convert the short to an IV.
1968
1969 void
1970 astMapGet0I( this, key )
1971 AstKeyMap * this
1972 char * key
1973 PREINIT:
1974 int RETVAL;
1975 int status;
1976 ALIAS:
1977 MapGet0S = 1
1978 PPCODE:
1979 #ifndef HASKEYMAP
1980 Perl_croak(aTHX_ "astMapGet0I: Please upgrade to AST V3.5 or newer");
1981 #else
1982 ASTCALL(
1983 status = astMapGet0I( this, key, &RETVAL );
1984 )
1985 if (status != 0) {
1986 XPUSHs(sv_2mortal(newSViv(RETVAL)));
1987 } else {
1988 XSRETURN_EMPTY;
1989 }
1990 #endif
1991
1992 void
1993 astMapGet0C( this, key )
1994 AstKeyMap * this
1995 char * key
1996 PREINIT:
1997 char * RETVAL;
1998 int status;
1999 PPCODE:
2000 #ifndef HASKEYMAP
2001 Perl_croak(aTHX_ "astMapGet0C: Please upgrade to AST V3.5 or newer");
2002 #else
2003 ASTCALL(
2004 status = astMapGet0C( this, key, (const char **)&RETVAL );
2005 )
2006 if (status != 0) {
2007 XPUSHs(sv_2mortal(newSVpvn(RETVAL,strlen(RETVAL))));
2008 } else {
2009 XSRETURN_EMPTY;
2010 }
2011 #endif
2012
2013 # Note the underscore in the name because currently we return
2014 # a Starlink::AST object rather than a real object and there is
2015 # a perl layer to rebless. We should probably do this in the C
2016 # layer
2017
2018 void
2019 ast_MapGet0A( this, key )
2020 AstKeyMap * this
2021 char * key
2022 PREINIT:
2023 AstObject * RETVAL;
2024 int status;
2025 SV * sv;
2026 PPCODE:
2027 #ifndef HASKEYMAP
2028 Perl_croak(aTHX_ "astMapGet0A: Please upgrade to AST V3.5 or newer");
2029 #else
2030 ASTCALL(
2031 status = astMapGet0A( this, key, &RETVAL );
2032 )
2033 if (status != 0) {
2034 /* Have an AstObject pointer. Convert to object. */
2035 sv = createPerlObject( "AstObjectPtr", RETVAL );
2036 XPUSHs(sv_2mortal( sv ));
2037 } else {
2038 XSRETURN_EMPTY;
2039 }
2040 #endif
2041
2042
2043 void
2044 astMapGet1D( this, key )
2045 AstKeyMap * this
2046 char * key
2047 PREINIT:
2048 int i;
2049 int status;
2050 double * outarr;
2051 int nelems;
2052 PPCODE:
2053 #ifndef HASKEYMAP
2054 Perl_croak(aTHX_ "astMapGet1D: Please upgrade to AST V3.5 or newer");
2055 #else
2056 /* First we need to find out how many elements are in the KeyMap */
2057 nelems = astMapLength( this, key );
2058 if (nelems == 0) {
2059 XSRETURN_EMPTY;
2060 }
2061
2062 /* get some memory */
2063 outarr = get_mortalspace( nelems, 'd' );
2064
2065 ASTCALL(
2066 status = astMapGet1D( this, key, nelems, &nelems, outarr );
2067 )
2068 if (status != 0) {
2069 for (i=0; i < nelems; i++) {
2070 XPUSHs(sv_2mortal(newSVnv( outarr[i] )));
2071 }
2072 } else {
2073 XSRETURN_EMPTY;
2074 }
2075 #endif
2076
2077 # The short int version does not need a separate implementation
2078 # because perl doesn't care and will end up reading it in as an IV
2079 # anyhow. The only reason to implement the "S" routine separately
2080 # is for the smaller memory requirement.
2081
2082 void
2083 astMapGet1I( this, key )
2084 AstKeyMap * this
2085 char * key
2086 PREINIT:
2087 int i;
2088 int status;
2089 int * outarr;
2090 int nelems;
2091 ALIAS:
2092 MapGet1S = 1
2093 PPCODE:
2094 #ifndef HASKEYMAP
2095 Perl_croak(aTHX_ "astMapGet1I: Please upgrade to AST V3.5 or newer");
2096 #else
2097 /* First we need to find out how many elements are in the KeyMap */
2098 nelems = astMapLength( this, key );
2099 if (nelems == 0) {
2100 XSRETURN_EMPTY;
2101 }
2102
2103 /* get some memory */
2104 outarr = get_mortalspace( nelems, 'i' );
2105
2106 ASTCALL(
2107 status = astMapGet1I( this, key, nelems, &nelems, outarr );
2108 )
2109 if (status != 0) {
2110 for (i=0; i < nelems; i++) {
2111 XPUSHs(sv_2mortal(newSViv( outarr[i] )));
2112 }
2113 } else {
2114 XSRETURN_EMPTY;
2115 }
2116 #endif
2117
2118 void
2119 ast_MapGet1A( this, key )
2120 AstKeyMap * this
2121 char * key
2122 PREINIT:
2123 SV * sv;
2124 int i;
2125 int status;
2126 AstObject ** outarr;
2127 int nelems;
2128 PPCODE:
2129 #ifndef HASKEYMAP
2130 Perl_croak(aTHX_ "astMapGet1A: Please upgrade to AST V3.5 or newer");
2131 #else
2132 /* First we need to find out how many elements are in the KeyMap */
2133 nelems = astMapLength( this, key );
2134 if (nelems == 0) {
2135 XSRETURN_EMPTY;
2136 }
2137
2138 /* get some memory */
2139 outarr = get_mortalspace( nelems, 'v' );
2140
2141 ASTCALL(
2142 status = astMapGet1A( this, key, nelems, &nelems, outarr );
2143 )
2144 if (status != 0) {
2145 for (i=0; i < nelems; i++) {
2146 /* Have an AstObject pointer. Convert to object. */
2147 sv = createPerlObject( "AstObjectPtr", outarr[i] );
2148 XPUSHs(sv_2mortal( sv ));
2149 }
2150 } else {
2151 XSRETURN_EMPTY;
2152 }
2153 #endif
2154
2155 void
2156 astMapGet1C( this, key )
2157 AstKeyMap * this
2158 char * key
2159 PREINIT:
2160 SV * sv;
2161 int i;
2162 int status;
2163 char * buffer;
2164 char * tmpp;
2165 int nelems;
2166 int maxlen = 80; /* max length of each string in map. Includes NUL */
2167 PPCODE:
2168 #ifndef HASKEYMAP
2169 Perl_croak(aTHX_ "astMapGet1C: Please upgrade to AST V3.5 or newer");
2170 #else
2171 /* First we need to find out how many elements are in the KeyMap */
2172 nelems = astMapLength( this, key );
2173 if (nelems == 0) {
2174 XSRETURN_EMPTY;
2175 }
2176
2177 /* get some memory */
2178 buffer = get_mortalspace( nelems * maxlen, 'u' );
2179
2180 ASTCALL(
2181 status = astMapGet1C( this, key, maxlen, nelems, &nelems, buffer );
2182 )
2183 if (status != 0) {
2184 /* set temp pointer to start of buffer */
2185 tmpp = buffer;
2186 for (i=0; i < nelems; i++) {
2187 /* Jump through the buffer in maxlen hops */
2188 XPUSHs(sv_2mortal( newSVpvn(tmpp, strlen(tmpp)) ));
2189 tmpp += maxlen;
2190 }
2191 } else {
2192 XSRETURN_EMPTY;
2193 }
2194 #endif
2195
2196 void
2197 astMapRemove( this, key )
2198 AstKeyMap * this
2199 char * key
2200 CODE:
2201 #ifndef HASKEYMAP
2202 Perl_croak(aTHX_ "astMapRemove: Please upgrade to AST V3.5 or newer");
2203 #else
2204
2205 ASTCALL(
2206 astMapRemove( this, key );
2207 )
2208 #endif
2209
2210 int
2211 astMapSize( this )
2212 AstKeyMap * this
2213 CODE:
2214 #ifndef HASKEYMAP
2215 Perl_croak(aTHX_ "astMapSize: Please upgrade to AST V3.5 or newer");
2216 #else
2217 ASTCALL(
2218 RETVAL = astMapSize( this );
2219 )
2220 #endif
2221 OUTPUT:
2222 RETVAL
2223
2224 int
2225 astMapLength( this, key )
2226 AstKeyMap * this
2227 char * key
2228 CODE:
2229 #ifndef HASKEYMAP
2230 Perl_croak(aTHX_ "astMapLength: Please upgrade to AST V3.5 or newer");
2231 #else
2232 ASTCALL(
2233 RETVAL = astMapLength( this, key );
2234 )
2235 #endif
2236 OUTPUT:
2237 RETVAL
2238
2239 bool
2240 astMapHasKey( this, key )
2241 AstKeyMap * this
2242 char * key
2243 PREINIT:
2244 int haskey;
2245 CODE:
2246 #ifndef HASKEYMAP
2247 Perl_croak(aTHX_ "astMapHasKey: Please upgrade to AST V3.5 or newer");
2248 #else
2249 ASTCALL(
2250 haskey = astMapHasKey( this, key );
2251 )
2252 RETVAL = ( haskey == 0 ? 0 : 1 );
2253 #endif
2254 OUTPUT:
2255 RETVAL
2256
2257 const char *
2258 astMapKey( this, index )
2259 AstKeyMap * this
2260 int index
2261 CODE:
2262 #ifndef HASKEYMAP
2263 Perl_croak(aTHX_ "astMapKey: Please upgrade to AST V3.5 or newer");
2264 #else
2265 ASTCALL(
2266 RETVAL = astMapKey( this, index );
2267 )
2268 #endif
2269 OUTPUT:
2270 RETVAL
2271
2272 int
2273 astMapType( this, key )
2274 AstKeyMap * this
2275 char * key
2276 CODE:
2277 #ifndef HASKEYMAP
2278 Perl_croak(aTHX_ "astMapType: Please upgrade to AST V3.5 or newer");
2279 #else
2280 ASTCALL(
2281 RETVAL = astMapType( this, key );
2282 )
2283 #endif
2284 OUTPUT:
2285 RETVAL
2286
2287 bool
2288 astMapDefined( this, key )
2289 AstKeyMap * this
2290 char * key
2291 CODE:
2292 #ifndef HASMAPDEFINED
2293 Perl_croak(aTHX_ "astMapDefined: Please upgrade to AST V7.2 or newer");
2294 #else
2295 ASTCALL(
2296 RETVAL = astMapDefined( this, key );
2297 )
2298 #endif
2299 OUTPUT:
2300 RETVAL
2301
2302 MODULE = Starlink::AST PACKAGE = Starlink::AST::Frame PREFIX = ast
2303
2304
2305 double
2306 astAngle( this, a, b, c )
2307 AstFrame * this
2308 AV* a
2309 AV* b
2310 AV* c
2311 PREINIT:
2312 double * aa;
2313 double * bb;
2314 double * cc;
2315 int naxes;
2316 CODE:
2317 /* Create C arrays of the correct dimensions */
2318 naxes = astGetI( this, "Naxes" );
2319
2320 /* Copy from the perl array to the C array */
2321 if (av_len(a) != naxes-1)
2322 Perl_croak(aTHX_ "Number of elements in first coord array must be %d",
2323 naxes);
2324 if (av_len(b) != naxes-1)
2325 Perl_croak(aTHX_ "Number of elements in second coord array must be %d",
2326 naxes);
2327 if (av_len(c) != naxes-1)
2328 Perl_croak(aTHX_ "Number of elements in third coord array must be %d",
2329 naxes);
2330
2331 aa = pack1D( newRV_noinc((SV*)a), 'd');
2332 bb = pack1D( newRV_noinc((SV*)b), 'd');
2333 cc = pack1D( newRV_noinc((SV*)c), 'd');
2334
2335 /* Call the ast function */
2336 ASTCALL(
2337 RETVAL = astAngle( this, aa, bb, cc);
2338 )
2339 OUTPUT:
2340 RETVAL
2341
2342 double
2343 astAxAngle( this, a, b, axis )
2344 AstFrame * this
2345 AV* a
2346 AV* b
2347 int axis
2348 PREINIT:
2349 double * aa;
2350 double * bb;
2351 int naxes;
2352 CODE:
2353 /* Create C arrays of the correct dimensions */
2354 naxes = astGetI( this, "Naxes" );
2355
2356 /* Copy from the perl array to the C array */
2357 if (av_len(a) != naxes-1)
2358 Perl_croak(aTHX_ "Number of elements in first coord array must be %d",
2359 naxes);
2360 if (av_len(b) != naxes-1)
2361 Perl_croak(aTHX_ "Number of elements in second coord array must be %d",
2362 naxes);
2363
2364 aa = pack1D( newRV_noinc((SV*)a), 'd');
2365 bb = pack1D( newRV_noinc((SV*)b), 'd');
2366 ASTCALL(
2367 RETVAL = astAxAngle( this, aa, bb, axis);
2368 )
2369 OUTPUT:
2370 RETVAL
2371
2372 double
2373 astAxDistance( this, axis, v1, v2)
2374 AstFrame * this
2375 int axis
2376 double v1
2377 double v2
2378 CODE:
2379 ASTCALL(
2380 RETVAL = astAxDistance( this, axis, v1, v2);
2381 )
2382 OUTPUT:
2383 RETVAL
2384
2385 double
2386 astAxOffset( this, axis, v1, dist)
2387 AstFrame * this
2388 int axis
2389 double v1
2390 double dist
2391 CODE:
2392 ASTCALL(
2393 RETVAL = astAxOffset( this, axis, v1, dist);
2394 )
2395 OUTPUT:
2396 RETVAL
2397
2398 AstFrameSet *
2399 astConvert( from, to, domainlist )
2400 AstFrame * from
2401 AstFrame * to
2402 char * domainlist
2403 CODE:
2404 ASTCALL(
2405 RETVAL = astConvert( from, to, domainlist );
2406 )
2407 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
2408 OUTPUT:
2409 RETVAL
2410
2411 double
2412 astDistance( this, point1, point2 )
2413 AstFrame * this
2414 AV* point1
2415 AV* point2
2416 PREINIT:
2417 double * aa;
2418 double * bb;
2419 int naxes;
2420 CODE:
2421 /* Create C arrays of the correct dimensions */
2422 naxes = astGetI( this, "Naxes" );
2423
2424 /* Copy from the perl array to the C array */
2425 if (av_len(point1) != naxes-1)
2426 Perl_croak(aTHX_ "Number of elements in first coord array must be %d",
2427 naxes);
2428 if (av_len(point2) != naxes-1)
2429 Perl_croak(aTHX_ "Number of elements in second coord array must be %d",
2430 naxes);
2431
2432 aa = pack1D( newRV_noinc((SV*)point1), 'd');
2433 bb = pack1D( newRV_noinc((SV*)point2), 'd');
2434 ASTCALL(
2435 RETVAL = astDistance( this, aa, bb);
2436 )
2437 OUTPUT:
2438 RETVAL
2439
2440 AstFrameSet *
2441 astFindFrame( this, template, domainlist )
2442 AstFrame * this
2443 AstFrame * template
2444 char * domainlist
2445 CODE:
2446 ASTCALL(
2447 RETVAL = astFindFrame( this, template, domainlist );
2448 )
2449 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
2450 OUTPUT:
2451 RETVAL
2452
2453 const char *
2454 astFormat( this, axis, value )
2455 AstFrame * this
2456 int axis
2457 double value
2458 CODE:
2459 ASTCALL(
2460 RETVAL = astFormat( this, axis, value );
2461 )
2462 OUTPUT:
2463 RETVAL
2464
2465 int
2466 astGetActiveUnit( this )
2467 AstFrame * this
2468 CODE:
2469 #ifndef HASGETACTIVEUNIT
2470 Perl_croak(aTHX_ "astGetActiveUnit: Please upgrade to AST V2.x or newer");
2471 #else
2472 ASTCALL(
2473 RETVAL = astGetActiveUnit( this );
2474 )
2475 #endif
2476 OUTPUT:
2477 RETVAL
2478
2479 # @normalised = $wcs->Norm( @unnormalised );
2480
2481 void
2482 astNorm( this, ... )
2483 AstFrame * this
2484 PREINIT:
2485 int argoff = 1; /* number of fixed arguments */
2486 int naxes;
2487 double * aa;
2488 int i;
2489 int ncoord_in;
2490 double * inputs;
2491 PPCODE:
2492 /* Create C arrays of the correct dimensions */
2493 naxes = astGetI( this, "Naxes" );
2494 ncoord_in = items - argoff;
2495
2496 /* Copy from the perl array to the C array */
2497 if (naxes != ncoord_in )
2498 Perl_croak(aTHX_ "Number of elements in first coord array must be %d",
2499 naxes);
2500 aa = get_mortalspace( ncoord_in, 'd' );
2501 for (i=0; i<ncoord_in; i++) {
2502 int argpos = i + argoff;
2503 aa[i] = SvNV( ST(argpos) );
2504 }
2505
2506 ASTCALL(
2507 astNorm( this, aa );
2508 )
2509
2510 for (i=0; i<naxes; i++) {
2511 XPUSHs( sv_2mortal( newSVnv( aa[i] ) ) );
2512 }
2513
2514 # Return list
2515
2516 void
2517 astOffset( this, point1, point2, offset )
2518 AstFrame * this
2519 AV* point1
2520 AV* point2
2521 double offset
2522 PREINIT:
2523 int naxes;
2524 double * aa;
2525 double * bb;
2526 double * point3;
2527 int i;
2528 AV * myoffset;
2529 PPCODE:
2530 naxes = astGetI( this, "Naxes" );
2531
2532 /* Copy from the perl array to the C array */
2533 if (av_len(point1) != naxes-1)
2534 Perl_croak(aTHX_ "Number of elements in first coord array must be %d",
2535 naxes);
2536 aa = pack1D( newRV_noinc((SV*)point1), 'd');
2537 if (av_len(point2) != naxes-1)
2538 Perl_croak(aTHX_ "Number of elements in second coord array must be %d",
2539 naxes);
2540 bb = pack1D( newRV_noinc((SV*)point2), 'd');
2541
2542
2543 /* Somewhere to put the return values */
2544 point3 = get_mortalspace( naxes, 'd' );
2545
2546 ASTCALL(
2547 astOffset( this, aa, bb, offset, point3 );
2548 )
2549
2550 /* now need to push the resulting values onto the return stack */
2551 /* Put everything in an array [rather than the stack] in order to
2552 be consistent in returning C arrays as perl arrays. */
2553 myoffset = newAV();
2554 for (i =0; i < naxes; i++ ) {
2555 av_push( myoffset, newSVnv( point3[i] ));
2556 }
2557 XPUSHs( newRV_noinc( (SV*)myoffset ));
2558
2559
2560
2561 # Returns angle and reference to array of pair of coordinates
2562
2563 void
2564 astOffset2( this, point1, angle, offset )
2565 AstFrame * this
2566 AV* point1
2567 double angle
2568 double offset
2569 PREINIT:
2570 int naxes;
2571 double * aa;
2572 double * point2;
2573 int i;
2574 double RETVAL;
2575 AV * myoffset;
2576 PPCODE:
2577 naxes = astGetI( this, "Naxes" );
2578
2579 /* Copy from the perl array to the C array */
2580 if (av_len(point1) != naxes-1)
2581 Perl_croak(aTHX_ "Number of elements in first coord array must be %d",
2582 naxes);
2583 aa = pack1D( newRV_noinc((SV*)point1), 'd');
2584
2585 /* Somewhere to put the return values */
2586 point2 = get_mortalspace( naxes, 'd' );
2587
2588 ASTCALL(
2589 RETVAL = astOffset2( this, aa, angle, offset, point2 );
2590 )
2591
2592 /* Push the angle on to the stack */
2593 XPUSHs(sv_2mortal(newSVnv(RETVAL)));
2594
2595 /* Put everything in an array [rather than the stack] in order to
2596 be consistent in returning C arrays as perl arrays. */
2597 myoffset = newAV();
2598 for (i =0; i < naxes; i++ ) {
2599 av_push( myoffset, newSVnv( point2[i] ));
2600 }
2601 XPUSHs( newRV_noinc( (SV*)myoffset ));
2602
2603
2604 void
2605 astPermAxes( this, perm )
2606 AstFrame * this
2607 AV* perm
2608 PREINIT:
2609 int * aa;
2610 int naxes;
2611 CODE:
2612 naxes = astGetI(this, "Naxes");
2613 /* Copy from the perl array to the C array */
2614 if (av_len(perm) != naxes-1)
2615 Perl_croak(aTHX_ "Number of elements in perm array must be %d",
2616 naxes);
2617 aa = pack1D( newRV_noinc((SV*)perm), 'i');
2618 ASTCALL(
2619 astPermAxes( this, aa );
2620 )
2621
2622 # Returns a new frame and an optional mapping
2623 # Also note that we count axes ourselves
2624
2625 # We always ask for the return mapping and we always
2626 # return both the new frame and the mapping from the old
2627 # The perl side decides whether the user wants to keep the
2628 # mapping or not depending on context (Which is unavailable
2629 # to XS)
2630
2631 void
2632 ast_PickAxes( this, axes )
2633 AstFrame * this;
2634 AV* axes
2635 PREINIT:
2636 int maxaxes;
2637 int naxes;
2638 int * aa;
2639 AstMapping * map;
2640 AstFrame * newframe;
2641 PPCODE:
2642 maxaxes = astGetI(this, "Naxes");
2643 naxes = av_len(axes) + 1;
2644 if ( naxes > maxaxes )
2645 Perl_croak(aTHX_ "Number of axes selected must be less than number of axes in frame");
2646 aa = pack1D( newRV_noinc((SV*)axes), 'i');
2647 ASTCALL(
2648 newframe = astPickAxes( this, naxes, aa, &map);
2649 )
2650 if ( newframe == AST__NULL ) XSRETURN_UNDEF;
2651 /* Create perl objects from the two return arguments */
2652 XPUSHs(sv_2mortal( createPerlObject( "AstFramePtr", (AstObject*)newframe )));
2653 XPUSHs(sv_2mortal( createPerlObject( "AstMappingPtr", (AstObject*)map )));
2654
2655
2656 # Returns reference to array [point4], plus two distances
2657
2658 void
2659 astResolve( this, point1, point2, point3 )
2660 AstFrame * this
2661 AV* point1
2662 AV* point2
2663 AV* point3
2664 PREINIT:
2665 double * cpoint1;
2666 double * cpoint2;
2667 double * cpoint3;
2668 double * cpoint4;
2669 AV * point4;
2670 double d1;
2671 double d2;
2672 int len;
2673 int naxes;
2674 PPCODE:
2675 naxes = astGetI(this, "Naxes");
2676 len = av_len(point1) + 1;
2677 if ( naxes != len )
2678 Perl_croak(aTHX_ "Number of coords in point1 must be equal to the number of axes in frame [%d != %d]", naxes, len);
2679 len = av_len(point2) + 1;
2680 if ( naxes != len )
2681 Perl_croak(aTHX_ "Number of coords in point2 must be equal to the number of axes in frame [%d != %d]", naxes, len);
2682 len = av_len(point3) + 1;
2683 if ( naxes != len )
2684 Perl_croak(aTHX_ "Number of coords in point3 must be equal to the number of axes in frame [%d != %d]", naxes, len);
2685
2686 cpoint1 = pack1D( newRV_noinc((SV*)point1), 'd');
2687 cpoint2 = pack1D( newRV_noinc((SV*)point2), 'd');
2688 cpoint3 = pack1D( newRV_noinc((SV*)point3), 'd');
2689 cpoint4 = get_mortalspace( naxes, 'd' );
2690
2691 ASTCALL(
2692 astResolve(this, cpoint1, cpoint2, cpoint3, cpoint4, &d1, &d2);
2693 )
2694
2695 point4 = newAV();
2696 unpack1D( newRV_noinc((SV*)point4), cpoint4, 'd', naxes);
2697
2698 XPUSHs( newRV_noinc((SV*) point4));
2699 XPUSHs( sv_2mortal(newSVnv(d1)));
2700 XPUSHs( sv_2mortal(newSVnv(d2)));
2701
2702
2703
2704
2705 void
2706 astSetActiveUnit( this, value )
2707 AstFrame * this
2708 int value
2709 CODE:
2710 #ifndef HASSETACTIVEUNIT
2711 Perl_croak(aTHX_ "astSetActiveUnit: Please upgrade to AST V2.x or newer");
2712 #else
2713 ASTCALL(
2714 astSetActiveUnit( this, value );
2715 )
2716 #endif
2717
2718 # astUnformat currently returns the value not the number of
2719 # characters read. Returns undef if no character read
2720 # XXXXX
2721
2722 double
2723 astUnformat( this, axis, string )
2724 AstFrame * this
2725 int axis
2726 char * string
2727 PREINIT:
2728 int nread;
2729 CODE:
2730 nread = astUnformat( this, axis, string, &RETVAL );
2731 if (nread == 0 ) XSRETURN_UNDEF;
2732 OUTPUT:
2733 RETVAL
2734
2735
2736 MODULE = Starlink::AST PACKAGE = Starlink::AST::FrameSet PREFIX = ast
2737
2738 void
2739 astAddFrame( this, iframe, map, frame)
2740 AstFrameSet * this
2741 int iframe
2742 AstMapping * map
2743 AstFrame * frame
2744 CODE:
2745 ASTCALL(
2746 astAddFrame( this, iframe, map, frame );
2747 )
2748
2749
2750 AstFrame *
2751 ast_GetFrame( this, iframe )
2752 AstFrameSet * this
2753 int iframe
2754 CODE:
2755 ASTCALL(
2756 RETVAL = astGetFrame( this, iframe );
2757 )
2758 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
2759 OUTPUT:
2760 RETVAL
2761
2762 AstMapping *
2763 astGetMapping( this, iframe1, iframe2 )
2764 AstFrameSet * this
2765 int iframe1
2766 int iframe2
2767 CODE:
2768 ASTCALL(
2769 RETVAL = astGetMapping( this, iframe1, iframe2 );
2770 )
2771 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
2772 OUTPUT:
2773 RETVAL
2774
2775 void
2776 astRemapFrame( this, iframe, map )
2777 AstFrameSet * this
2778 int iframe
2779 AstMapping * map
2780 CODE:
2781 ASTCALL(
2782 astRemapFrame( this, iframe, map );
2783 )
2784
2785 void
2786 astRemoveFrame( this, iframe )
2787 AstFrameSet * this
2788 int iframe
2789 CODE:
2790 ASTCALL(
2791 astRemoveFrame( this, iframe );
2792 )
2793
2794 MODULE = Starlink::AST PACKAGE = Starlink::AST::Mapping PREFIX = ast
2795
2796 # Return the new mappings and booleans as a list
2797 # Do this later since it requires subversion of the typemap
2798 # system
2799
2800 # XXXXX
2801
2802 void
2803 astDecompose( this )
2804 AstMapping * this
2805 PREINIT:
2806 AstMapping * map1;
2807 AstMapping * map2;
2808 int series;
2809 int invert1;
2810 int invert2;
2811 PPCODE:
2812 Perl_croak(aTHX_ "astDecompose not yet implemented\n");
2813 /* May want to restrict this to CmpMap and CmpFrame classes
2814 explicitly */
2815 ASTCALL(
2816 astDecompose(this, &map1, &map2, &series, &invert1, &invert2);
2817 )
2818
2819
2820 void
2821 astInvert( this )
2822 AstMapping * this
2823 CODE:
2824 ASTCALL(
2825 astInvert( this );
2826 )
2827
2828 void
2829 astLinearApprox( this, lbnd, ubnd, tol )
2830 AstMapping * this
2831 AV * lbnd
2832 AV * ubnd
2833 double tol
2834 PREINIT:
2835 int len;
2836 double * clbnd;
2837 double * cubnd;
2838 int nin;
2839 int nout;
2840 int ncoeff;
2841 double * fit;
2842 int i;
2843 int status;
2844 PPCODE:
2845 #ifndef HASLINEARAPPROX
2846 Perl_croak(aTHX_ "astLinearApprox: Please upgrade to AST V3.4 or greater");
2847 #else
2848 /* get the input values and verify them */
2849 nin = astGetI( this, "Nin" );
2850 len = av_len( lbnd ) + 1;
2851 if ( len != nin ) Perl_croak( aTHX_ "lbnd must contain %d elements", nin );
2852 len = av_len( ubnd ) + 1;
2853 if ( len != nin ) Perl_croak( aTHX_ "ubnd must contain %d elements", nin );
2854 clbnd = pack1D(newRV_noinc((SV*)lbnd), 'd');
2855 cubnd = pack1D(newRV_noinc((SV*)ubnd), 'd');
2856
2857 /* Get memory for the return values */
2858 nout = astGetI( this, "Nout");
2859 ncoeff = (nin+1) * nout;
2860 fit = get_mortalspace( ncoeff, 'd' );
2861
2862 ASTCALL(
2863 status = astLinearApprox( this, clbnd, cubnd, tol, fit );
2864 )
2865 if ( status == 0) {
2866 XSRETURN_EMPTY;
2867 } else {
2868 for (i = 0; i < ncoeff; i++) {
2869 XPUSHs( sv_2mortal( newSVnv( fit[i] ) ) );
2870 }
2871 }
2872 #endif
2873
2874 # astMapBox
2875 # ($lbnd_out, $ubnd_out, \@xl, \@xu) = $mapping->MapBox(\@lbnd_in, \@ubnd_in, $forward, $coord_out);
2876
2877 void
2878 astMapBox( this, lbnd_in, ubnd_in, forward, coord_out )
2879 AstMapping * this
2880 AV * lbnd_in
2881 AV * ubnd_in
2882 int forward
2883 int coord_out
2884 PREINIT:
2885 int nin;
2886 int len;
2887 double * clbnd = NULL;
2888 double * cubnd = NULL;
2889 double * cxl = NULL;
2890 double * cxu = NULL;
2891 double lbnd_out;
2892 double ubnd_out;
2893 AV * xl = NULL;
2894 AV * xu = NULL;
2895 PPCODE:
2896 nin = astGetI( this, "Nin" );
2897 len = av_len( lbnd_in ) + 1;
2898 if ( len != nin ) Perl_croak( aTHX_ "lbnd must contain %d elements", nin );
2899 len = av_len( ubnd_in ) + 1;
2900 if ( len != nin ) Perl_croak( aTHX_ "ubnd must contain %d elements", nin );
2901 clbnd = pack1D(newRV_noinc((SV*)lbnd_in), 'd' );
2902 cubnd = pack1D(newRV_noinc((SV*)ubnd_in), 'd' );
2903
2904 /* Return arrays */
2905 cxl = get_mortalspace( nin, 'd' );
2906 cxu = get_mortalspace( nin, 'd' );
2907
2908 ASTCALL(
2909 astMapBox( this, clbnd, cubnd, forward, coord_out,
2910 &lbnd_out, &ubnd_out, cxl, cxu );
2911 )
2912
2913 /* Push results */
2914 XPUSHs(sv_2mortal(newSVnv(lbnd_out)));
2915 XPUSHs(sv_2mortal(newSVnv(ubnd_out)));
2916
2917 xl = newAV();
2918 unpack1D( newRV_noinc((SV*) xl), cxl, 'd', nin );
2919 XPUSHs( newRV_noinc( (SV*)xl ));
2920 xu = newAV();
2921 unpack1D( newRV_noinc((SV*) xu), cxu, 'd', nin );
2922 XPUSHs( newRV_noinc( (SV*)xu ));
2923
2924
2925 # astMapSplit
2926 # One argument: The indices of the mapping to extract
2927 # Two return arguments: A mapping and a list of indices
2928 # ($map, @indices) = $map->MapSplit( \@indices );
2929 void
2930 astMapSplit( this, in )
2931 AstMapping * this
2932 AV * in
2933 PREINIT:
2934 int i;
2935 int nin;
2936 int nout;
2937 int * cin;
2938 int * cout;
2939 AstMapping * outmap = NULL;
2940 PPCODE:
2941 #ifndef HASMAPSPLIT
2942 Perl_croak(aTHX_ "astMapSplit: Please upgrade to AST V5.3 or greater");
2943 #else
2944 nin = av_len( in ) + 1;
2945 cin = pack1D(newRV_noinc((SV*)in), 'i');
2946
2947 /* output array */
2948 nout = astGetI( this, "Nout" );
2949 cout = get_mortalspace( nout, 'i' );
2950
2951 ASTCALL(
2952 astMapSplit( this, nin, cin, cout, &outmap );
2953 )
2954
2955 /* Push the results onto the stack */
2956 if (outmap) {
2957 SV * sv = createPerlObject( "AstMappingPtr", (AstObject*)outmap );
2958 XPUSHs(sv_2mortal( sv ));
2959 /* recalculate nout */
2960 nout = astGetI( outmap, "Nout" );
2961 for (i = 0; i < nout; i++) {
2962 XPUSHs( sv_2mortal( newSViv( cout[i] ) ) );
2963 }
2964 } else {
2965 XSRETURN_EMPTY;
2966 }
2967 #endif
2968
2969 # astRate
2970 # Returns the rate and (sometimes) the second derivatives
2971 # Returns empty list if astRate returns AST__BAD
2972
2973 void
2974 astRate( this, at, ax1, ax2 )
2975 AstMapping * this
2976 AV* at
2977 int ax1
2978 int ax2
2979 PREINIT:
2980 int nin;
2981 int len;
2982 double * cat;
2983 double d2;
2984 PPCODE:
2985 #ifndef HASRATE
2986 Perl_croak(aTHX_ "astRate: Please upgrade to AST V3.x or greater");
2987 #else
2988 nin = astGetI( this, "Nin");
2989 len = av_len( at ) + 1;
2990 if (nin != len)
2991 Perl_croak(aTHX_ "Must supply Nin coordinates to astRate [%d != %d]",
2992 nin, len);
2993 cat = pack1D( newRV_noinc((SV*)at), 'd');
2994 myAstRate( this, cat ,ax1, ax2, &d2 );
2995 #endif
2996
2997
2998 # astResample XXXX
2999
3000
3001 AstMapping *
3002 astSimplify( this )
3003 AstMapping * this
3004 CODE:
3005 ASTCALL(
3006 RETVAL = astSimplify( this );
3007 )
3008 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
3009 OUTPUT:
3010 RETVAL
3011
3012 # astTran1
3013 # Returns one array
3014 # Even though we return one array, we use PPCODE so that it is closer to
3015 # the code used for astTran2
3016
3017 void
3018 astTran1( this, xin, forward )
3019 AstMapping * this
3020 AV* xin
3021 bool forward
3022 PREINIT:
3023 int len1;
3024 double * cxin;
3025 AV* xout;
3026 double * cxout;
3027 SV** elem;
3028 PPCODE:
3029 len1 = av_len( xin ) + 1;
3030 cxin = pack1D( newRV_noinc((SV*)xin), 'd');
3031 cxout = get_mortalspace( len1, 'd' );
3032
3033 ASTCALL(
3034 astTran1( this, len1, cxin, forward, cxout );
3035 )
3036
3037 xout = newAV();
3038 unpack1D( newRV_noinc((SV*) xout), cxout, 'd', len1);
3039
3040 XPUSHs( newRV_noinc((SV*) xout ));
3041
3042
3043
3044 # astTran2
3045 # Returns 2 arrays
3046
3047 void
3048 astTran2( this, xin, yin, forward )
3049 AstMapping * this
3050 AV* xin
3051 AV* yin
3052 bool forward
3053 PREINIT:
3054 int len1;
3055 int len2;
3056 double * cxin;
3057 double * cyin;
3058 AV* xout;
3059 AV* yout;
3060 double * cxout;
3061 double * cyout;
3062 SV** elem;
3063 PPCODE:
3064 len1 = av_len( xin ) + 1;
3065 len2 = av_len( yin ) + 1;
3066 if ( len1 != len2 )
3067 Perl_croak(aTHX_ "Number of elements in input arrays must be identical (%d != %d )",
3068 len1, len2);
3069 cxin = pack1D( newRV_noinc((SV*)xin), 'd');
3070 cyin = pack1D( newRV_noinc((SV*)yin), 'd');
3071 cxout = get_mortalspace( len1, 'd' );
3072 cyout = get_mortalspace( len2, 'd' );
3073
3074 ASTCALL(
3075 astTran2( this, len1, cxin, cyin, forward, cxout, cyout );
3076 )
3077
3078 xout = newAV();
3079 yout = newAV();
3080 unpack1D( newRV_noinc((SV*) xout), cxout, 'd', len1);
3081 unpack1D( newRV_noinc((SV*) yout), cyout, 'd', len2);
3082
3083 XPUSHs( newRV_noinc((SV*) xout ));
3084 XPUSHs( newRV_noinc((SV*) yout ));
3085
3086
3087
3088 # astTranN XXXX
3089
3090 # astTranP
3091
3092 # Note that to allow a better perl interface, we put all the array
3093 # arguments at the end and allow an arbitrary number of coordinates
3094 # to be provided without having to use an array of arrays
3095
3096 # To match the interface to astTranP there must be an input array
3097 # per input axis, and each array must contain the same number of elements
3098 # referring to the coordinate for a specific dimension. ie for a 2D coordinate
3099 # you will need just two arrays: the first array has all the X coordinates
3100 # and the second has all the Y coordinates.
3101
3102 # @transformed = $wcs->TranP( 1, [ 1,0 ], [1,-1] ... );
3103
3104 void
3105 astTranP( this, forward, ... )
3106 AstMapping * this
3107 int forward
3108 PREINIT:
3109 int i;
3110 int n;
3111 int argoff = 2; /* number of fixed arguments */
3112 int ndims;
3113 int npoint;
3114 int naxin;
3115 int naxout;
3116 int ncoord_in;
3117 int ncoord_out;
3118 double **ptr_in;
3119 double **ptr_out;
3120 PPCODE:
3121 /* Make sure we have some coordinates to transform */
3122 ndims = items - argoff;
3123 if (ndims > 0) {
3124 /* Number of in and output coordinates required for this mapping */
3125 naxin = astGetI( this, "Nin" );
3126 naxout = astGetI( this, "Nout" );
3127
3128 /* The required dimensionality depends on direction */
3129 if (forward) {
3130 ncoord_in = naxin;
3131 ncoord_out = naxout;
3132 } else {
3133 ncoord_in = naxout;
3134 ncoord_out = naxin;
3135 }
3136
3137 /* Make sure that the number of supplied arguments matches the
3138 number of required input dimensions */
3139 if ( ndims != ncoord_in )
3140 Perl_croak(aTHX_ "Number of input arrays must be identical to the number of coordinates in the input frame (%d != %d )", ndims, ncoord_in);
3141
3142 /* Get some memory for the input and output pointer arrays */
3143 ptr_in = get_mortalspace( ncoord_in, 'v' );
3144 ptr_out = get_mortalspace( ncoord_out, 'v' );
3145
3146 /* Need to get the number of input elements in the first array */
3147 npoint = (int)nelem1D( ST(argoff) );
3148
3149 /* Loop over all the remaining arrays and store them in an array */
3150 for (i = argoff; i<items; i++) {
3151 int count = i - argoff;
3152 /* input coordinates */
3153 ptr_in[count] = pack1D( ST(i), 'd' );
3154
3155 /* Check size */
3156 n = nelem1D( ST(i) );
3157 if (n != npoint)
3158 Perl_croak(aTHX_ "Input array %d has differing number of elements to first array (%d != %d)",
3159 count, n, npoint);
3160
3161 }
3162 /* Allocate memory for the output coordinates */
3163 for (i = 0; i < ncoord_out; i++) {
3164 ptr_out[i] = get_mortalspace( npoint, 'd' );
3165 }
3166
3167 /* Call AST */
3168 ASTCALL (
3169 astTranP( this, npoint, ncoord_in, (const double**)ptr_in, forward, ncoord_out, ptr_out);
3170 )
3171
3172 /* Copy the output to perl */
3173 for (i = 0; i < ncoord_out; i++) {
3174 AV* outarr = newAV();
3175 unpack1D( newRV_noinc((SV*)outarr), ptr_out[i], 'd', npoint);
3176 XPUSHs( newRV_noinc((SV*)outarr) );
3177 }
3178
3179 } else {
3180 /* no input, no output */
3181 XSRETURN_EMPTY;
3182 }
3183
3184 MODULE = Starlink::AST PACKAGE = Starlink::AST::RateMap
3185
3186 AstRateMap *
3187 new( class, map, ax1, ax2, options )
3188 char * class
3189 AstMapping * map
3190 int ax1
3191 int ax2
3192 char * options
3193 CODE:
3194 #ifndef HASRATEMAP
3195 Perl_croak(aTHX_ "astRateMap: Please upgrade to AST V3.5 or newer");
3196 #else
3197 ASTCALL(
3198 RETVAL = astRateMap( map, ax1, ax2, options );
3199 )
3200 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
3201 #endif
3202 OUTPUT:
3203 RETVAL
3204
3205 MODULE = Starlink::AST PACKAGE = Starlink::AST::Channel PREFIX = ast
3206
3207 AstObject *
3208 ast_Read( channel )
3209 AstChannel * channel
3210 CODE:
3211 ASTCALL(
3212 RETVAL = astRead( channel );
3213 )
3214 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
3215 OUTPUT:
3216 RETVAL
3217
3218 int
3219 astWrite( channel, object )
3220 AstChannel * channel
3221 AstObject * object
3222 CODE:
3223 ASTCALL(
3224 RETVAL = astWrite( channel, object );
3225 )
3226 OUTPUT:
3227 RETVAL
3228
3229 MODULE = Starlink::AST PACKAGE = Starlink::AST::Region PREFIX = ast
3230
3231 AstFrame *
3232 astGetRegionFrame( this )
3233 AstRegion * this
3234 CODE:
3235 #ifndef HASREGION
3236 Perl_croak(aTHX_ "astGetRegionFrame: Please upgrade to AST V3.5 or greater");
3237 #else
3238 ASTCALL(
3239 RETVAL = astGetRegionFrame( this );
3240 )
3241 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
3242 #endif
3243 OUTPUT:
3244 RETVAL
3245
3246 AstRegion *
3247 astMapRegion( this, map, frame )
3248 AstRegion * this
3249 AstMapping * map
3250 AstFrame * frame
3251 CODE:
3252 #ifndef HASREGION
3253 Perl_croak(aTHX_ "astMapRegion: Please upgrade to AST V3.5 or greater");
3254 #else
3255 ASTCALL(
3256 RETVAL = astMapRegion( this, map, frame );
3257 )
3258 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
3259 #endif
3260 OUTPUT:
3261 RETVAL
3262
3263 # Takes as input a data array and associated pixel bounds, and returns
3264 # the modified data array and the number of values masked within it.
3265 # Fortran order is assumed. This routine should really be implemented
3266 # using PDLs rather than perl linear arrays
3267 # NOT PROPERLY IMPLEMENTED
3268
3269 void
3270 astMaskD( this, map, inside, lbnd, ubnd, in, val)
3271 AstRegion * this
3272 AstMapping * map
3273 bool inside
3274 AV * lbnd
3275 AV * ubnd
3276 AV * in
3277 double val
3278 PREINIT:
3279 int len;
3280 int ndims;
3281 int * clbnd;
3282 int * cubnd;
3283 double * cin;
3284 int nelem;
3285 int i;
3286 AV * output;
3287 int nmasked;
3288 PPCODE:
3289 #ifndef HASREGION
3290 Perl_croak(aTHX_ "astNegate: Please upgrade to AST V3.5 or greater");
3291 #else
3292 ndims = astGetI( map, "Nout" );
3293 len = av_len( lbnd ) + 1;
3294 if ( len != ndims ) Perl_croak( aTHX_ "lbnd must contain %d elements", ndims );
3295 len = av_len( ubnd ) + 1;
3296 if ( len != ndims ) Perl_croak( aTHX_ "ubnd must contain %d elements", ndims );
3297 clbnd = pack1D(newRV_noinc((SV*)lbnd), 'd');
3298 cubnd = pack1D(newRV_noinc((SV*)ubnd), 'd');
3299 cin = pack1D( newRV_noinc((SV*)in), 'd' );
3300 ASTCALL(
3301 nmasked = astMaskD( this, map, inside, ndims, clbnd, cubnd, cin, val);
3302 )
3303 /* but now need to unroll the data array into a perl array */
3304 nelem = cubnd[0] - clbnd[0];
3305 for ( i=1; i < ndims; i++ ) {
3306 nelem *= ( cubnd[i] - clbnd[i] );
3307 }
3308 output = newAV();
3309 unpack1D( newRV_noinc((SV*) output), cin, 'd', nelem);
3310 XPUSHs( newRV_noinc((SV*)output));
3311 XPUSHs( sv_2mortal(newSVnv(nmasked)));
3312 #endif
3313
3314 void
3315 astNegate( this )
3316 AstRegion * this
3317 CODE:
3318 #ifndef HASREGION
3319 Perl_croak(aTHX_ "astNegate: Please upgrade to AST V3.5 or greater");
3320 #else
3321 ASTCALL(
3322 astNegate( this );
3323 )
3324 #endif
3325
3326 int
3327 astOverlap( this, that )
3328 AstRegion * this
3329 AstRegion * that
3330 CODE:
3331 #ifndef HASREGION
3332 Perl_croak(aTHX_ "astOverlap: Please upgrade to AST V3.5 or greater");
3333 #else
3334 ASTCALL(
3335 RETVAL = astOverlap( this, that );
3336 )
3337 #endif
3338 OUTPUT:
3339 RETVAL
3340
3341 void
3342 astSetUnc( this, unc )
3343 AstRegion * this
3344 AstRegion * unc
3345 CODE:
3346 #ifndef HASREGION
3347 Perl_croak(aTHX_ "astSetUnc: Please upgrade to AST V3.5 or greater");
3348 #else
3349 ASTCALL(
3350 astSetUnc( this, unc );
3351 )
3352 #endif
3353
3354 # astGetRegionBounds
3355 # (\@lbnd, \@ubnd) = $region->GetRegionBounds();
3356
3357 void
3358 astGetRegionBounds( this )
3359 AstRegion * this
3360 PREINIT:
3361 int naxes;
3362 int i;
3363 double * clbnd;
3364 double * cubnd;
3365 AV * lbnd;
3366 AV * ubnd;
3367 PPCODE:
3368 #ifndef HASREGION
3369 Perl_croak(aTHX_ "astGetRegionBounds: Please upgrade to AST V3.5 or greater");
3370 #else
3371 naxes = astGetI( this, "Naxes" );
3372 clbnd = get_mortalspace( naxes, 'd' );
3373 cubnd = get_mortalspace( naxes, 'd' );
3374
3375 ASTCALL(
3376 astGetRegionBounds( this, clbnd, cubnd );
3377 )
3378
3379 lbnd = newAV();
3380 ubnd = newAV();
3381 unpack1D( newRV_noinc((SV*) lbnd), clbnd, 'd', naxes );
3382 unpack1D( newRV_noinc((SV*) ubnd), cubnd, 'd', naxes );
3383
3384 XPUSHs(newRV_noinc((SV*) lbnd));
3385 XPUSHs(newRV_noinc((SV*) ubnd));
3386 #endif
3387
3388 MODULE = Starlink::AST PACKAGE = Starlink::AST::Ellipse
3389
3390 AstEllipse *
3391 new( class, frame, form, centre, point1, point2, unc, options)
3392 char * class
3393 AstFrame * frame
3394 int form
3395 AV * centre
3396 AV * point1
3397 AV * point2
3398 AstRegion * unc
3399 char * options
3400 PREINIT:
3401 int naxes = 2;
3402 int len;
3403 int nreq;
3404 double * ccentre;
3405 double * cpoint1;
3406 double * cpoint2;
3407 CODE:
3408 #ifndef HASREGION
3409 Perl_croak(aTHX_ "astEllipse: Please upgrade to AST V3.5 or greater");
3410 #else
3411 len = av_len( centre ) + 1;
3412 if ( len != naxes ) Perl_croak( aTHX_ "centre must contain %d elements", naxes );
3413 len = av_len( point1 ) + 1;
3414 if ( len != 2 ) Perl_croak( aTHX_ "point1 must contain %d elements", 2 );
3415 len = av_len( point2 ) + 1;
3416 if (form == 0) {
3417 nreq = naxes;
3418 } else {
3419 nreq = 1;
3420 }
3421 if ( len != nreq ) Perl_croak( aTHX_ "point2 must contain %d elements not %d", nreq, len );
3422 ccentre = pack1D(newRV_noinc((SV*)centre), 'd');
3423 cpoint1 = pack1D(newRV_noinc((SV*)point1), 'd');
3424 cpoint2 = pack1D(newRV_noinc((SV*)point2), 'd');
3425 ASTCALL(
3426 RETVAL = astEllipse( frame, form, ccentre, cpoint1, cpoint2, unc, options);
3427 )
3428 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
3429 #endif
3430 OUTPUT:
3431 RETVAL
3432
3433
3434 MODULE = Starlink::AST PACKAGE = Starlink::AST::Box
3435
3436 AstBox *
3437 new( class, frame, form, point1, point2, unc, options )
3438 char * class
3439 AstFrame * frame
3440 int form
3441 AV * point1
3442 AV * point2
3443 AstRegion * unc
3444 char * options
3445 PREINIT:
3446 double * cpoint2;
3447 double * cpoint1;
3448 int len;
3449 int naxes;
3450 CODE:
3451 #ifndef HASREGION
3452 Perl_croak(aTHX_ "astBox: Please upgrade to AST V3.5 or greater");
3453 #else
3454 naxes = astGetI( frame, "Naxes" );
3455 len = av_len( point1 ) + 1;
3456 if ( len != naxes ) Perl_croak( aTHX_ "point1 must contain %d elements", naxes );
3457 len = av_len( point2 ) + 1;
3458 if ( len != naxes ) Perl_croak( aTHX_ "point2 must contain %d elements", naxes );
3459 cpoint1 = pack1D(newRV_noinc((SV*)point1), 'd');
3460 cpoint2 = pack1D(newRV_noinc((SV*)point2), 'd');
3461 ASTCALL(
3462 RETVAL = astBox( frame, form, cpoint1, cpoint2, unc, options);
3463 )
3464 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
3465 #endif
3466 OUTPUT:
3467 RETVAL
3468
3469 MODULE = Starlink::AST PACKAGE = Starlink::AST::Interval
3470
3471 AstInterval *
3472 new( class, frame, lbnd, ubnd, unc, options )
3473 char * class
3474 AstFrame * frame
3475 AV * lbnd
3476 AV * ubnd
3477 AstRegion * unc
3478 char * options
3479 PREINIT:
3480 double * clbnd;
3481 double * cubnd;
3482 int len;
3483 int naxes;
3484 CODE:
3485 #ifndef HASREGION
3486 Perl_croak(aTHX_ "astInterval: Please upgrade to AST V3.5 or greater");
3487 #else
3488 naxes = astGetI( frame, "Naxes" );
3489 len = av_len( lbnd ) + 1;
3490 if ( len != naxes ) Perl_croak( aTHX_ "lbnd must contain %d elements", naxes );
3491 len = av_len( ubnd ) + 1;
3492 if ( len != naxes ) Perl_croak( aTHX_ "ubnd must contain %d elements", naxes );
3493 clbnd = pack1D(newRV_noinc((SV*)lbnd), 'd');
3494 cubnd = pack1D(newRV_noinc((SV*)ubnd), 'd');
3495 ASTCALL(
3496 RETVAL = astInterval( frame, clbnd, cubnd, unc, options);
3497 )
3498 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
3499 #endif
3500 OUTPUT:
3501 RETVAL
3502
3503 MODULE = Starlink::AST PACKAGE = Starlink::AST::Polygon
3504
3505 # Note that the interface differs to the low level routine
3506
3507 AstPolygon *
3508 new( class, frame, xpoints, ypoints, unc, options )
3509 char * class
3510 AstFrame * frame
3511 AV * xpoints
3512 AV * ypoints
3513 AstRegion * unc
3514 char * options
3515 PREINIT:
3516 int i;
3517 int xlen;
3518 int ylen;
3519 double * points;
3520 double * cxpoints;
3521 double * cypoints;
3522 double * x;
3523 double * y;
3524 CODE:
3525 #ifndef HASREGION
3526 Perl_croak(aTHX_ "astPolygon: Please upgrade to AST V3.5 or greater");
3527 #else
3528 /* count elements */
3529 xlen = av_len( xpoints ) + 1;
3530 ylen = av_len( ypoints ) + 1;
3531 if ( xlen != ylen ) Perl_croak( aTHX_ "number of x and y points differ (%d != %d)",
3532 xlen, ylen );
3533 cxpoints = pack1D(newRV_noinc((SV*)xpoints), 'd');
3534 cypoints = pack1D(newRV_noinc((SV*)ypoints), 'd');
3535
3536 /* Create memory for the array as required by AST */
3537 points = get_mortalspace( xlen * 2, 'd');
3538
3539 /* copy points in */
3540 x = points;
3541 y = points + xlen; /* offset into the array */
3542 for (i = 0; i < xlen; i++ ) {
3543 x[i] = cxpoints[i];
3544 y[i] = cypoints[i];
3545 }
3546
3547 ASTCALL(
3548 RETVAL = astPolygon(frame, xlen, xlen, points, unc, options );
3549 )
3550 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
3551 #endif
3552 OUTPUT:
3553 RETVAL
3554
3555 MODULE = Starlink::AST PACKAGE = Starlink::AST::NullRegion
3556
3557 AstNullRegion *
3558 new( class, frame, unc, options )
3559 char * class
3560 AstFrame * frame
3561 AstRegion * unc
3562 char * options
3563 CODE:
3564 #ifndef HASREGION
3565 Perl_croak(aTHX_ "astNullRegion: Please upgrade to AST V3.5 or greater");
3566 #else
3567 ASTCALL(
3568 RETVAL = astNullRegion( frame, unc, options);
3569 )
3570 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
3571 #endif
3572 OUTPUT:
3573 RETVAL
3574
3575 MODULE = Starlink::AST PACKAGE = Starlink::AST::Region PREFIX = ast
3576
3577 # Note that we are trying to make this a method in the Region base class
3578 # so that all regions can be converted into CmpRegions
3579
3580 AstCmpRegion *
3581 astCmpRegion( region1, region2, oper, options )
3582 AstRegion * region1
3583 AstRegion * region2
3584 int oper
3585 char * options
3586 CODE:
3587 #ifndef HASREGION
3588 Perl_croak(aTHX_ "astCmpRegion: Please upgrade to AST V3.5 or greater");
3589 #else
3590 ASTCALL(
3591 RETVAL = astCmpRegion( region1, region2, oper, options);
3592 )
3593 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
3594 #endif
3595 OUTPUT:
3596 RETVAL
3597
3598 int
3599 AST__AND()
3600 CODE:
3601 #ifdef AST__AND
3602 RETVAL = AST__AND;
3603 #else
3604 Perl_croak(aTHX_ "Constant AST__AND not defined\n");
3605 #endif
3606 OUTPUT:
3607 RETVAL
3608
3609 int
3610 AST__OR()
3611 CODE:
3612 #ifdef AST__OR
3613 RETVAL = AST__OR;
3614 #else
3615 Perl_croak(aTHX_ "Constant AST__OR not defined\n");
3616 #endif
3617 OUTPUT:
3618 RETVAL
3619
3620
3621
3622 MODULE = Starlink::AST PACKAGE = Starlink::AST::Circle
3623
3624 AstCircle *
3625 new( class, frame, form, centre, point, unc, options )
3626 char * class
3627 AstFrame * frame
3628 int form
3629 AV * centre
3630 AV * point
3631 AstRegion * unc
3632 char * options
3633 PREINIT:
3634 double * ccentre;
3635 double * cpoint;
3636 int len;
3637 int naxes;
3638 int nform;
3639 CODE:
3640 #ifndef HASREGION
3641 Perl_croak(aTHX_ "astCircle: Please upgrade to AST V3.5 or greater");
3642 #else
3643 naxes = astGetI( frame, "Naxes" );
3644 len = av_len( centre ) + 1;
3645 if ( len != naxes ) Perl_croak( aTHX_ "point1 must contain %d elements", naxes );
3646 /* point depends on form */
3647 len = av_len( point ) + 1;
3648 if (form == 0) {
3649 nform = naxes;
3650 } else {
3651 nform = 1;
3652 }
3653 if ( len != nform ) Perl_croak( aTHX_ "point() must contain %d elements", nform );
3654 ccentre = pack1D(newRV_noinc((SV*)centre), 'd');
3655 cpoint = pack1D(newRV_noinc((SV*)point), 'd');
3656 ASTCALL(
3657 RETVAL = astCircle( frame, form, ccentre, cpoint, unc, options);
3658 )
3659 if ( RETVAL == AST__NULL ) XSRETURN_UNDEF;
3660 #endif
3661 OUTPUT:
3662 RETVAL
3663
3664
3665 MODULE = Starlink::AST PACKAGE = Starlink::AST::FitsChan PREFIX = ast
3666
3667 void
3668 astPutCards( this, cards )
3669 AstFitsChan * this
3670 char * cards
3671 CODE:
3672 #ifndef HASPUTCARDS
3673 Perl_croak(aTHX_ "astPutCards: Please upgrade to AST V3.2 or greater");
3674 #else
3675 ASTCALL(
3676 astPutCards( this, cards );
3677 )
3678 #endif
3679
3680 void
3681 astPutFits( this, card, overwrite )
3682 AstFitsChan * this
3683 char * card
3684 int overwrite
3685 CODE:
3686 ASTCALL(
3687 astPutFits(this, card, overwrite);
3688 )
3689
3690 void
3691 astDelFits( this )
3692 AstFitsChan * this
3693 CODE:
3694 ASTCALL(
3695 astDelFits( this );
3696 )
3697
3698 # Need to handle a NULL card - XXXXX
3699
3700 int
3701 astFindFits( this, name, card, inc )
3702 AstFitsChan * this
3703 char * name
3704 char * card = NO_INIT
3705 int inc
3706 PREINIT:
3707 char buff[81];
3708 CODE:
3709 card = buff;
3710 ASTCALL(
3711 RETVAL = astFindFits( this, name, card, inc );
3712 )
3713 OUTPUT:
3714 RETVAL
3715 card
3716
3717 void
3718 astSetFitsCF( this, name, real, imag, comment, overwrite )
3719 AstFitsChan * this
3720 char * name
3721 double real
3722 double imag
3723 char * comment
3724 int overwrite
3725 PREINIT:
3726 double value[2];
3727 CODE:
3728 #ifndef HASSETFITS
3729 Perl_croak(aTHX_ "astSetFitsX: Please upgrade to AST v3.5 or newer");
3730 #else
3731 value[0] = real;
3732 value[1] = imag;
3733 ASTCALL(
3734 astSetFitsCF( this, name, value, comment, overwrite );
3735 )
3736 #endif
3737
3738 void
3739 astSetFitsCI( this, name, real, imag, comment, overwrite )
3740 AstFitsChan * this
3741 char * name
3742 int real
3743 int imag
3744 char * comment
3745 int overwrite
3746 PREINIT:
3747 int value[2];
3748 CODE:
3749 #ifndef HASSETFITS
3750 Perl_croak(aTHX_ "astSetFitsX: Please upgrade to AST v3.5 or newer");
3751 #else
3752 value[0] = real;
3753 value[1] = imag;
3754 ASTCALL(
3755 astSetFitsCI( this, name, value, comment, overwrite );
3756 )
3757 #endif
3758
3759
3760 void
3761 astSetFitsF( this, name, value, comment, overwrite )
3762 AstFitsChan * this
3763 char * name
3764 double value
3765 char * comment
3766 int overwrite
3767 CODE:
3768 #ifndef HASSETFITS
3769 Perl_croak(aTHX_ "astSetFitsX: Please upgrade to AST v3.5 or newer");
3770 #else
3771 ASTCALL(
3772 astSetFitsF( this, name, value, comment, overwrite );
3773 )
3774 #endif
3775
3776 void
3777 astSetFitsI( this, name, value, comment, overwrite )
3778 AstFitsChan * this
3779 char * name
3780 int value
3781 char * comment
3782 int overwrite
3783 CODE:
3784 #ifndef HASSETFITS
3785 Perl_croak(aTHX_ "astSetFitsX: Please upgrade to AST v3.5 or newer");
3786 #else
3787 ASTCALL(
3788 astSetFitsI( this, name, value, comment, overwrite );
3789 )
3790 #endif
3791
3792 void
3793 astSetFitsL( this, name, value, comment, overwrite )
3794 AstFitsChan * this
3795 char * name
3796 bool value
3797 char * comment
3798 int overwrite
3799 PREINIT:
3800 int bval;
3801 CODE:
3802 #ifndef HASSETFITS
3803 Perl_croak(aTHX_ "astSetFitsX: Please upgrade to AST v3.5 or newer");
3804 #else
3805 bval = ( value ? 1 : 0);
3806 ASTCALL(
3807 astSetFitsL( this, name, bval, comment, overwrite );
3808 )
3809 #endif
3810
3811 void
3812 astSetFitsS( this, name, value, comment, overwrite )
3813 AstFitsChan * this
3814 char * name
3815 char * value
3816 char * comment
3817 int overwrite
3818 CODE:
3819 #ifndef HASSETFITS
3820 Perl_croak(aTHX_ "astSetFitsX: Please upgrade to AST v3.5 or newer");
3821 #else
3822 ASTCALL(
3823 astSetFitsS( this, name, value, comment, overwrite );
3824 )
3825 #endif
3826
3827 void
3828 astSetFitsCN( this, name, value, comment, overwrite )
3829 AstFitsChan * this
3830 char * name
3831 char * value
3832 char * comment
3833 int overwrite
3834 CODE:
3835 #ifndef HASSETFITS
3836 Perl_croak(aTHX_ "astSetFitsX: Please upgrade to AST v3.5 or newer");
3837 #else
3838 ASTCALL(
3839 astSetFitsCN( this, name, value, comment, overwrite );
3840 )
3841 #endif
3842
3843 MODULE = Starlink::AST PACKAGE = Starlink::AST::SpecFrame PREFIX = ast
3844
3845 void
3846 astSetRefPos( this, frm, lon, lat)
3847 AstSpecFrame * this
3848 AstSkyFrame * frm
3849 double lon
3850 double lat
3851 CODE:
3852 #ifndef HASSETREFPOS
3853 Perl_croak(aTHX_ "astSetRefPos: Please upgrade to AST v2.x or newer");
3854 #else
3855 ASTCALL(
3856 astSetRefPos( this, frm, lon, lat );
3857 )
3858 #endif
3859
3860 # XXX frm is allowed to be null here
3861
3862 void
3863 astGetRefPos( this, frm )
3864 AstSpecFrame * this
3865 AstSkyFrame * frm
3866 PREINIT:
3867 double lon;
3868 double lat;
3869 PPCODE:
3870 #ifndef HASGETREFPOS
3871 Perl_croak(aTHX_ "astGetRefPos: Please upgrade to AST v2.x or newer");
3872 #else
3873 ASTCALL(
3874 astGetRefPos( this, frm, &lon, &lat );
3875 )
3876 XPUSHs(sv_2mortal(newSVnv(lon)));
3877 XPUSHs(sv_2mortal(newSVnv(lat)));
3878 #endif
3879
3880 MODULE = Starlink::AST PACKAGE = Starlink::AST::SlaMap PREFIX = astSla
3881
3882 void
3883 astSlaAdd( this, cvt, args )
3884 AstSlaMap * this
3885 char * cvt
3886 AV* args
3887 PREINIT:
3888 double * cargs;
3889 CODE:
3890 cargs = pack1D(newRV_noinc((SV*)args), 'd');
3891 ASTCALL(
3892 astSlaAdd( this, cvt, cargs );
3893 )
3894
3895 MODULE = Starlink::AST PACKAGE = Starlink::AST::SpecMap PREFIX = astSpec
3896
3897 void
3898 astSpecAdd( this, cvt, args )
3899 AstSpecMap * this
3900 char * cvt
3901 AV* args
3902 PREINIT:
3903 double * cargs;
3904 CODE:
3905 cargs = pack1D(newRV_noinc((SV*)args), 'd');
3906 #ifndef HASSPECADD
3907 Perl_croak(aTHX_ "astSpecAdd: Please upgrade to AST v2.x or newer");
3908 #else
3909 ASTCALL(
3910 astSpecAdd( this, cvt, cargs );
3911 )
3912 #endif
3913
3914 MODULE = Starlink::AST PACKAGE = Starlink::AST::Plot PREFIX = ast
3915
3916 void
3917 astBorder( this )
3918 AstPlot * this
3919 PREINIT:
3920 SV* arg = ST(0);
3921 CODE:
3922 PLOTCALL(arg,
3923 astBorder(this);
3924 )
3925
3926 void
3927 astBoundingBox( this )
3928 AstPlot * this
3929 PREINIT:
3930 float clbnd[2];
3931 float cubnd[2];
3932 AV* lbnd;
3933 AV* ubnd;
3934 SV * arg = ST(0);
3935 PPCODE:
3936 PLOTCALL (arg,
3937 astBoundingBox( this, clbnd, cubnd );
3938 )
3939 lbnd = newAV();
3940 unpack1D( newRV_noinc((SV*) lbnd), clbnd, 'f', 2 );
3941 ubnd = newAV();
3942 unpack1D( newRV_noinc((SV*) ubnd), cubnd, 'f', 2 );
3943 XPUSHs(newRV_noinc((SV*)lbnd ));
3944 XPUSHs(newRV_noinc((SV*)ubnd ));
3945
3946
3947 void
3948 astClip( this, iframe, lbnd, ubnd )
3949 AstPlot * this
3950 int iframe
3951 AV* lbnd
3952 AV* ubnd
3953 PREINIT:
3954 int len;
3955 double * clbnd;
3956 double * cubnd;
3957 int naxes;
3958 SV * arg = ST(0);
3959 CODE:
3960 naxes = astGetI( this, "Naxes" );
3961 len = av_len( lbnd ) + 1;
3962 if ( len != naxes ) Perl_croak( aTHX_ "lbnd must contain %d elements", naxes );
3963 len = av_len( ubnd ) + 1;
3964 if ( len != naxes ) Perl_croak( aTHX_ "ubnd must contain %d elements", naxes );
3965 clbnd = pack1D(newRV_noinc((SV*)lbnd), 'd');
3966 cubnd = pack1D(newRV_noinc((SV*)ubnd), 'd');
3967 PLOTCALL (arg,
3968 astClip( this, iframe, clbnd, cubnd );
3969 )
3970
3971 void
3972 astCurve( this, start, finish )
3973 AstPlot * this
3974 AV* start
3975 AV* finish
3976 PREINIT:
3977 int len;
3978 double * cstart;
3979 double * cfinish;
3980 int naxes;
3981 SV* arg = ST(0);
3982 CODE:
3983 naxes = astGetI(this, "Naxes" );
3984 len = av_len( start ) + 1;
3985 if ( len != naxes ) Perl_croak( aTHX_ "start must contain %d elements", naxes );
3986 len = av_len( finish ) + 1;
3987 if ( len != naxes ) Perl_croak( aTHX_ "finish must contain %d elements", naxes);
3988 cstart = pack1D(newRV_noinc((SV*)start), 'd');
3989 cfinish = pack1D(newRV_noinc((SV*)finish), 'd');
3990 PLOTCALL (arg,
3991 astCurve( this, cstart, cfinish );
3992 )
3993
3994 void
3995 astGenCurve( this, map )
3996 AstPlot * this
3997 AstMapping * map
3998 PREINIT:
3999 SV * arg = ST(0);
4000 CODE:
4001 PLOTCALL(arg,
4002 astGenCurve(this, map);
4003 )
4004
4005 void
4006 astGrid( this )
4007 AstPlot * this
4008 PREINIT:
4009 SV * arg = ST(0);
4010 CODE:
4011 PLOTCALL(arg,
4012 astGrid(this);
4013 )
4014
4015 void
4016 astGridLine( this, axis, start, length )
4017 AstPlot * this
4018 int axis
4019 AV* start
4020 double length
4021 PREINIT:
4022 double * cstart;
4023 int naxes;
4024 int len;
4025 SV * arg = ST(0);
4026 CODE:
4027 naxes = astGetI( this, "Naxes" );
4028 len = av_len( start ) + 1;
4029 if ( len != naxes ) Perl_croak( aTHX_ "start must contain %d elements", naxes );
4030 cstart = pack1D(newRV_noinc((SV*)start), 'd');
4031 PLOTCALL(arg,
4032 astGridLine( this, axis, cstart, length );
4033 )
4034
4035 # Make this a little different to the published interface
4036 # By requesting @x and @y rather than an array of coordinate doublets.
4037
4038 void
4039 astMark(this, type, ...)
4040 AstPlot * this
4041 int type
4042 PREINIT:
4043 double * cin;
4044 int ncoords;
4045 int nmarks = 0;
4046 int indim;
4047 int size;
4048 int i;
4049 int total;
4050 int argoff = 2; /* number of fixed arguments */
4051 int naxes;
4052 SV * arg = ST(0);
4053 CODE:
4054 /* First make sure we have some arguments */
4055 if (items > argoff ) {
4056 /* Number of dimensions should be just the number of stack items */
4057 ncoords = items - argoff;
4058
4059 /* and this should equal the number of axes in the frame */
4060 naxes = astGetI( this, "Naxes" );
4061
4062 if ( naxes != ncoords )
4063 Perl_croak(aTHX_ "Number of supplied coordinate sets must equal number of axes in frame [%d != %d]",naxes,ncoords);
4064
4065 /* Now go through each finding out how long each array is */
4066 for (i = argoff + 1; i<=items; i++ ) {
4067 int nelem;
4068 int index = i - 1;
4069 SV * coordsv = ST(index);
4070 AV * curr;
4071 if (SvROK(coordsv) && SvTYPE(SvRV(coordsv)) == SVt_PVAV) {
4072 curr = (AV*)SvRV( coordsv );
4073 nelem = av_len( curr ) + 1;
4074 if (i == argoff + 1) {
4075 /* No previous values */
4076 nmarks = nelem;
4077 } else if (nmarks != nelem) {
4078 Perl_croak(aTHX_ "All coordinates must have same number of elements [%d != %d]",nmarks, nelem);
4079 }
4080 } else {
4081 Perl_croak(aTHX_ "Argument %d to Mark() must be ref to array",i);
4082 }
4083 }
4084
4085 /* Get some memory for the array */
4086 total = nmarks * ncoords;
4087 cin = get_mortalspace( total, 'd');
4088
4089 /* and go through the arrays again (but less checking now) */
4090 for (i = 0; i < ncoords; i++ ) {
4091 int j;
4092 int argpos = i + argoff;
4093 AV * curr = (AV*)SvRV( ST(argpos) );
4094
4095 for (j = 0; j < nmarks ; j ++ ) {
4096 SV ** elem = av_fetch( curr, j, 0);
4097 double dtmp;
4098 if (elem == NULL ) {
4099 /* undef */
4100 dtmp = 0.0;
4101 } else {
4102 dtmp = SvNV( *elem );
4103 }
4104 /* use pointer arithmetic to make sure that things align
4105 the way AST expects */
4106 *(cin + (i * nmarks) + j) = dtmp;
4107 }
4108 }
4109
4110 /* Now call the AST routine */
4111 PLOTCALL( arg,
4112 astMark( this, nmarks, ncoords, nmarks, cin, type );
4113 )
4114
4115 } else {
4116 XSRETURN_EMPTY;
4117 }
4118
4119 # Make this a little different to the published interface
4120 # By requesting @x and @y rather than an array of coordinate doublets.
4121 # [code identical to astMark without the type]
4122
4123 void
4124 astPolyCurve(this, ...)
4125 AstPlot * this
4126 PREINIT:
4127 double * cin;
4128 int ncoords;
4129 int npoints = 0;
4130 int indim;
4131 int size;
4132 int i;
4133 int total;
4134 int argoff = 1; /* number of fixed arguments */
4135 int naxes;
4136 SV * arg = ST(0);
4137 CODE:
4138 /* First make sure we have some arguments */
4139 if (items > argoff ) {
4140 /* Number of dimensions should be just the number of stack items */
4141 ncoords = items - argoff;
4142
4143 /* and this should equal the number of axes in the frame */
4144 naxes = astGetI( this, "Naxes" );
4145
4146 if ( naxes != ncoords )
4147 Perl_croak(aTHX_ "Number of supplied coordinate sets must equal number of axes in frame [%d != %d]",naxes,ncoords);
4148
4149 /* Now go through each finding out how long each array is */
4150 for (i = argoff + 1; i<=items; i++ ) {
4151 int nelem;
4152 int index = i - 1;
4153 SV * coordsv = ST(index);
4154 AV * curr;
4155 if (SvROK(coordsv) && SvTYPE(SvRV(coordsv)) == SVt_PVAV) {
4156 curr = (AV*)SvRV( coordsv );
4157 nelem = av_len( curr ) + 1;
4158 if (i == argoff + 1) {
4159 /* No previous values */
4160 npoints = nelem;
4161 } else if (npoints != nelem) {
4162 Perl_croak(aTHX_ "All coordinates must have same number of elements [%d != %d]",npoints, nelem);
4163 }
4164 } else {
4165 Perl_croak(aTHX_ "Argument %d to Mark() must be ref to array",i);
4166 }
4167 }
4168
4169 /* Get some memory for the array */
4170 total = npoints * ncoords;
4171 cin = get_mortalspace( total, 'd');
4172
4173 /* and go through the arrays again (but less checking now) */
4174 for (i = 0; i < ncoords; i++ ) {
4175 int j;
4176 int argpos = i + argoff;
4177 AV * curr = (AV*)SvRV( ST(argpos) );
4178
4179 for (j = 0; j < npoints ; j ++ ) {
4180 SV ** elem = av_fetch( curr, j, 0);
4181 double dtmp;
4182 if (elem == NULL ) {
4183 /* undef */
4184 dtmp = 0.0;
4185 } else {
4186 dtmp = SvNV( *elem );
4187 }
4188 /* use pointer arithmetic to make sure that things align
4189 the way AST expects */
4190 *(cin + (i * npoints) + j) = dtmp;
4191 }
4192 }
4193
4194 /* Now call the AST routine */
4195 PLOTCALL( arg,
4196 astPolyCurve( this, npoints, ncoords, npoints, cin );
4197 )
4198
4199 } else {
4200 XSRETURN_EMPTY;
4201 }
4202
4203 void
4204 astText( this, text, pos, up, just )
4205 AstPlot * this
4206 char * text
4207 AV* pos
4208 AV* up
4209 char * just
4210 PREINIT:
4211 int len;
4212 float * cup;
4213 double * cpos;
4214 int naxes;
4215 SV * arg = ST(0);
4216 CODE:
4217 naxes = astGetI( this, "Naxes" );
4218 len = av_len( pos ) + 1;
4219 if ( len != naxes ) Perl_croak( aTHX_ "pos must contain %d elements", naxes);
4220 len = av_len( up ) + 1;
4221 if ( len != 2 ) Perl_croak( aTHX_ "up must contain 2 elements");
4222 cpos = pack1D(newRV_noinc((SV*)pos), 'd');
4223 cup = pack1D(newRV_noinc((SV*)up), 'f');
4224 PLOTCALL(arg,
4225 astText( this, text, cpos, cup, just );
4226 )
4227
4228
4229 # Constants
4230
4231 # Start with errors. Bless them into class Starlink::AST::Status
4232
4233 INCLUDE: AST_ERR.xsh
4234
4235 # Then the WcsMap constants
4236
4237 INCLUDE: AST_WCSMAP.xsh
4238
4239 # Then the Grf constants
4240
4241 INCLUDE: AST_GRF.xsh
4242