CR2RE Pipeline Reference Manual 1.6.10
irplib_framelist.c
1/*
2 * This file is part of the irplib package
3 * Copyright (C) 2002,2003 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
18 */
19
20
21#ifdef HAVE_CONFIG_H
22#include <config.h>
23#endif
24
25
26/*-----------------------------------------------------------------------------
27 Includes
28 -----------------------------------------------------------------------------*/
29
30#include "irplib_framelist.h"
31#include "irplib_utils.h"
32
33#include <stdio.h>
34#include <string.h>
35#include <sys/types.h>
36#include <regex.h>
37#include <math.h>
38#include <assert.h>
39
40
41/*-----------------------------------------------------------------------------
42 New types
43 -----------------------------------------------------------------------------*/
44
45/* @cond */
46struct _irplib_framelist_ {
47 int size;
48 cpl_frame ** frame;
49 cpl_propertylist ** propertylist;
50
51};
52/* @endcond */
53
54/*-----------------------------------------------------------------------------
55 Private funcions
56 -----------------------------------------------------------------------------*/
57
58static void irplib_framelist_set_size(irplib_framelist *)
59#if defined __GNUC__ && __GNUC__ >= 4
60 __attribute__((nonnull))
61#endif
62;
63
64static cpl_boolean irplib_property_equal(const cpl_propertylist *,
65 const cpl_propertylist *,
66 const char *, cpl_type, double,
67 char **, char **)
68#if defined __GNUC__ && __GNUC__ >= 4
69 __attribute__((nonnull))
70#endif
71;
72
73/*----------------------------------------------------------------------------*/
152/*----------------------------------------------------------------------------*/
153
156/*-----------------------------------------------------------------------------
157 Function codes
158 -----------------------------------------------------------------------------*/
159
160/*----------------------------------------------------------------------------*/
168/*----------------------------------------------------------------------------*/
169irplib_framelist * irplib_framelist_new(void)
170{
171
172 return (irplib_framelist *) cpl_calloc(1, sizeof(irplib_framelist));
173
174}
175
176/*----------------------------------------------------------------------------*/
181/*----------------------------------------------------------------------------*/
182void irplib_framelist_delete(irplib_framelist * self)
183{
184
186 cpl_free(self);
187}
188
189
190/*----------------------------------------------------------------------------*/
199/*----------------------------------------------------------------------------*/
200irplib_framelist * irplib_framelist_cast(const cpl_frameset * frameset)
201{
202 irplib_framelist * self;
203 int i ;
204
205 cpl_ensure(frameset != NULL, CPL_ERROR_NULL_INPUT, NULL);
206
207 /* The function cannot fail now */
208 self = irplib_framelist_new();
209
210 for (i = 0; i < cpl_frameset_get_size(frameset); i++)
211 {
212 const cpl_frame * frame = cpl_frameset_get_position_const(frameset, i);
213
214 cpl_frame * copy = cpl_frame_duplicate(frame);
215
216#ifndef NDEBUG
217 const cpl_error_code error =
218#endif
219 irplib_framelist_set(self, copy, i);
220
221 assert(error == CPL_ERROR_NONE);
222
223 }
224
225 assert(self->size == cpl_frameset_get_size(frameset));
226
227 return self;
228
229}
230
231
232/*----------------------------------------------------------------------------*/
241/*----------------------------------------------------------------------------*/
242cpl_frameset * irplib_frameset_cast(const irplib_framelist * self)
243{
244 cpl_frameset * new;
245 int i ;
246
247 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
248
249 /* The function cannot fail now */
250 new = cpl_frameset_new();
251
252 for (i = 0; i < self->size; i++) {
253 cpl_frame * frame = cpl_frame_duplicate(self->frame[i]);
254#ifndef NDEBUG
255 const cpl_error_code error =
256#endif
257 cpl_frameset_insert(new, frame);
258
259 assert(error == CPL_ERROR_NONE);
260
261 }
262
263 assert(self->size == cpl_frameset_get_size(new));
264
265 return new;
266
267}
268
269
270/*----------------------------------------------------------------------------*/
282/*----------------------------------------------------------------------------*/
283irplib_framelist * irplib_framelist_extract(const irplib_framelist * self,
284 const char * tag)
285{
286
287 irplib_framelist * new;
288 int i, newsize;
289
290
291 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
292 cpl_ensure(tag != NULL, CPL_ERROR_NULL_INPUT, NULL);
293
294 new = irplib_framelist_new();
295 newsize = 0;
296
297 for (i = 0; i < self->size; i++) {
298 const cpl_frame * frame = self->frame[i];
299 const char * ftag = cpl_frame_get_tag(frame);
300 cpl_frame * copy;
301 cpl_error_code code;
302
303 if (ftag == NULL) {
304 /* The frame is ill-formed */
306 (void)cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
307 return NULL;
308 }
309
310 if (strcmp(tag, ftag)) continue;
311
312 copy = cpl_frame_duplicate(frame);
313
314 code = irplib_framelist_set(new, copy, newsize);
315 if (code != CPL_ERROR_NONE) break; /* Should not be possible */
316
317 if (self->propertylist[i] != NULL) new->propertylist[newsize]
318 = cpl_propertylist_duplicate(self->propertylist[i]);
319
320 newsize++;
321 }
322
323 assert( newsize == new->size );
324
325 if (newsize == 0) {
326#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
327 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
328 "The list of %d frame(s) has no frames "
329 "with tag: %s", self->size, tag);
330#else
331 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
332 "The list of frame(s) has no frames "
333 "with the given tag");
334#endif
336 new = NULL;
337 }
338
339 return new;
340
341}
342
343/*----------------------------------------------------------------------------*/
353/*----------------------------------------------------------------------------*/
354irplib_framelist * irplib_framelist_extract_regexp(const irplib_framelist* self,
355 const char * regexp,
356 cpl_boolean invert)
357{
358
359 irplib_framelist * new;
360 int error;
361 int i, newsize;
362 const int xor_val = (invert == CPL_FALSE ? 0 : 1);
363 regex_t re;
364
365
366 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
367 cpl_ensure(regexp != NULL, CPL_ERROR_NULL_INPUT, NULL);
368
369 error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
370 cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, NULL);
371
372 new = irplib_framelist_new();
373 newsize = 0;
374
375 for (i = 0; i < self->size; i++) {
376 const cpl_frame * frame = self->frame[i];
377 const char * tag = cpl_frame_get_tag(frame);
378 cpl_frame * copy;
379
380 if (tag == NULL) {
381 /* The frame is ill-formed */
383 regfree(&re);
384 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
385 }
386
387 if ((regexec(&re, tag, (size_t)0, NULL, 0) == REG_NOMATCH ? 1 : 0)
388 ^ xor_val) continue;
389
390 copy = cpl_frame_duplicate(frame);
391
392 error = (int)irplib_framelist_set(new, copy, newsize);
393 assert(error == CPL_ERROR_NONE);
394
395 if (self->propertylist[i] != NULL) new->propertylist[newsize]
396 = cpl_propertylist_duplicate(self->propertylist[i]);
397
398 newsize++;
399
400 }
401
402 regfree(&re);
403
404 assert( newsize == new->size );
405
406 if (newsize == 0) {
407#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
408 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
409 "The list of %d frame(s) has no frames "
410 "that match: %s", self->size, regexp);
411#else
412 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
413 "The list of frames has no frames "
414 "that match the regular expression");
415#endif
417 new = NULL;
418 }
419
420 return new;
421}
422
423
424/*----------------------------------------------------------------------------*/
431/*----------------------------------------------------------------------------*/
432int irplib_framelist_get_size(const irplib_framelist * self)
433{
434
435 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, -1);
436
437 return self->size;
438
439}
440
441/*----------------------------------------------------------------------------*/
449/*----------------------------------------------------------------------------*/
450cpl_frame * irplib_framelist_get(irplib_framelist * self, int pos)
451{
452 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
453 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
454 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
455
456 return self->frame[pos];
457}
458
459
460/*----------------------------------------------------------------------------*/
469/*----------------------------------------------------------------------------*/
470const cpl_frame * irplib_framelist_get_const(const irplib_framelist * self,
471 int pos)
472{
473 /* Code duplicated from irplib_framelist_get() */
474 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
475 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
476 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
477
478 return self->frame[pos];
479}
480
481
482/*----------------------------------------------------------------------------*/
491/*----------------------------------------------------------------------------*/
492cpl_error_code irplib_framelist_set_propertylist(irplib_framelist * self,
493 int pos,
494 const cpl_propertylist * list)
495{
496
497 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
498 cpl_ensure_code(list != NULL, CPL_ERROR_NULL_INPUT);
499 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
500 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
501
502 cpl_propertylist_delete(self->propertylist[pos]);
503
504 self->propertylist[pos] = cpl_propertylist_duplicate(list);
505
506 cpl_ensure_code(self->propertylist[pos] != NULL, cpl_error_get_code());
507
508 return CPL_ERROR_NONE;
509
510}
511
512
513/*----------------------------------------------------------------------------*/
524/*----------------------------------------------------------------------------*/
525cpl_propertylist * irplib_framelist_get_propertylist(irplib_framelist * self,
526 int pos)
527{
528 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
529 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
530 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
531
532 cpl_ensure(self->propertylist[pos] != NULL,
533 CPL_ERROR_DATA_NOT_FOUND, NULL);
534
535 return self->propertylist[pos];
536}
537
538
539/*----------------------------------------------------------------------------*/
551/*----------------------------------------------------------------------------*/
553 const irplib_framelist * self,
554 int pos)
555{
556 /* Code duplicated from irplib_framelist_get_propertylist() */
557 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
558 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
559 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
560
561 cpl_ensure(self->propertylist[pos] != NULL,
562 CPL_ERROR_DATA_NOT_FOUND, NULL);
563
564 return self->propertylist[pos];
565
566}
567
568
569/*----------------------------------------------------------------------------*/
583/*----------------------------------------------------------------------------*/
584cpl_error_code irplib_framelist_load_propertylist(irplib_framelist * self,
585 int pos, int ind,
586 const char * regexp,
587 cpl_boolean invert)
588{
589
590 const char * filename;
591
592
593 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
594 cpl_ensure_code(regexp != NULL, CPL_ERROR_NULL_INPUT);
595 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
596 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
597
598 filename = cpl_frame_get_filename(self->frame[pos]);
599
600 cpl_ensure_code(filename != NULL, cpl_error_get_code());
601
602 cpl_propertylist_delete(self->propertylist[pos]);
603
604 self->propertylist[pos] = cpl_propertylist_load_regexp(filename, ind,
605 regexp,
606 invert ? 1 : 0);
607
608 if (self->propertylist[pos] == NULL) {
609#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
610 return cpl_error_set_message(cpl_func, cpl_error_get_code(), "Could "
611 "not load FITS header from '%s' using "
612 "regexp '%s'", filename, regexp);
613#else
614 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
615 "Could not load FITS header");
616#endif
617 }
618
619 return CPL_ERROR_NONE;
620
621}
622
623
624/*----------------------------------------------------------------------------*/
638/*----------------------------------------------------------------------------*/
639cpl_error_code irplib_framelist_load_propertylist_all(irplib_framelist * self,
640 int ind,
641 const char * regexp,
642 cpl_boolean invert)
643{
644
645 int nprops = 0;
646 int nfiles = 0;
647 int i;
648
649 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
650 cpl_ensure_code(regexp != NULL, CPL_ERROR_NULL_INPUT);
651
652 for (i=0; i < self->size; i++) {
653 if (self->propertylist[i] == NULL)
654 cpl_ensure_code(!irplib_framelist_load_propertylist(self, i,
655 ind,
656 regexp,
657 invert),
658 cpl_error_get_code());
659 /* Counting just for diagnostics - this actually causes
660 the whole list to be reiterated :-( */
661 nprops += cpl_propertylist_get_size(self->propertylist[i]);
662 nfiles++;
663 }
664
665 cpl_msg_info(cpl_func, "List of %d frames has %d properties", nfiles,
666 nprops);
667
668 return CPL_ERROR_NONE;
669
670}
671
672
673
674/*----------------------------------------------------------------------------*/
682/*----------------------------------------------------------------------------*/
683cpl_error_code irplib_framelist_set_tag_all(irplib_framelist * self,
684 const char * tag)
685{
686
687 int i;
688
689 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
690 cpl_ensure_code(tag != NULL, CPL_ERROR_NULL_INPUT);
691
692 for (i=0; i < self->size; i++)
693 cpl_ensure_code(!cpl_frame_set_tag(self->frame[i], tag),
694 cpl_error_get_code());
695
696 return CPL_ERROR_NONE;
697}
698
699
700/*----------------------------------------------------------------------------*/
714/*----------------------------------------------------------------------------*/
715cpl_error_code irplib_framelist_set(irplib_framelist * self, cpl_frame * frame,
716 int pos)
717{
718
719 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
720 cpl_ensure_code(frame != NULL, CPL_ERROR_NULL_INPUT);
721 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
722
723 if (pos == self->size) {
724
725 self->size++;
726
727 irplib_framelist_set_size(self);
728
729 } else {
730
731 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
732
733 cpl_frame_delete(self->frame[pos]);
734 cpl_propertylist_delete(self->propertylist[pos]);
735 }
736
737 self->frame[pos] = frame;
738 self->propertylist[pos] = NULL;
739
740 return CPL_ERROR_NONE;
741
742}
743
744/*----------------------------------------------------------------------------*/
753/*----------------------------------------------------------------------------*/
754cpl_error_code irplib_framelist_erase(irplib_framelist * self, int pos)
755{
756
757 int i;
758
759 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
760 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
761 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
762
763
764 /* Delete the specified frame and its propertylist */
765 cpl_frame_delete(self->frame[pos]);
766 cpl_propertylist_delete(self->propertylist[pos]);
767
768 /* Move following frames down one position */
769 for (i = pos+1; i < self->size; i++) {
770
771 self->frame[i-1] = self->frame[i];
772
773 self->propertylist[i-1] = self->propertylist[i];
774
775 }
776
777 self->size--;
778
779 irplib_framelist_set_size(self);
780
781 return CPL_ERROR_NONE;
782
783}
784
785
786
787/*----------------------------------------------------------------------------*/
803/*----------------------------------------------------------------------------*/
804cpl_frame * irplib_framelist_unset(irplib_framelist * self, int pos,
805 cpl_propertylist ** plist)
806
807{
808 cpl_frame * frame;
809 int i;
810
811
812 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
813 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
814 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
815
816 /* Get the specified frame and its propertylist */
817 frame = self->frame[pos];
818
819 if (plist != NULL)
820 *plist = self->propertylist[pos];
821 else
822 cpl_propertylist_delete(self->propertylist[pos]);
823
824
825 /* Move following frames down one position */
826 for (i = pos+1; i < self->size; i++) {
827
828 self->frame[i-1] = self->frame[i];
829
830 self->propertylist[i-1] = self->propertylist[i];
831
832 }
833
834 self->size--;
835
836 irplib_framelist_set_size(self);
837
838 return frame;
839
840}
841
842/*----------------------------------------------------------------------------*/
849/*----------------------------------------------------------------------------*/
850void irplib_framelist_empty(irplib_framelist * self)
851{
852
853 if (self != NULL) {
854
855 /* Deallocate all frames and their propertylists */
856 while (self->size > 0) {
857 self->size--;
858 cpl_frame_delete(self->frame[self->size]);
859 cpl_propertylist_delete(self->propertylist[self->size]);
860
861 }
862
863 /* Deallocate the arrays */
864 irplib_framelist_set_size(self);
865
866 }
867}
868
869
870
871/*----------------------------------------------------------------------------*/
909/*----------------------------------------------------------------------------*/
910cpl_error_code irplib_framelist_contains(const irplib_framelist * self,
911 const char * key, cpl_type type,
912 cpl_boolean is_equal, double fp_tol)
913{
914
915 char * value_0 = NULL;
916 char * value_i = NULL;
917 cpl_type type_0 = CPL_TYPE_INVALID;
918 int i, ifirst = -1; /* First non-NULL propertylist */
919
920
921 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
922 cpl_ensure_code(key != NULL, CPL_ERROR_NULL_INPUT);
923 cpl_ensure_code(fp_tol >= 0.0, CPL_ERROR_ILLEGAL_INPUT);
924
925 for (i=0; i < self->size; i++) {
926 cpl_type type_i;
927
928
929 if (self->propertylist[i] == NULL) continue;
930 if (ifirst < 0) ifirst = i;
931
932 type_i = cpl_propertylist_get_type(self->propertylist[i], key);
933
934 if (type_i == CPL_TYPE_INVALID) {
935 if (type == CPL_TYPE_INVALID)
936#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
937 cpl_error_set_message(cpl_func, cpl_error_get_code(), "FITS "
938 "key '%s' is missing from file %s", key,
939 cpl_frame_get_filename(self->frame[i]));
940 else
941 cpl_error_set_message(cpl_func, cpl_error_get_code(),
942 "FITS key '%s' [%s] is missing from file "
943 "%s", key, cpl_type_get_name(type),
944 cpl_frame_get_filename(self->frame[i]));
945#else
946 cpl_error_set_message(cpl_func, cpl_error_get_code(),
947 "A FITS key is missing from a file");
948 else
949 cpl_error_set_message(cpl_func, cpl_error_get_code(),
950 "A FITS key is missing from a file");
951#endif
952 return cpl_error_get_code();
953 }
954
955 if (type != CPL_TYPE_INVALID && type_i != type) {
956#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
957 return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
958 "FITS key '%s' has type %s instead of "
959 "%s in file %s", key,
960 cpl_type_get_name(type_i),
961 cpl_type_get_name(type),
962 cpl_frame_get_filename(self->frame[i]));
963#else
964 return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
965 "A FITS key had an unexpected type");
966#endif
967
968 }
969
970 if (!is_equal) continue;
971
972 if (type_0 == CPL_TYPE_INVALID) {
973 type_0 = type_i;
974 continue;
975 }
976
977 if (type_i != type_0) {
978 assert( type == CPL_TYPE_INVALID );
979#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
980 return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
981 "FITS key '%s' has different types "
982 "(%s <=> %s) in files %s and %s", key,
983 cpl_type_get_name(type_0),
984 cpl_type_get_name(type_i),
985 cpl_frame_get_filename(self->frame[0]),
986 cpl_frame_get_filename(self->frame[i]));
987#else
988 return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
989 "A FITS key has different types in "
990 "two files");
991#endif
992 }
993
994 if (irplib_property_equal(self->propertylist[ifirst],
995 self->propertylist[i],
996 key, type_0, fp_tol, &value_0, &value_i))
997 continue;
998
999 if ((type_0 == CPL_TYPE_FLOAT || type_0 == CPL_TYPE_DOUBLE)
1000 && fp_tol > 0.0) {
1001#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1002 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "FITS"
1003 " key '%s' [%s] has values that differ by "
1004 "more than %g (%s <=> %s) in files %s and %s",
1005 key, cpl_type_get_name(type_0), fp_tol,
1006 value_0, value_i,
1007 cpl_frame_get_filename(self->frame[0]),
1008 cpl_frame_get_filename(self->frame[i]));
1009#else
1010 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "A "
1011 "FITS key has values that differ by more "
1012 "than the allowed tolerance in two file");
1013#endif
1014 } else {
1015#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1016 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
1017 "FITS key '%s' [%s] has different values "
1018 "(%s <=> %s) in files %s and %s", key,
1019 cpl_type_get_name(type_0),
1020 value_0, value_i,
1021 cpl_frame_get_filename(self->frame[0]),
1022 cpl_frame_get_filename(self->frame[i]));
1023#else
1024 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "A "
1025 "FITS key has different values in two files");
1026#endif
1027 }
1028 cpl_free(value_0);
1029 cpl_free(value_i);
1030
1031 return cpl_error_get_code();
1032 }
1033
1034 return CPL_ERROR_NONE;
1035
1036}
1037
1038
1039/*----------------------------------------------------------------------------*/
1052/*----------------------------------------------------------------------------*/
1053cpl_imagelist * irplib_imagelist_load_framelist(const irplib_framelist * self,
1054 cpl_type pixeltype,
1055 int planenum,
1056 int extnum)
1057{
1058
1059 cpl_imagelist * list = NULL;
1060 cpl_image * image = NULL;
1061 int i;
1062
1063
1064 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
1065 cpl_ensure(extnum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
1066 cpl_ensure(planenum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
1067
1068 list = cpl_imagelist_new();
1069
1070 for (i=0; i < self->size; i++, image = NULL) {
1071 const char * filename = cpl_frame_get_filename(self->frame[i]);
1072 cpl_error_code code;
1073
1074 if (filename == NULL) break;
1075
1076 image = cpl_image_load(filename, pixeltype, planenum, extnum);
1077 if (image == NULL) {
1078#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1079 (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
1080 "Could not load FITS-image from plane "
1081 "%d in extension %d in file %s",
1082 planenum, extnum, filename);
1083#else
1084 (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
1085 "Could not load FITS-image");
1086#endif
1087 break;
1088 }
1089
1090 code = cpl_imagelist_set(list, image, i);
1091 if (code != CPL_ERROR_NONE) break; /* Should not be possible */
1092 }
1093
1094 cpl_image_delete(image);
1095
1096 if (cpl_imagelist_get_size(list) != self->size) {
1097 cpl_imagelist_delete(list);
1098 list = NULL;
1099 (void)cpl_error_set_where(cpl_func);
1100 }
1101
1102 return list;
1103
1104}
1105
1106
1110/*----------------------------------------------------------------------------*/
1122/*----------------------------------------------------------------------------*/
1123static void irplib_framelist_set_size(irplib_framelist * self)
1124{
1125
1126
1127 assert( self != NULL);
1128
1129 if (self->size == 0) {
1130 /* The list has been emptied */
1131 cpl_free(self->frame);
1132 cpl_free(self->propertylist);
1133 self->frame = NULL;
1134 self->propertylist = NULL;
1135 } else if (self->size > 0) {
1136 /* Update the size of the arrays */
1137
1138 self->frame = cpl_realloc(self->frame, (size_t)self->size * sizeof(cpl_frame*));
1139 self->propertylist =
1140 cpl_realloc(self->propertylist,
1141 (size_t)self->size * sizeof(cpl_propertylist*));
1142 } else {
1143 (void)cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
1144 }
1145
1146}
1147
1148/*----------------------------------------------------------------------------*/
1172/*----------------------------------------------------------------------------*/
1173static cpl_boolean irplib_property_equal(const cpl_propertylist * self,
1174 const cpl_propertylist * other,
1175 const char * key, cpl_type type,
1176 double fp_tol,
1177 char ** sstring, char ** ostring)
1178{
1179
1180 cpl_boolean equal;
1181
1182
1183 assert(self != NULL);
1184 assert(other != NULL);
1185 assert(key != NULL);
1186 assert(sstring != NULL);
1187 assert(ostring != NULL);
1188
1189 /* FIXME: disable for better performance also with debugging */
1190 assert(cpl_propertylist_get_type(other, key) == type);
1191 assert(fp_tol >= 0.0);
1192
1193 if (self == other) return CPL_TRUE;
1194
1195 switch (type) {
1196
1197 case CPL_TYPE_CHAR: {
1198 const char svalue = cpl_propertylist_get_char(self, key);
1199 const char ovalue = cpl_propertylist_get_char(other, key);
1200
1201 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1202 if (!equal) {
1203 *sstring = cpl_sprintf("%c", svalue);
1204 *ostring = cpl_sprintf("%c", ovalue);
1205 }
1206 break;
1207 }
1208
1209 case CPL_TYPE_BOOL: {
1210 const int svalue = cpl_propertylist_get_bool(self, key);
1211 const int ovalue = cpl_propertylist_get_bool(other, key);
1212
1213 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1214 if (!equal) {
1215 *sstring = cpl_strdup(svalue == 0 ? "F" : "T");
1216 *ostring = cpl_strdup(ovalue == 0 ? "F" : "T");
1217 }
1218 break;
1219 }
1220
1221 case CPL_TYPE_INT: {
1222 const int svalue = cpl_propertylist_get_int(self, key);
1223 const int ovalue = cpl_propertylist_get_int(other, key);
1224
1225 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1226 if (!equal) {
1227 *sstring = cpl_sprintf("%d", svalue);
1228 *ostring = cpl_sprintf("%d", ovalue);
1229 }
1230 break;
1231 }
1232
1233 case CPL_TYPE_LONG: {
1234 const long svalue = cpl_propertylist_get_long(self, key);
1235 const long ovalue = cpl_propertylist_get_long(other, key);
1236
1237 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1238 if (!equal) {
1239 *sstring = cpl_sprintf("%ld", svalue);
1240 *ostring = cpl_sprintf("%ld", ovalue);
1241 }
1242 break;
1243 }
1244
1245 case CPL_TYPE_FLOAT: {
1246 const double svalue = (double)cpl_propertylist_get_float(self, key);
1247 const double ovalue = (double)cpl_propertylist_get_float(other, key);
1248
1249 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
1250 if (!equal) {
1251 *sstring = cpl_sprintf("%f", svalue);
1252 *ostring = cpl_sprintf("%f", ovalue);
1253 }
1254 break;
1255 }
1256
1257 case CPL_TYPE_DOUBLE: {
1258 const double svalue = cpl_propertylist_get_double(self, key);
1259 const double ovalue = cpl_propertylist_get_double(other, key);
1260
1261 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
1262 if (!equal) {
1263 *sstring = cpl_sprintf("%g", svalue);
1264 *ostring = cpl_sprintf("%g", ovalue);
1265 }
1266 break;
1267 }
1268 case CPL_TYPE_STRING: {
1269 const char * svalue = cpl_propertylist_get_string(self, key);
1270 const char * ovalue = cpl_propertylist_get_string(other, key);
1271
1272 equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
1273 if (!equal) {
1274 *sstring = cpl_strdup(svalue);
1275 *ostring = cpl_strdup(ovalue);
1276 }
1277 break;
1278 }
1279 default:
1280 /* Unknown property type */
1281#ifdef NDEBUG
1282 equal = CPL_FALSE;
1283#endif
1284 assert( 0 );
1285
1286 }
1287
1288 if (!equal) {
1289 assert( *sstring != NULL );
1290 assert( *ostring != NULL );
1291 }
1292
1293 return equal;
1294
1295}
int irplib_framelist_get_size(const irplib_framelist *self)
Get the size of a framelist.
cpl_frame * irplib_framelist_unset(irplib_framelist *self, int pos, cpl_propertylist **plist)
Erase a frame from a framelist and return it to the caller.
cpl_error_code irplib_framelist_set(irplib_framelist *self, cpl_frame *frame, int pos)
Add a frame to a framelist.
cpl_frameset * irplib_frameset_cast(const irplib_framelist *self)
Create a CPL frameset from an irplib_framelist.
irplib_framelist * irplib_framelist_extract(const irplib_framelist *self, const char *tag)
Extract the frames with the given tag from a framelist.
irplib_framelist * irplib_framelist_extract_regexp(const irplib_framelist *self, const char *regexp, cpl_boolean invert)
Extract the frames with the given tag from a framelist.
cpl_error_code irplib_framelist_load_propertylist(irplib_framelist *self, int pos, int ind, const char *regexp, cpl_boolean invert)
Load the propertylist of the specified frame in the framelist.
cpl_frame * irplib_framelist_get(irplib_framelist *self, int pos)
Get the specified frame from the framelist.
irplib_framelist * irplib_framelist_cast(const cpl_frameset *frameset)
Create an irplib_framelist from a cpl_framelist.
void irplib_framelist_delete(irplib_framelist *self)
Deallocate an irplib_framelist with its frames and properties.
void irplib_framelist_empty(irplib_framelist *self)
Erase all frames from a framelist.
cpl_error_code irplib_framelist_set_tag_all(irplib_framelist *self, const char *tag)
Set the tag of all frames in the list.
cpl_error_code irplib_framelist_erase(irplib_framelist *self, int pos)
Erase a frame from a framelist and delete it and its propertylist.
cpl_error_code irplib_framelist_set_propertylist(irplib_framelist *self, int pos, const cpl_propertylist *list)
Duplicate a propertylist to the specified position in the framelist.
cpl_propertylist * irplib_framelist_get_propertylist(irplib_framelist *self, int pos)
Get the propertylist of the specified frame in the framelist.
irplib_framelist * irplib_framelist_new(void)
Create an empty framelist.
const cpl_propertylist * irplib_framelist_get_propertylist_const(const irplib_framelist *self, int pos)
Get the propertylist of the specified frame in the framelist.
const cpl_frame * irplib_framelist_get_const(const irplib_framelist *self, int pos)
Get the specified frame from the framelist.
cpl_error_code irplib_framelist_load_propertylist_all(irplib_framelist *self, int ind, const char *regexp, cpl_boolean invert)
Load the propertylists of all frames in the framelist.
cpl_imagelist * irplib_imagelist_load_framelist(const irplib_framelist *self, cpl_type pixeltype, int planenum, int extnum)
Load an imagelist from a framelist.
cpl_error_code irplib_framelist_contains(const irplib_framelist *self, const char *key, cpl_type type, cpl_boolean is_equal, double fp_tol)
Verify that a property is present for all frames.