CR2RE Pipeline Reference Manual 1.7.0
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{
48 int size;
49 cpl_frame **frame;
50 cpl_propertylist **propertylist;
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 *,
67 cpl_type,
68 double,
69 char **,
70 char **)
71#if defined __GNUC__ && __GNUC__ >= 4
72 __attribute__((nonnull))
73#endif
74 ;
75
76/*----------------------------------------------------------------------------*/
155/*----------------------------------------------------------------------------*/
156
158
159/*-----------------------------------------------------------------------------
160 Function codes
161 -----------------------------------------------------------------------------*/
162
163/*----------------------------------------------------------------------------*/
171/*----------------------------------------------------------------------------*/
172irplib_framelist *
174{
175 return (irplib_framelist *)cpl_calloc(1, sizeof(irplib_framelist));
176}
177
178/*----------------------------------------------------------------------------*/
183/*----------------------------------------------------------------------------*/
184void
185irplib_framelist_delete(irplib_framelist *self)
186{
188 cpl_free(self);
189}
190
191
192/*----------------------------------------------------------------------------*/
201/*----------------------------------------------------------------------------*/
202irplib_framelist *
203irplib_framelist_cast(const cpl_frameset *frameset)
204{
205 irplib_framelist *self;
206 int i;
207
208 cpl_ensure(frameset != NULL, CPL_ERROR_NULL_INPUT, NULL);
209
210 /* The function cannot fail now */
211 self = irplib_framelist_new();
212
213 for (i = 0; i < cpl_frameset_get_size(frameset); i++) {
214 const cpl_frame *frame = cpl_frameset_get_position_const(frameset, i);
215
216 cpl_frame *copy = cpl_frame_duplicate(frame);
217
218#ifndef NDEBUG
219 const cpl_error_code error =
220#endif
221 irplib_framelist_set(self, copy, i);
222
223 assert(error == CPL_ERROR_NONE);
224 }
225
226 assert(self->size == cpl_frameset_get_size(frameset));
227
228 return self;
229}
230
231
232/*----------------------------------------------------------------------------*/
241/*----------------------------------------------------------------------------*/
242cpl_frameset *
243irplib_frameset_cast(const irplib_framelist *self)
244{
245 cpl_frameset *new;
246 int i;
247
248 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
249
250 /* The function cannot fail now */
251 new = cpl_frameset_new();
252
253 for (i = 0; i < self->size; i++) {
254 cpl_frame *frame = cpl_frame_duplicate(self->frame[i]);
255#ifndef NDEBUG
256 const cpl_error_code error =
257#endif
258 cpl_frameset_insert(new, frame);
259
260 assert(error == CPL_ERROR_NONE);
261 }
262
263 assert(self->size == cpl_frameset_get_size(new));
264
265 return new;
266}
267
268
269/*----------------------------------------------------------------------------*/
281/*----------------------------------------------------------------------------*/
282irplib_framelist *
283irplib_framelist_extract(const irplib_framelist *self, const char *tag)
284{
285 irplib_framelist *new;
286 int i, newsize;
287
288
289 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
290 cpl_ensure(tag != NULL, CPL_ERROR_NULL_INPUT, NULL);
291
292 new = irplib_framelist_new();
293 newsize = 0;
294
295 for (i = 0; i < self->size; i++) {
296 const cpl_frame *frame = self->frame[i];
297 const char *ftag = cpl_frame_get_tag(frame);
298 cpl_frame *copy;
299 cpl_error_code code;
300
301 if (ftag == NULL) {
302 /* The frame is ill-formed */
304 (void)cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
305 return NULL;
306 }
307
308 if (strcmp(tag, ftag))
309 continue;
310
311 copy = cpl_frame_duplicate(frame);
312
313 code = irplib_framelist_set(new, copy, newsize);
314 if (code != CPL_ERROR_NONE)
315 break; /* Should not be possible */
316
317 if (self->propertylist[i] != NULL)
318 new->propertylist[newsize] =
319 cpl_propertylist_duplicate(self->propertylist[i]);
320
321 newsize++;
322 }
323
324 assert(newsize == new->size);
325
326 if (newsize == 0) {
327#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
328 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
329 "The list of %d frame(s) has no frames "
330 "with tag: %s",
331 self->size, tag);
332#else
333 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
334 "The list of frame(s) has no frames "
335 "with the given tag");
336#endif
338 new = NULL;
339 }
340
341 return new;
342}
343
344/*----------------------------------------------------------------------------*/
354/*----------------------------------------------------------------------------*/
355irplib_framelist *
356irplib_framelist_extract_regexp(const irplib_framelist *self,
357 const char *regexp,
358 cpl_boolean invert)
359{
360 irplib_framelist *new;
361 int error;
362 int i, newsize;
363 const int xor_val = (invert == CPL_FALSE ? 0 : 1);
364 regex_t re;
365
366
367 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
368 cpl_ensure(regexp != NULL, CPL_ERROR_NULL_INPUT, NULL);
369
370 error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
371 cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, NULL);
372
373 new = irplib_framelist_new();
374 newsize = 0;
375
376 for (i = 0; i < self->size; i++) {
377 const cpl_frame *frame = self->frame[i];
378 const char *tag = cpl_frame_get_tag(frame);
379 cpl_frame *copy;
380
381 if (tag == NULL) {
382 /* The frame is ill-formed */
384 regfree(&re);
385 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
386 }
387
388 if ((regexec(&re, tag, (size_t)0, NULL, 0) == REG_NOMATCH ? 1 : 0) ^
389 xor_val)
390 continue;
391
392 copy = cpl_frame_duplicate(frame);
393
394 error = (int)irplib_framelist_set(new, copy, newsize);
395 assert(error == CPL_ERROR_NONE);
396
397 if (self->propertylist[i] != NULL)
398 new->propertylist[newsize] =
399 cpl_propertylist_duplicate(self->propertylist[i]);
400
401 newsize++;
402 }
403
404 regfree(&re);
405
406 assert(newsize == new->size);
407
408 if (newsize == 0) {
409#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
410 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
411 "The list of %d frame(s) has no frames "
412 "that match: %s",
413 self->size, regexp);
414#else
415 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
416 "The list of frames has no frames "
417 "that match the regular expression");
418#endif
420 new = NULL;
421 }
422
423 return new;
424}
425
426
427/*----------------------------------------------------------------------------*/
434/*----------------------------------------------------------------------------*/
435int
436irplib_framelist_get_size(const irplib_framelist *self)
437{
438 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, -1);
439
440 return self->size;
441}
442
443/*----------------------------------------------------------------------------*/
451/*----------------------------------------------------------------------------*/
452cpl_frame *
453irplib_framelist_get(irplib_framelist *self, int pos)
454{
455 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
456 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
457 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
458
459 return self->frame[pos];
460}
461
462
463/*----------------------------------------------------------------------------*/
472/*----------------------------------------------------------------------------*/
473const cpl_frame *
474irplib_framelist_get_const(const irplib_framelist *self, int pos)
475{
476 /* Code duplicated from irplib_framelist_get() */
477 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
478 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
479 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
480
481 return self->frame[pos];
482}
483
484
485/*----------------------------------------------------------------------------*/
494/*----------------------------------------------------------------------------*/
495cpl_error_code
497 int pos,
498 const cpl_propertylist *list)
499{
500 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
501 cpl_ensure_code(list != NULL, CPL_ERROR_NULL_INPUT);
502 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
503 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
504
505 cpl_propertylist_delete(self->propertylist[pos]);
506
507 self->propertylist[pos] = cpl_propertylist_duplicate(list);
508
509 cpl_ensure_code(self->propertylist[pos] != NULL, cpl_error_get_code());
510
511 return CPL_ERROR_NONE;
512}
513
514
515/*----------------------------------------------------------------------------*/
526/*----------------------------------------------------------------------------*/
527cpl_propertylist *
528irplib_framelist_get_propertylist(irplib_framelist *self, int pos)
529{
530 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
531 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
532 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
533
534 cpl_ensure(self->propertylist[pos] != NULL, CPL_ERROR_DATA_NOT_FOUND, NULL);
535
536 return self->propertylist[pos];
537}
538
539
540/*----------------------------------------------------------------------------*/
552/*----------------------------------------------------------------------------*/
553const cpl_propertylist *
554irplib_framelist_get_propertylist_const(const irplib_framelist *self, 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, CPL_ERROR_DATA_NOT_FOUND, NULL);
562
563 return self->propertylist[pos];
564}
565
566
567/*----------------------------------------------------------------------------*/
581/*----------------------------------------------------------------------------*/
582cpl_error_code
584 int pos,
585 int ind,
586 const char *regexp,
587 cpl_boolean invert)
588{
589 const char *filename;
590
591
592 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
593 cpl_ensure_code(regexp != NULL, CPL_ERROR_NULL_INPUT);
594 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
595 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
596
597 filename = cpl_frame_get_filename(self->frame[pos]);
598
599 cpl_ensure_code(filename != NULL, cpl_error_get_code());
600
601 cpl_propertylist_delete(self->propertylist[pos]);
602
603 self->propertylist[pos] =
604 cpl_propertylist_load_regexp(filename, ind, regexp, invert ? 1 : 0);
605
606 if (self->propertylist[pos] == NULL) {
607#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
608 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
609 "Could "
610 "not load FITS header from '%s' using "
611 "regexp '%s'",
612 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/*----------------------------------------------------------------------------*/
637/*----------------------------------------------------------------------------*/
638cpl_error_code
640 int ind,
641 const char *regexp,
642 cpl_boolean invert)
643{
644 int nprops = 0;
645 int nfiles = 0;
646 int i;
647
648 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
649 cpl_ensure_code(regexp != NULL, CPL_ERROR_NULL_INPUT);
650
651 for (i = 0; i < self->size; i++) {
652 if (self->propertylist[i] == NULL)
653 cpl_ensure_code(!irplib_framelist_load_propertylist(self, i, ind,
654 regexp, invert),
655 cpl_error_get_code());
656 /* Counting just for diagnostics - this actually causes
657 the whole list to be reiterated :-( */
658 nprops += cpl_propertylist_get_size(self->propertylist[i]);
659 nfiles++;
660 }
661
662 cpl_msg_info(cpl_func, "List of %d frames has %d properties", nfiles,
663 nprops);
664
665 return CPL_ERROR_NONE;
666}
667
668
669/*----------------------------------------------------------------------------*/
677/*----------------------------------------------------------------------------*/
678cpl_error_code
679irplib_framelist_set_tag_all(irplib_framelist *self, const char *tag)
680{
681 int i;
682
683 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
684 cpl_ensure_code(tag != NULL, CPL_ERROR_NULL_INPUT);
685
686 for (i = 0; i < self->size; i++)
687 cpl_ensure_code(!cpl_frame_set_tag(self->frame[i], tag),
688 cpl_error_get_code());
689
690 return CPL_ERROR_NONE;
691}
692
693
694/*----------------------------------------------------------------------------*/
708/*----------------------------------------------------------------------------*/
709cpl_error_code
710irplib_framelist_set(irplib_framelist *self, cpl_frame *frame, int pos)
711{
712 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
713 cpl_ensure_code(frame != NULL, CPL_ERROR_NULL_INPUT);
714 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
715
716 if (pos == self->size) {
717 self->size++;
718
719 irplib_framelist_set_size(self);
720 }
721 else {
722 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
723
724 cpl_frame_delete(self->frame[pos]);
725 cpl_propertylist_delete(self->propertylist[pos]);
726 }
727
728 self->frame[pos] = frame;
729 self->propertylist[pos] = NULL;
730
731 return CPL_ERROR_NONE;
732}
733
734/*----------------------------------------------------------------------------*/
743/*----------------------------------------------------------------------------*/
744cpl_error_code
745irplib_framelist_erase(irplib_framelist *self, int pos)
746{
747 int i;
748
749 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
750 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
751 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
752
753
754 /* Delete the specified frame and its propertylist */
755 cpl_frame_delete(self->frame[pos]);
756 cpl_propertylist_delete(self->propertylist[pos]);
757
758 /* Move following frames down one position */
759 for (i = pos + 1; i < self->size; i++) {
760 self->frame[i - 1] = self->frame[i];
761
762 self->propertylist[i - 1] = self->propertylist[i];
763 }
764
765 self->size--;
766
767 irplib_framelist_set_size(self);
768
769 return CPL_ERROR_NONE;
770}
771
772
773/*----------------------------------------------------------------------------*/
789/*----------------------------------------------------------------------------*/
790cpl_frame *
791irplib_framelist_unset(irplib_framelist *self,
792 int pos,
793 cpl_propertylist **plist)
794
795{
796 cpl_frame *frame;
797 int i;
798
799
800 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
801 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
802 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
803
804 /* Get the specified frame and its propertylist */
805 frame = self->frame[pos];
806
807 if (plist != NULL)
808 *plist = self->propertylist[pos];
809 else
810 cpl_propertylist_delete(self->propertylist[pos]);
811
812
813 /* Move following frames down one position */
814 for (i = pos + 1; i < self->size; i++) {
815 self->frame[i - 1] = self->frame[i];
816
817 self->propertylist[i - 1] = self->propertylist[i];
818 }
819
820 self->size--;
821
822 irplib_framelist_set_size(self);
823
824 return frame;
825}
826
827/*----------------------------------------------------------------------------*/
834/*----------------------------------------------------------------------------*/
835void
836irplib_framelist_empty(irplib_framelist *self)
837{
838 if (self != NULL) {
839 /* Deallocate all frames and their propertylists */
840 while (self->size > 0) {
841 self->size--;
842 cpl_frame_delete(self->frame[self->size]);
843 cpl_propertylist_delete(self->propertylist[self->size]);
844 }
845
846 /* Deallocate the arrays */
847 irplib_framelist_set_size(self);
848 }
849}
850
851
852/*----------------------------------------------------------------------------*/
890/*----------------------------------------------------------------------------*/
891cpl_error_code
892irplib_framelist_contains(const irplib_framelist *self,
893 const char *key,
894 cpl_type type,
895 cpl_boolean is_equal,
896 double fp_tol)
897{
898 char *value_0 = NULL;
899 char *value_i = NULL;
900 cpl_type type_0 = CPL_TYPE_INVALID;
901 int i, ifirst = -1; /* First non-NULL propertylist */
902
903
904 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
905 cpl_ensure_code(key != NULL, CPL_ERROR_NULL_INPUT);
906 cpl_ensure_code(fp_tol >= 0.0, CPL_ERROR_ILLEGAL_INPUT);
907
908 for (i = 0; i < self->size; i++) {
909 cpl_type type_i;
910
911
912 if (self->propertylist[i] == NULL)
913 continue;
914 if (ifirst < 0)
915 ifirst = i;
916
917 type_i = cpl_propertylist_get_type(self->propertylist[i], key);
918
919 if (type_i == CPL_TYPE_INVALID) {
920 if (type == CPL_TYPE_INVALID)
921#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
922 cpl_error_set_message(cpl_func, cpl_error_get_code(),
923 "FITS "
924 "key '%s' is missing from file %s",
925 key,
926 cpl_frame_get_filename(self->frame[i]));
927 else
928 cpl_error_set_message(cpl_func, cpl_error_get_code(),
929 "FITS key '%s' [%s] is missing from file "
930 "%s",
931 key, cpl_type_get_name(type),
932 cpl_frame_get_filename(self->frame[i]));
933#else
934 cpl_error_set_message(cpl_func, cpl_error_get_code(),
935 "A FITS key is missing from a file");
936 else
937 cpl_error_set_message(cpl_func, cpl_error_get_code(),
938 "A FITS key is missing from a file");
939#endif
940 return cpl_error_get_code();
941 }
942
943 if (type != CPL_TYPE_INVALID && type_i != type) {
944#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
945 return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
946 "FITS key '%s' has type %s instead of "
947 "%s in file %s",
948 key, cpl_type_get_name(type_i),
949 cpl_type_get_name(type),
950 cpl_frame_get_filename(
951 self->frame[i]));
952#else
953 return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
954 "A FITS key had an unexpected type");
955#endif
956 }
957
958 if (!is_equal)
959 continue;
960
961 if (type_0 == CPL_TYPE_INVALID) {
962 type_0 = type_i;
963 continue;
964 }
965
966 if (type_i != type_0) {
967 assert(type == CPL_TYPE_INVALID);
968#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
969 return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
970 "FITS key '%s' has different types "
971 "(%s <=> %s) in files %s and %s",
972 key, cpl_type_get_name(type_0),
973 cpl_type_get_name(type_i),
974 cpl_frame_get_filename(self->frame[0]),
975 cpl_frame_get_filename(
976 self->frame[i]));
977#else
978 return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
979 "A FITS key has different types in "
980 "two files");
981#endif
982 }
983
984 if (irplib_property_equal(self->propertylist[ifirst],
985 self->propertylist[i], key, type_0, fp_tol,
986 &value_0, &value_i))
987 continue;
988
989 if ((type_0 == CPL_TYPE_FLOAT || type_0 == CPL_TYPE_DOUBLE) &&
990 fp_tol > 0.0) {
991#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
992 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
993 "FITS"
994 " key '%s' [%s] has values that differ by "
995 "more than %g (%s <=> %s) in files %s and %s",
996 key, cpl_type_get_name(type_0), fp_tol,
997 value_0, value_i,
998 cpl_frame_get_filename(self->frame[0]),
999 cpl_frame_get_filename(self->frame[i]));
1000#else
1001 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
1002 "A "
1003 "FITS key has values that differ by more "
1004 "than the allowed tolerance in two file");
1005#endif
1006 }
1007 else {
1008#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1009 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
1010 "FITS key '%s' [%s] has different values "
1011 "(%s <=> %s) in files %s and %s",
1012 key, cpl_type_get_name(type_0), value_0,
1013 value_i,
1014 cpl_frame_get_filename(self->frame[0]),
1015 cpl_frame_get_filename(self->frame[i]));
1016#else
1017 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
1018 "A "
1019 "FITS key has different values in two files");
1020#endif
1021 }
1022 cpl_free(value_0);
1023 cpl_free(value_i);
1024
1025 return cpl_error_get_code();
1026 }
1027
1028 return CPL_ERROR_NONE;
1029}
1030
1031
1032/*----------------------------------------------------------------------------*/
1045/*----------------------------------------------------------------------------*/
1046cpl_imagelist *
1047irplib_imagelist_load_framelist(const irplib_framelist *self,
1048 cpl_type pixeltype,
1049 int planenum,
1050 int extnum)
1051{
1052 cpl_imagelist *list = NULL;
1053 cpl_image *image = NULL;
1054 int i;
1055
1056
1057 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
1058 cpl_ensure(extnum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
1059 cpl_ensure(planenum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
1060
1061 list = cpl_imagelist_new();
1062
1063 for (i = 0; i < self->size; i++, image = NULL) {
1064 const char *filename = cpl_frame_get_filename(self->frame[i]);
1065 cpl_error_code code;
1066
1067 if (filename == NULL)
1068 break;
1069
1070 image = cpl_image_load(filename, pixeltype, planenum, extnum);
1071 if (image == NULL) {
1072#if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1073 (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
1074 "Could not load FITS-image from plane "
1075 "%d in extension %d in file %s",
1076 planenum, extnum, filename);
1077#else
1078 (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
1079 "Could not load FITS-image");
1080#endif
1081 break;
1082 }
1083
1084 code = cpl_imagelist_set(list, image, i);
1085 if (code != CPL_ERROR_NONE)
1086 break; /* Should not be possible */
1087 }
1088
1089 cpl_image_delete(image);
1090
1091 if (cpl_imagelist_get_size(list) != self->size) {
1092 cpl_imagelist_delete(list);
1093 list = NULL;
1094 (void)cpl_error_set_where(cpl_func);
1095 }
1096
1097 return list;
1098}
1099
1100
1102
1103
1104/*----------------------------------------------------------------------------*/
1116/*----------------------------------------------------------------------------*/
1117static void
1118irplib_framelist_set_size(irplib_framelist *self)
1119{
1120 assert(self != NULL);
1121
1122 if (self->size == 0) {
1123 /* The list has been emptied */
1124 cpl_free(self->frame);
1125 cpl_free(self->propertylist);
1126 self->frame = NULL;
1127 self->propertylist = NULL;
1128 }
1129 else if (self->size > 0) {
1130 /* Update the size of the arrays */
1131
1132 self->frame =
1133 cpl_realloc(self->frame, (size_t)self->size * sizeof(cpl_frame *));
1134 self->propertylist =
1135 cpl_realloc(self->propertylist,
1136 (size_t)self->size * sizeof(cpl_propertylist *));
1137 }
1138 else {
1139 (void)cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
1140 }
1141}
1142
1143/*----------------------------------------------------------------------------*/
1167/*----------------------------------------------------------------------------*/
1168static cpl_boolean
1169irplib_property_equal(const cpl_propertylist *self,
1170 const cpl_propertylist *other,
1171 const char *key,
1172 cpl_type type,
1173 double fp_tol,
1174 char **sstring,
1175 char **ostring)
1176{
1177 cpl_boolean equal;
1178
1179
1180 assert(self != NULL);
1181 assert(other != NULL);
1182 assert(key != NULL);
1183 assert(sstring != NULL);
1184 assert(ostring != NULL);
1185
1186 /* FIXME: disable for better performance also with debugging */
1187 assert(cpl_propertylist_get_type(other, key) == type);
1188 assert(fp_tol >= 0.0);
1189
1190 if (self == other)
1191 return CPL_TRUE;
1192
1193 switch (type) {
1194 case CPL_TYPE_CHAR: {
1195 const char svalue = cpl_propertylist_get_char(self, key);
1196 const char ovalue = cpl_propertylist_get_char(other, key);
1197
1198 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1199 if (!equal) {
1200 *sstring = cpl_sprintf("%c", svalue);
1201 *ostring = cpl_sprintf("%c", ovalue);
1202 }
1203 break;
1204 }
1205
1206 case CPL_TYPE_BOOL: {
1207 const int svalue = cpl_propertylist_get_bool(self, key);
1208 const int ovalue = cpl_propertylist_get_bool(other, key);
1209
1210 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1211 if (!equal) {
1212 *sstring = cpl_strdup(svalue == 0 ? "F" : "T");
1213 *ostring = cpl_strdup(ovalue == 0 ? "F" : "T");
1214 }
1215 break;
1216 }
1217
1218 case CPL_TYPE_INT: {
1219 const int svalue = cpl_propertylist_get_int(self, key);
1220 const int ovalue = cpl_propertylist_get_int(other, key);
1221
1222 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1223 if (!equal) {
1224 *sstring = cpl_sprintf("%d", svalue);
1225 *ostring = cpl_sprintf("%d", ovalue);
1226 }
1227 break;
1228 }
1229
1230 case CPL_TYPE_LONG: {
1231 const long svalue = cpl_propertylist_get_long(self, key);
1232 const long ovalue = cpl_propertylist_get_long(other, key);
1233
1234 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1235 if (!equal) {
1236 *sstring = cpl_sprintf("%ld", svalue);
1237 *ostring = cpl_sprintf("%ld", ovalue);
1238 }
1239 break;
1240 }
1241
1242 case CPL_TYPE_FLOAT: {
1243 const double svalue = (double)cpl_propertylist_get_float(self, key);
1244 const double ovalue =
1245 (double)cpl_propertylist_get_float(other, key);
1246
1247 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
1248 if (!equal) {
1249 *sstring = cpl_sprintf("%f", svalue);
1250 *ostring = cpl_sprintf("%f", ovalue);
1251 }
1252 break;
1253 }
1254
1255 case CPL_TYPE_DOUBLE: {
1256 const double svalue = cpl_propertylist_get_double(self, key);
1257 const double ovalue = cpl_propertylist_get_double(other, key);
1258
1259 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
1260 if (!equal) {
1261 *sstring = cpl_sprintf("%g", svalue);
1262 *ostring = cpl_sprintf("%g", ovalue);
1263 }
1264 break;
1265 }
1266 case CPL_TYPE_STRING: {
1267 const char *svalue = cpl_propertylist_get_string(self, key);
1268 const char *ovalue = cpl_propertylist_get_string(other, key);
1269
1270 equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
1271 if (!equal) {
1272 *sstring = cpl_strdup(svalue);
1273 *ostring = cpl_strdup(ovalue);
1274 }
1275 break;
1276 }
1277 default:
1278 /* Unknown property type */
1279#ifdef NDEBUG
1280 equal = CPL_FALSE;
1281#endif
1282 assert(0);
1283 }
1284
1285 if (!equal) {
1286 assert(*sstring != NULL);
1287 assert(*ostring != NULL);
1288 }
1289
1290 return equal;
1291}
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.