-
Notifications
You must be signed in to change notification settings - Fork 59
/
cmpmap.c
4690 lines (3927 loc) · 171 KB
/
cmpmap.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
*class++
* Name:
* CmpMap
* Purpose:
* Compound Mapping.
* Constructor Function:
c astCmpMap
f AST_CMPMAP
* Description:
* A CmpMap is a compound Mapping which allows two component
* Mappings (of any class) to be connected together to form a more
* complex Mapping. This connection may either be "in series"
* (where the first Mapping is used to transform the coordinates of
* each point and the second mapping is then applied to the
* result), or "in parallel" (where one Mapping transforms the
* earlier coordinates for each point and the second Mapping
* simultaneously transforms the later coordinates).
*
* Since a CmpMap is itself a Mapping, it can be used as a
* component in forming further CmpMaps. Mappings of arbitrary
* complexity may be built from simple individual Mappings in this
* way.
* Inheritance:
* The CmpMap class inherits from the Mapping class.
* Attributes:
* The CmpMap class does not define any new attributes beyond those
* which are applicable to all Mappings.
* Functions:
c The CmpMap class does not define any new functions beyond those
f The CmpMap class does not define any new routines beyond those
* which are applicable to all Mappings.
* Copyright:
* Copyright (C) 1997-2006 Council for the Central Laboratory of the
* Research Councils
* Licence:
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licence as
* published by the Free Software Foundation; either version 2 of
* the Licence, or (at your option) any later version.
*
* This program is distributed in the hope that it will be
* useful,but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public Licence for more details.
*
* You should have received a copy of the GNU General Public Licence
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street,Fifth Floor, Boston, MA
* 02110-1301, USA
* Authors:
* RFWS: R.F. Warren-Smith (Starlink)
* History:
* 1-FEB-1996 (RFWS):
* Original version.
* 25-SEP-1996 (RFWS):
* Implemented external interface and I/O facilities.
* 12-DEC-1996 (RFWS):
* Over-ride the astMapList method.
* 13-DEC-1996 (RFWS):
* Over-ride the astSimplify method.
* 4-JUN-1997 (RFWS):
* Eliminate any simplification when MapList is used. Instead,
* over-ride the MapMerge method and implement all
* simplification in this.
* 24-MAR-1998 (RFWS):
* Fixed bug in testing of simplified invert flag in Simplify.
* 15-APR-1998 (RFWS):
* Improved the MapMerge method to allow parallel combinations
* of series CmpMaps to be replaced by series combinations of
* parallel CmpMaps, and vice versa.
* 26-SEP-2001 (DSB):
* Over-ride the astDecompose method.
* 8-JAN-2003 (DSB):
* - Changed private InitVtab method to protected astInitCmpMapVtab
* method.
* 8-JAN-2003 (DSB):
* - Modified MapMerge so that a parallel CmpMap can swap with a
* suitable PermMap lower neighbour.
* 23-APR-2004 (DSB):
* - Modified Simplify to avoid infinite loops.
* 27-APR-2004 (DSB):
* - Correction to MapMerge to prevent segvio if CmpMap and PermMap
* cannot be swapped.
* 4-OCT-2004 (DSB):
* Modify astMapList to return flag indicating presence of inverted
* CmpMaps in supplied Mapping.
* 20-APR-2005 (DSB):
* Modify MapMerge so that it will attempt to merge the first
* and second CmpMaps in a list of series CmpMaps.
* 8-FEB-2006 (DSB):
* Corrected logic within MapMerge for cases where a PermMap is
* followed by a parallel CmpMap.
* 14-FEB-2006 (DSB):
* Override astGetObjSize.
* 14-MAR-2006 (DSB):
* - When checking for patterns in the simplification process,
* require at least 30 samples in the waveform for evidence of a
* pattern.
* - Override astEqual.
* - The constructor no longer reports an error if the resulting
* CmpMap cannot transform points in either direction. This is
* because it may be possible to simplify such a CmpMap and the
* simplified Mapping may have defined transformations. E.g. if a
* Mapping which has only a forward transformation is combined in
* series with its own inverse, the combination will simplify to a
* UnitMap (usually).
* 9-MAY-2006 (DSB):
* - In Simplify, remove checks for patterns in the number of atomic
* mappings when calling astSimplify recursively.
* 23-AUG-2006 (DSB):
* - In Simplify, add checks for re-appearance of a Mapping that is
* already being simplified at a higher levelin the call stack.
* 18-APR-2007 (DSB):
* In Simplify: if the returned Mapping is not a CmpMap, always copy
* the returned component Mapping (rather than cloning it) so that
* the returned Mapping is not affected if user code subsequently
* inverts the component Mapping via some other pointer.
* 12-MAR-2008 (DSB):
* Modify MapSplit so that attempts to split the inverse
* transformation if it cannot split the forward transformation.
* 30-JUL-2009 (DSB):
* Ensure the PermMap has equal number of inputs and outputs when
* swapping a PermMap and a CmpMap in astMapMerge.
* 3-JAN-2011 (DSB):
* In MapSplit, certain classes of Mapping (e.g. PermMaps) can
* produce a returned Mapping with zero outputs. Consider such
* Mappings to be unsplitable.
* 11-JAN-2011 (DSB):
* Improve simplification of serial combinations of parellel CmpMaps.
* 25-JAN-2011 (DSB):
* Big improvement to the efficiency of the astMapSplit method.
* 24-JAN-2012 (DSB):
* If efficient MapSplit fails to split (e.g. due to the presence
* of PermMaps), then revert to the older slower method.
*class--
*/
/* Module Macros. */
/* ============== */
/* Set the name of the class we are implementing. This indicates to
the header files that define class interfaces that they should make
"protected" symbols available. */
#define astCLASS CmpMap
/* Include files. */
/* ============== */
/* Interface definitions. */
/* ---------------------- */
#include "error.h" /* Error reporting facilities */
#include "memory.h" /* Memory allocation facilities */
#include "object.h" /* Base Object class */
#include "pointset.h" /* Sets of points/coordinates */
#include "mapping.h" /* Coordinate Mappings (parent class) */
#include "channel.h" /* I/O channels */
#include "permmap.h" /* Coordinate permutation Mappings */
#include "unitmap.h" /* Unit transformations */
#include "cmpmap.h" /* Interface definition for this class */
#include "frameset.h" /* Interface definition for FrameSets */
#include "globals.h" /* Thread-safe global data access */
/* Error code definitions. */
/* ----------------------- */
#include "ast_err.h" /* AST error codes */
/* C header files. */
/* --------------- */
#include <stdarg.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
/* Module Variables. */
/* ================= */
/* Address of this static variable is used as a unique identifier for
member of this class. */
static int class_check;
/* Pointers to parent class methods which are extended by this class. */
static int (* parent_getobjsize)( AstObject *, int * );
static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, AstPointSet *, int * );
static int (* parent_maplist)( AstMapping *, int, int, int *, AstMapping ***, int **, int * );
static int *(* parent_mapsplit)( AstMapping *, int, const int *, AstMapping **, int * );
#if defined(THREAD_SAFE)
static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * );
#endif
/* Define macros for accessing each item of thread specific global data. */
#ifdef THREAD_SAFE
/* Define how to initialise thread-specific globals. */
#define GLOBAL_inits \
globals->Class_Init = 0; \
globals->Simplify_Depth = 0; \
globals->Simplify_Stackmaps = NULL;
/* Create the function that initialises global data for this module. */
astMAKE_INITGLOBALS(CmpMap)
#define class_init astGLOBAL(CmpMap,Class_Init)
#define class_vtab astGLOBAL(CmpMap,Class_Vtab)
#define simplify_depth astGLOBAL(CmpMap,Simplify_Depth)
#define simplify_stackmaps astGLOBAL(CmpMap,Simplify_Stackmaps)
/* If thread safety is not needed, declare and initialise globals at static
variables. */
#else
static int simplify_depth = 0;
static AstMapping **simplify_stackmaps = NULL;
/* Define the class virtual function table and its initialisation flag
as static variables. */
static AstCmpMapVtab class_vtab; /* Virtual function table */
static int class_init = 0; /* Virtual function table initialised? */
#endif
/* External Interface Function Prototypes. */
/* ======================================= */
/* The following functions have public prototypes only (i.e. no
protected prototypes), so we must provide local prototypes for use
within this module. */
AstCmpMap *astCmpMapId_( void *, void *, int, const char *, ... );
/* Prototypes for Private Member Functions. */
/* ======================================== */
static AstMapping *CombineMaps( AstMapping *, int, AstMapping *, int, int, int * );
static AstMapping *RemoveRegions( AstMapping *, int * );
static AstMapping *Simplify( AstMapping *, int * );
static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * );
static double Rate( AstMapping *, double *, int, int, int * );
static int *MapSplit( AstMapping *, int, const int *, AstMapping **, int * );
static int *MapSplit0( AstMapping *, int, const int *, AstMapping **, int, int * );
static int *MapSplit1( AstMapping *, int, const int *, AstMapping **, int * );
static int *MapSplit2( AstMapping *, int, const int *, AstMapping **, int * );
static int Equal( AstObject *, AstObject *, int * );
static int GetIsLinear( AstMapping *, int * );
static int MapList( AstMapping *, int, int, int *, AstMapping ***, int **, int * );
static int MapMerge( AstMapping *, int, int, int *, AstMapping ***, int **, int * );
static int PatternCheck( int, int, int **, int *, int * );
static void Copy( const AstObject *, AstObject *, int * );
static void Decompose( AstMapping *, AstMapping **, AstMapping **, int *, int *, int *, int * );
static void Delete( AstObject *, int * );
static void Dump( AstObject *, AstChannel *, int * );
static int GetObjSize( AstObject *, int * );
#if defined(THREAD_SAFE)
static int ManageLock( AstObject *, int, int, AstObject **, int * );
#endif
/* Member functions. */
/* ================= */
static int Equal( AstObject *this_object, AstObject *that_object, int *status ) {
/*
* Name:
* Equal
* Purpose:
* Test if two CmpMaps are equivalent.
* Type:
* Private function.
* Synopsis:
* #include "cmpmap.h"
* int Equal( AstObject *this, AstObject *that, int *status )
* Class Membership:
* CmpMap member function (over-rides the astEqual protected
* method inherited from the astMapping class).
* Description:
* This function returns a boolean result (0 or 1) to indicate whether
* two CmpMaps are equivalent.
* Parameters:
* this
* Pointer to the first Object (a CmpMap).
* that
* Pointer to the second Object.
* status
* Pointer to the inherited status variable.
* Returned Value:
* One if the CmpMaps are equivalent, zero otherwise.
* Notes:
* - A value of zero will be returned if this function is invoked
* with the global status set, or if it should fail for any reason.
*/
/* Local Variables: */
AstCmpMap *that;
AstCmpMap *this;
AstMapping **that_map_list;
AstMapping **this_map_list;
int *that_invert_list;
int *this_invert_list;
int i;
int result;
int that_inv;
int that_nmap;
int this_inv;
int this_nmap;
/* Initialise. */
result = 0;
/* Check the global error status. */
if ( !astOK ) return result;
/* Obtain pointers to the two CmpMap structures. */
this = (AstCmpMap *) this_object;
that = (AstCmpMap *) that_object;
/* Check the second object is a CmpMap. We know the first is a
CmpMap since we have arrived at this implementation of the virtual
function. */
if( astIsACmpMap( that ) ) {
/* Check they are both either parallel or series. */
if( that->series == that->series ) {
/* Decompose the first CmpMap into a sequence of Mappings to be applied in
series or parallel, as appropriate, and an associated list of
Invert flags. */
this_nmap = 0;
this_map_list = NULL;
this_invert_list = NULL;
astMapList( (AstMapping *) this, this->series, astGetInvert( this ),
&this_nmap, &this_map_list, &this_invert_list );
/* Similarly decompose the second CmpMap. */
that_nmap = 0;
that_map_list = NULL;
that_invert_list = NULL;
astMapList( (AstMapping *) that, that->series, astGetInvert( that ),
&that_nmap, &that_map_list, &that_invert_list );
/* Check the decompositions yielded the same number of component
Mappings. */
if( that_nmap == this_nmap ) {
/* Check equality of every component. */
for( i = 0; i < this_nmap; i++ ) {
/* Temporarily set the Mapping Invert flags to the required values,
saving the original values so that they can be re-instated later.*/
this_inv = astGetInvert( this_map_list[ i ] );
astSetInvert( this_map_list[ i ], this_invert_list[ i ] );
that_inv = astGetInvert( that_map_list[ i ] );
astSetInvert( that_map_list[ i ], that_invert_list[ i ] );
/* Compare the two component Mappings for equality. */
result = astEqual( this_map_list[ i ], that_map_list[ i ] );
/* Re-instate the original Invert flags. */
astSetInvert( this_map_list[ i ], this_inv );
astSetInvert( that_map_list[ i ], that_inv );
/* Leave the loop if the Mappings are not equal. */
if( !result ) break;
}
}
/* Free resources */
for( i = 0; i < this_nmap; i++ ) {
this_map_list[ i ] = astAnnul( this_map_list[ i ] );
}
this_map_list = astFree( this_map_list );
this_invert_list = astFree( this_invert_list );
for( i = 0; i < that_nmap; i++ ) {
that_map_list[ i ] = astAnnul( that_map_list[ i ] );
}
that_map_list = astFree( that_map_list );
that_invert_list = astFree( that_invert_list );
}
}
/* If an error occurred, clear the result value. */
if ( !astOK ) result = 0;
/* Return the result, */
return result;
}
static int GetIsLinear( AstMapping *this_mapping, int *status ){
/*
* Name:
* GetIsLinear
* Purpose:
* Return the value of the IsLinear attribute for a CmpMap.
* Type:
* Private function.
* Synopsis:
* #include "mapping.h"
* void GetIsLinear( AstMapping *this, int *status )
* Class Membership:
* CmpMap member function (over-rides the protected astGetIsLinear
* method inherited from the Mapping class).
* Description:
* This function returns the value of the IsLinear attribute for a
* Frame, which is one if both component Mappings have a value of 1
* for the IsLinear attribute.
* Parameters:
* this
* Pointer to the CmpqMap.
* status
* Pointer to the inherited status variable.
*/
AstCmpMap *this;
this = (AstCmpMap *) this_mapping;
return astGetIsLinear( this->map1 ) && astGetIsLinear( this->map2 );
}
static int GetObjSize( AstObject *this_object, int *status ) {
/*
* Name:
* GetObjSize
* Purpose:
* Return the in-memory size of an Object.
* Type:
* Private function.
* Synopsis:
* #include "cmpmap.h"
* int GetObjSize( AstObject *this, int *status )
* Class Membership:
* CmpMap member function (over-rides the astGetObjSize protected
* method inherited from the parent class).
* Description:
* This function returns the in-memory size of the supplied CmpMap,
* in bytes.
* Parameters:
* this
* Pointer to the CmpMap.
* status
* Pointer to the inherited status variable.
* Returned Value:
* The Object size, in bytes.
* Notes:
* - A value of zero will be returned if this function is invoked
* with the global status set, or if it should fail for any reason.
*/
/* Local Variables: */
AstCmpMap *this; /* Pointer to CmpMap structure */
int result; /* Result value to return */
/* Initialise. */
result = 0;
/* Check the global error status. */
if ( !astOK ) return result;
/* Obtain a pointers to the CmpMap structure. */
this = (AstCmpMap *) this_object;
/* Invoke the GetObjSize method inherited from the parent class, and then
add on any components of the class structure defined by thsi class
which are stored in dynamically allocated memory. */
result = (*parent_getobjsize)( this_object, status );
result += astGetObjSize( this->map1 );
result += astGetObjSize( this->map2 );
/* If an error occurred, clear the result value. */
if ( !astOK ) result = 0;
/* Return the result, */
return result;
}
static AstMapping *CombineMaps( AstMapping *mapping1, int invert1,
AstMapping *mapping2, int invert2,
int series, int *status ) {
/*
* Name:
* CombineMaps
* Purpose:
* Combine two Mappings with specified Invert flags into a CmpMap.
* Type:
* Private function.
* Synopsis:
* #include "cmpmap.h"
* AstMapping *CombineMaps( AstMapping *mapping1, int invert1,
* AstMapping *mapping2, int invert2,
* int series, int *status )
* Class Membership:
* CmpMap member function.
* Description:
* This function combines two Mappings into a CmpMap (compound
* Mapping) as if their Invert flags were set to specified values
* when the CmpMap is created. However, the individual Mappings are
* returned with their Invert flag values unchanged from their
* original state.
* Parameters:
* mapping1
* Pointer to the first Mapping.
* invert1
* The (boolean) Invert flag value required for the first Mapping.
* mapping2
* Pointer to the second Mapping.
* invert2
* The (boolean) Invert flag value required for the second Mapping.
* series
* Whether the Mappings are to be combined in series (as opposed to
* in parallel).
* status
* Pointer to the inherited status variable.
* Returned Value:
* A pointer to the resulting compound Mapping (a CmpMap).
* Notes:
* - This function is a wrap-up for the astCmpMap constructor and
* temporarily assigns the required Invert flag values while
* creating the required CmpMap. However, it also takes account of
* the possibility that the two Mapping pointers supplied may point
* at the same Mapping.
* - A null Object pointer (AST__NULL) will be returned if this
* function is invoked with the AST error status set, or if it
* should fail for any reason.
*/
/* Local Variables: */
AstMapping *map1; /* First temporary Mapping pointer */
AstMapping *map2; /* Second temporary Mapping pointer */
AstMapping *result; /* Pointer to result Mapping */
int copy; /* Copy needed? */
int inv1; /* First original Invert flag value */
int inv2; /* Second original Invert flag value */
int set1; /* First Invert flag originally set? */
int set2; /* Second Invert flag originally set? */
/* Initialise */
result = NULL;
/* Check the global error status. */
if ( !astOK ) return result;
/* Limit incoming values to 0 or 1. */
invert1 = ( invert1 != 0 );
invert2 = ( invert2 != 0 );
/* Obtain the Invert flag values for each Mapping. */
inv1 = astGetInvert( mapping1 );
inv2 = astGetInvert( mapping2 );
/* Also determine if these values are explicitly set. */
set1 = astTestInvert( mapping1 );
set2 = astTestInvert( mapping2 );
/* If both Mappings are actually the same but we need different Invert
flag values to be set, then this can only be achieved by making a
copy. Note if this is necessary. */
copy = ( ( mapping1 == mapping2 ) && ( invert1 != invert2 ) );
/* Clone the first Mapping pointer. Do likewise for the second but
make a copy instead if necessary. */
map1 = astClone( mapping1 );
map2 = copy ? astCopy( mapping2 ) : astClone( mapping2 );
/* If the Invert value for the first Mapping needs changing, make the
change. */
if ( invert1 != inv1 ) {
if ( invert1 ) {
astSetInvert( map1, 1 );
} else {
astClearInvert( map1 );
}
}
/* Similarly, change the Invert flag for the second Mapping if
necessary. */
if ( invert2 != inv2 ) {
if ( invert2 ) {
astSetInvert( map2, 1 );
} else {
astClearInvert( map2 );
}
}
/* Combine the two Mappings into a CmpMap. */
result = (AstMapping *) astCmpMap( map1, map2, series, "", status );
/* If the first Mapping's Invert value was changed, restore it to its
original state. */
if ( invert1 != inv1 ) {
if ( set1 ) {
astSetInvert( map1, inv1 );
} else {
astClearInvert( map1 );
}
}
/* Similarly, restore the second Mapping's Invert value if
necessary. This step is not needed, however, if a copy was made. */
if ( ( invert2 != inv2 ) && !copy ) {
if ( set2 ) {
astSetInvert( map2, inv2 );
} else {
astClearInvert( map2 );
}
}
/* Annul the temporary Mapping pointers. */
map1 = astAnnul( map1 );
map2 = astAnnul( map2 );
/* If an error occurred, then annul the result pointer. */
if ( !astOK ) result = astAnnul( result );
/* Return the result. */
return result;
}
static void Decompose( AstMapping *this_mapping, AstMapping **map1,
AstMapping **map2, int *series, int *invert1,
int *invert2, int *status ) {
/*
*
* Name:
* Decompose
* Purpose:
* Decompose a Mapping into two component Mappings.
* Type:
* Private function.
* Synopsis:
* #include "mapping.h"
* void Decompose( AstMapping *this, AstMapping **map1,
* AstMapping **map2, int *series,
* int *invert1, int *invert2, int *status )
* Class Membership:
* CmpMap member function (over-rides the protected astDecompose
* method inherited from the Mapping class).
* Description:
* This function returns pointers to two Mappings which, when applied
* either in series or parallel, are equivalent to the supplied Mapping.
*
* Since the Frame class inherits from the Mapping class, Frames can
* be considered as special types of Mappings and so this method can
* be used to decompose either CmpMaps or CmpFrames.
* Parameters:
* this
* Pointer to the Mapping.
* map1
* Address of a location to receive a pointer to first component
* Mapping.
* map2
* Address of a location to receive a pointer to second component
* Mapping.
* series
* Address of a location to receive a value indicating if the
* component Mappings are applied in series or parallel. A non-zero
* value means that the supplied Mapping is equivalent to applying map1
* followed by map2 in series. A zero value means that the supplied
* Mapping is equivalent to applying map1 to the lower numbered axes
* and map2 to the higher numbered axes, in parallel.
* invert1
* The value of the Invert attribute to be used with map1.
* invert2
* The value of the Invert attribute to be used with map2.
* status
* Pointer to the inherited status variable.
* Notes:
* - Any changes made to the component Mappings using the returned
* pointers will be reflected in the supplied Mapping.
*-
*/
/* Local Variables: */
AstCmpMap *this; /* Pointer to CmpMap structure */
/* Check the global error status. */
if ( !astOK ) return;
/* Obtain a pointer to the CmpMap structure. */
this = (AstCmpMap *) this_mapping;
/* First deal with series mappings. */
if( this->series ) {
if( series ) *series = 1;
/* If the CmpMap has been inverted, return the Mappings in reverse
order with inverted Invert falgs. */
if( astGetInvert( this ) ) {
if( map1 ) *map1 = astClone( this->map2 );
if( map2 ) *map2 = astClone( this->map1 );
if( invert1 ) *invert1 = this->invert2 ? 0 : 1;
if( invert2 ) *invert2 = this->invert1 ? 0 : 1;
/* If the CmpMap has not been inverted, return the Mappings in their
original order with their original Invert flags. */
} else {
if( map1 ) *map1 = astClone( this->map1 );
if( map2 ) *map2 = astClone( this->map2 );
if( invert1 ) *invert1 = this->invert1;
if( invert2 ) *invert2 = this->invert2;
}
/* Now deal with parallel mappings. */
} else {
if( series ) *series = 0;
/* The mappings are returned in their original order whether or not the
CmpMap has been inverted. */
if( map1 ) *map1 = astClone( this->map1 );
if( map2 ) *map2 = astClone( this->map2 );
/* If the CmpMap has been inverted, return inverted Invert flags. */
if( astGetInvert( this ) ) {
if( invert1 ) *invert1 = this->invert1 ? 0 : 1;
if( invert2 ) *invert2 = this->invert2 ? 0 : 1;
/* If the CmpMap has not been inverted, return the original Invert flags. */
} else {
if( invert1 ) *invert1 = this->invert1;
if( invert2 ) *invert2 = this->invert2;
}
}
}
void astInitCmpMapVtab_( AstCmpMapVtab *vtab, const char *name, int *status ) {
/*
*+
* Name:
* astInitCmpMapVtab
* Purpose:
* Initialise a virtual function table for a CmpMap.
* Type:
* Protected function.
* Synopsis:
* #include "cmpmap.h"
* void astInitCmpMapVtab( AstCmpMapVtab *vtab, const char *name )
* Class Membership:
* CmpMap vtab initialiser.
* Description:
* This function initialises the component of a virtual function
* table which is used by the CmpMap class.
* Parameters:
* vtab
* Pointer to the virtual function table. The components used by
* all ancestral classes will be initialised if they have not already
* been initialised.
* name
* Pointer to a constant null-terminated character string which contains
* the name of the class to which the virtual function table belongs (it
* is this pointer value that will subsequently be returned by the Object
* astClass function).
*-
*/
/* Local Variables: */
astDECLARE_GLOBALS /* Pointer to thread-specific global data */
AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */
AstObjectVtab *object; /* Pointer to Object component of Vtab */
/* Check the local error status. */
if ( !astOK ) return;
/* Get a pointer to the thread specific global data structure. */
astGET_GLOBALS(NULL);
/* Initialize the component of the virtual function table used by the
parent class. */
astInitMappingVtab( (AstMappingVtab *) vtab, name );
/* Store a unique "magic" value in the virtual function table. This
will be used (by astIsACmpMap) to determine if an object belongs to
this class. We can conveniently use the address of the (static)
class_check variable to generate this unique value. */
vtab->id.check = &class_check;
vtab->id.parent = &(((AstMappingVtab *) vtab)->id);
/* Initialise member function pointers. */
/* ------------------------------------ */
/* Store pointers to the member functions (implemented here) that
provide virtual methods for this class. */
/* None. */
/* Save the inherited pointers to methods that will be extended, and
replace them with pointers to the new member functions. */
object = (AstObjectVtab *) vtab;
mapping = (AstMappingVtab *) vtab;
parent_getobjsize = object->GetObjSize;
object->GetObjSize = GetObjSize;
#if defined(THREAD_SAFE)
parent_managelock = object->ManageLock;
object->ManageLock = ManageLock;
#endif
parent_maplist = mapping->MapList;
mapping->MapList = MapList;
parent_transform = mapping->Transform;
mapping->Transform = Transform;
parent_mapsplit = mapping->MapSplit;
mapping->MapSplit = MapSplit;
/* Store replacement pointers for methods which will be over-ridden by
new member functions implemented here. */
object->Equal = Equal;
mapping->Decompose = Decompose;
mapping->MapMerge = MapMerge;
mapping->Simplify = Simplify;
mapping->RemoveRegions = RemoveRegions;
mapping->GetIsLinear = GetIsLinear;
/* For some reason the CmpMap implementation of astRate can be immensely
slow for complex Mapping, so it's currently disable until such time as
I have time to sort it out.
mapping->Rate = Rate;
*/
/* Declare the copy constructor, destructor and class dump function. */
astSetCopy( vtab, Copy );
astSetDelete( vtab, Delete );
astSetDump( vtab, Dump, "CmpMap", "Compound Mapping" );
/* If we have just initialised the vtab for the current class, indicate
that the vtab is now initialised, and store a pointer to the class
identifier in the base "object" level of the vtab. */
if( vtab == &class_vtab ) {
class_init = 1;
astSetVtabClassIdentifier( vtab, &(vtab->id) );
}
}
#if defined(THREAD_SAFE)
static int ManageLock( AstObject *this_object, int mode, int extra,
AstObject **fail, int *status ) {
/*
* Name:
* ManageLock
* Purpose:
* Manage the thread lock on an Object.
* Type:
* Private function.
* Synopsis:
* #include "object.h"
* AstObject *ManageLock( AstObject *this, int mode, int extra,
* AstObject **fail, int *status )
* Class Membership:
* CmpMap member function (over-rides the astManageLock protected
* method inherited from the parent class).
* Description:
* This function manages the thread lock on the supplied Object. The
* lock can be locked, unlocked or checked by this function as
* deteremined by parameter "mode". See astLock for details of the way
* these locks are used.
* Parameters:
* this
* Pointer to the Object.
* mode
* An integer flag indicating what the function should do:
*
* AST__LOCK: Lock the Object for exclusive use by the calling
* thread. The "extra" value indicates what should be done if the
* Object is already locked (wait or report an error - see astLock).
*
* AST__UNLOCK: Unlock the Object for use by other threads.
*
* AST__CHECKLOCK: Check that the object is locked for use by the
* calling thread (report an error if not).
* extra
* Extra mode-specific information.
* fail
* If a non-zero function value is returned, a pointer to the
* Object that caused the failure is returned at "*fail". This may
* be "this" or it may be an Object contained within "this". Note,
* the Object's reference count is not incremented, and so the
* returned pointer should not be annulled. A NULL pointer is
* returned if this function returns a value of zero.
* status
* Pointer to the inherited status variable.
* Returned Value:
* A local status value:
* 0 - Success
* 1 - Could not lock or unlock the object because it was already
* locked by another thread.
* 2 - Failed to lock a POSIX mutex
* 3 - Failed to unlock a POSIX mutex
* 4 - Bad "mode" value supplied.
* Notes:
* - This function attempts to execute even if an error has already
* occurred.
*/
/* Local Variables: */
AstCmpMap *this; /* Pointer to CmpMap structure */
int result; /* Returned status value */
/* Initialise */
result = 0;
/* Check the supplied pointer is not NULL. */
if( !this_object ) return result;
/* Obtain a pointers to the CmpMap structure. */
this = (AstCmpMap *) this_object;
/* Invoke the ManageLock method inherited from the parent class. */
if( !result ) result = (*parent_managelock)( this_object, mode, extra,
fail, status );
/* Invoke the astManageLock method on any Objects contained within
the supplied Object. */
if( !result ) result = astManageLock( this->map1, mode, extra, fail );
if( !result ) result = astManageLock( this->map2, mode, extra, fail );
return result;
}
#endif
static int MapList( AstMapping *this_mapping, int series, int invert,
int *nmap, AstMapping ***map_list, int **invert_list, int *status ) {
/*
* Name:
* MapList
* Purpose:
* Decompose a CmpMap into a sequence of simpler Mappings.
* Type:
* Private function.
* Synopsis:
* #include "mapping.h"
* int MapList( AstMapping *this, int series, int invert, int *nmap,
* AstMapping ***map_list, int **invert_list )