38 #include "irplib_framelist.h"
39 #include "irplib_utils.h"
44 #include <sys/types.h>
55 struct _irplib_framelist_ {
58 cpl_propertylist ** propertylist;
67 static void irplib_framelist_set_size(irplib_framelist *)
68 #if defined __GNUC__ && __GNUC__ >= 4
69 __attribute__((nonnull))
73 static cpl_boolean irplib_property_equal(
const cpl_propertylist *,
74 const cpl_propertylist *,
75 const char *, cpl_type,
double,
77 #if defined __GNUC__ && __GNUC__ >= 4
78 __attribute__((nonnull))
181 return (irplib_framelist *) cpl_calloc(1,
sizeof(irplib_framelist));
212 irplib_framelist *
self;
213 const cpl_frame * frame;
217 cpl_ensure(frameset != NULL, CPL_ERROR_NULL_INPUT, NULL);
222 for (i = 0, frame = cpl_frameset_get_first_const(frameset);
224 i++, frame = cpl_frameset_get_next_const(frameset)) {
226 cpl_frame * copy = cpl_frame_duplicate(frame);
230 assert(error == CPL_ERROR_NONE);
234 assert(self->size == cpl_frameset_get_size(frameset));
257 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
260 new = cpl_frameset_new();
262 for (i = 0; i <
self->size; i++) {
263 cpl_frame * frame = cpl_frame_duplicate(self->frame[i]);
264 const cpl_error_code error = cpl_frameset_insert(
new, frame);
266 assert(error == CPL_ERROR_NONE);
270 assert(self->size == cpl_frameset_get_size(
new));
294 irplib_framelist *
new;
298 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
299 cpl_ensure(tag != NULL, CPL_ERROR_NULL_INPUT, NULL);
304 for (i = 0; i <
self->size; i++) {
305 const cpl_frame * frame =
self->frame[i];
306 const char * ftag = cpl_frame_get_tag(frame);
308 cpl_error_code error;
313 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
316 if (strcmp(tag, ftag))
continue;
318 copy = cpl_frame_duplicate(frame);
321 assert(error == CPL_ERROR_NONE);
323 if (self->propertylist[i] != NULL)
new->propertylist[newsize]
324 = cpl_propertylist_duplicate(self->propertylist[i]);
329 assert( newsize == new->size );
332 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
333 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
334 "The list of %d frame(s) has no frames "
335 "with tag: %s", self->size, tag);
337 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
338 "The list of frame(s) has no frames "
339 "with the given tag");
365 irplib_framelist *
new;
368 const int xor = invert == CPL_FALSE ? 0 : 1;
372 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
373 cpl_ensure(regexp != NULL, CPL_ERROR_NULL_INPUT, NULL);
375 error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
376 cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, NULL);
381 for (i = 0; i <
self->size; i++) {
382 const cpl_frame * frame =
self->frame[i];
383 const char * tag = cpl_frame_get_tag(frame);
390 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
393 if ((regexec(&re, tag, (
size_t)0, NULL, 0) == REG_NOMATCH ? 1 : 0)
396 copy = cpl_frame_duplicate(frame);
399 assert(error == CPL_ERROR_NONE);
401 if (self->propertylist[i] != NULL)
new->propertylist[newsize]
402 = cpl_propertylist_duplicate(self->propertylist[i]);
410 assert( newsize == new->size );
413 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
414 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
415 "The list of %d frame(s) has no frames "
416 "that match: %s", self->size, regexp);
418 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
419 "The list of frames has no frames "
420 "that match the regular expression");
441 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, -1);
458 IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
460 IRPLIB_DIAG_PRAGMA_POP;
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);
481 return self->frame[pos];
498 const cpl_propertylist * list)
501 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
502 cpl_ensure_code(list != NULL, CPL_ERROR_NULL_INPUT);
503 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
504 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
506 cpl_propertylist_delete(self->propertylist[pos]);
508 self->propertylist[pos] = cpl_propertylist_duplicate(list);
510 cpl_ensure_code(self->propertylist[pos] != NULL, cpl_error_get_code());
512 return CPL_ERROR_NONE;
533 IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
536 IRPLIB_DIAG_PRAGMA_POP;
553 const irplib_framelist *
self,
556 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
557 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
558 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
560 cpl_ensure(self->propertylist[pos] != NULL,
561 CPL_ERROR_DATA_NOT_FOUND, NULL);
563 return self->propertylist[pos];
589 const char * filename;
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);
597 filename = cpl_frame_get_filename(self->frame[pos]);
599 cpl_ensure_code(filename != NULL, cpl_error_get_code());
601 cpl_propertylist_delete(self->propertylist[pos]);
603 self->propertylist[pos] = cpl_propertylist_load_regexp(filename, ind,
607 if (self->propertylist[pos] == NULL) {
608 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
609 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
"Could "
610 "not load FITS header from '%s' using "
611 "regexp '%s'", filename, regexp);
613 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
614 "Could not load FITS header");
618 return CPL_ERROR_NONE;
648 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
649 cpl_ensure_code(regexp != NULL, CPL_ERROR_NULL_INPUT);
651 for (i=0; i <
self->size; i++) {
652 if (self->propertylist[i] == NULL)
657 cpl_error_get_code());
660 nprops += cpl_propertylist_get_size(self->propertylist[i]);
664 cpl_msg_info(cpl_func,
"List of %d frames has %d properties", nfiles,
667 return CPL_ERROR_NONE;
688 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
689 cpl_ensure_code(tag != NULL, CPL_ERROR_NULL_INPUT);
691 for (i=0; i <
self->size; i++)
692 cpl_ensure_code(!cpl_frame_set_tag(self->frame[i], tag),
693 cpl_error_get_code());
695 return CPL_ERROR_NONE;
718 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
719 cpl_ensure_code(frame != NULL, CPL_ERROR_NULL_INPUT);
720 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
722 if (pos == self->size) {
726 irplib_framelist_set_size(
self);
730 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
732 cpl_frame_delete(self->frame[pos]);
733 cpl_propertylist_delete(self->propertylist[pos]);
736 self->frame[pos] = frame;
737 self->propertylist[pos] = NULL;
739 return CPL_ERROR_NONE;
758 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
759 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
760 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
764 cpl_frame_delete(self->frame[pos]);
765 cpl_propertylist_delete(self->propertylist[pos]);
768 for (i = pos+1; i <
self->size; i++) {
770 self->frame[i-1] =
self->frame[i];
772 self->propertylist[i-1] =
self->propertylist[i];
778 irplib_framelist_set_size(
self);
780 return CPL_ERROR_NONE;
804 cpl_propertylist ** plist)
811 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
812 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
813 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
816 frame =
self->frame[pos];
819 *plist =
self->propertylist[pos];
821 cpl_propertylist_delete(self->propertylist[pos]);
825 for (i = pos+1; i <
self->size; i++) {
827 self->frame[i-1] =
self->frame[i];
829 self->propertylist[i-1] =
self->propertylist[i];
835 irplib_framelist_set_size(
self);
855 while (self->size > 0) {
857 cpl_frame_delete(self->frame[self->size]);
858 cpl_propertylist_delete(self->propertylist[self->size]);
863 irplib_framelist_set_size(
self);
910 const char * key, cpl_type type,
911 cpl_boolean is_equal,
double fp_tol)
916 cpl_type type_0 = CPL_TYPE_INVALID;
920 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
921 cpl_ensure_code(key != NULL, CPL_ERROR_NULL_INPUT);
922 cpl_ensure_code(fp_tol >= 0.0, CPL_ERROR_ILLEGAL_INPUT);
924 for (i=0; i <
self->size; i++) {
928 if (self->propertylist[i] == NULL)
continue;
929 if (ifirst < 0) ifirst = i;
931 type_i = cpl_propertylist_get_type(self->propertylist[i], key);
933 if (type_i == CPL_TYPE_INVALID) {
934 if (type == CPL_TYPE_INVALID)
935 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
936 cpl_error_set_message(cpl_func, cpl_error_get_code(),
"FITS "
937 "key '%s' is missing from file %s", key,
938 cpl_frame_get_filename(self->frame[i]));
940 cpl_error_set_message(cpl_func, cpl_error_get_code(),
941 "FITS key '%s' [%s] is missing from file "
942 "%s", key, cpl_type_get_name(type),
943 cpl_frame_get_filename(self->frame[i]));
945 cpl_error_set_message(cpl_func, cpl_error_get_code(),
946 "A FITS key is missing from a file");
948 cpl_error_set_message(cpl_func, cpl_error_get_code(),
949 "A FITS key is missing from a file");
951 return cpl_error_get_code();
954 if (type != CPL_TYPE_INVALID && type_i != type) {
955 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
956 return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
957 "FITS key '%s' has type %s instead of "
958 "%s in file %s", key,
959 cpl_type_get_name(type_i),
960 cpl_type_get_name(type),
961 cpl_frame_get_filename(self->frame[i]));
963 return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
964 "A FITS key had an unexpected type");
969 if (!is_equal)
continue;
971 if (type_0 == CPL_TYPE_INVALID) {
976 if (type_i != type_0) {
977 assert( type == CPL_TYPE_INVALID );
978 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
979 return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
980 "FITS key '%s' has different types "
981 "(%s <=> %s) in files %s and %s", key,
982 cpl_type_get_name(type_0),
983 cpl_type_get_name(type_i),
984 cpl_frame_get_filename(self->frame[0]),
985 cpl_frame_get_filename(self->frame[i]));
987 return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
988 "A FITS key has different types in "
993 if (irplib_property_equal(self->propertylist[ifirst],
994 self->propertylist[i],
995 key, type_0, fp_tol, &value_0, &value_i))
998 if ((type_0 == CPL_TYPE_FLOAT || type_0 == CPL_TYPE_DOUBLE)
1000 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1001 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
"FITS"
1002 " key '%s' [%s] has values that differ by "
1003 "more than %g (%s <=> %s) in files %s and %s",
1004 key, cpl_type_get_name(type_0), fp_tol,
1006 cpl_frame_get_filename(self->frame[0]),
1007 cpl_frame_get_filename(self->frame[i]));
1009 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
"A "
1010 "FITS key has values that differ by more "
1011 "than the allowed tolerance in two file");
1014 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1015 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
1016 "FITS key '%s' [%s] has different values "
1017 "(%s <=> %s) in files %s and %s", key,
1018 cpl_type_get_name(type_0),
1020 cpl_frame_get_filename(self->frame[0]),
1021 cpl_frame_get_filename(self->frame[i]));
1023 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
"A "
1024 "FITS key has different values in two files");
1030 return cpl_error_get_code();
1033 return CPL_ERROR_NONE;
1058 cpl_imagelist * list = NULL;
1059 cpl_image * image = NULL;
1063 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
1064 cpl_ensure(extnum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
1065 cpl_ensure(planenum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
1067 list = cpl_imagelist_new();
1069 for (i=0; i <
self->size; i++, image = NULL) {
1070 const char * filename = cpl_frame_get_filename(self->frame[i]);
1071 cpl_error_code error;
1073 if (filename == NULL)
break;
1075 image = cpl_image_load(filename, pixeltype, planenum, extnum);
1076 if (image == NULL) {
1077 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1078 (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
1079 "Could not load FITS-image from plane "
1080 "%d in extension %d in file %s",
1081 planenum, extnum, filename);
1083 (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
1084 "Could not load FITS-image");
1089 error = cpl_imagelist_set(list, image, i);
1090 assert(error == CPL_ERROR_NONE);
1093 cpl_image_delete(image);
1095 if (cpl_imagelist_get_size(list) != self->size) {
1096 cpl_imagelist_delete(list);
1098 assert(cpl_error_get_code() != CPL_ERROR_NONE);
1122 static void irplib_framelist_set_size(irplib_framelist *
self)
1126 assert(
self != NULL);
1128 if (self->size == 0) {
1130 cpl_free(self->frame);
1131 cpl_free(self->propertylist);
1133 self->propertylist = NULL;
1137 self->frame = cpl_realloc(self->frame, self->size *
sizeof(cpl_frame*));
1138 self->propertylist =
1139 cpl_realloc(self->propertylist,
1140 self->size *
sizeof(cpl_propertylist*));
1170 static cpl_boolean irplib_property_equal(
const cpl_propertylist *
self,
1171 const cpl_propertylist * other,
1172 const char * key, cpl_type type,
1174 char ** sstring,
char ** ostring)
1180 assert(
self != NULL);
1181 assert(other != NULL);
1182 assert(key != NULL);
1183 assert(sstring != NULL);
1184 assert(ostring != NULL);
1187 assert(cpl_propertylist_get_type(other, key) == type);
1188 assert(fp_tol >= 0.0);
1190 if (
self == other)
return CPL_TRUE;
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);
1198 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1200 *sstring = cpl_sprintf(
"%c", svalue);
1201 *ostring = cpl_sprintf(
"%c", ovalue);
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);
1210 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1212 *sstring = cpl_strdup(svalue == 0 ?
"F" :
"T");
1213 *ostring = cpl_strdup(ovalue == 0 ?
"F" :
"T");
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);
1222 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1224 *sstring = cpl_sprintf(
"%d", svalue);
1225 *ostring = cpl_sprintf(
"%d", ovalue);
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);
1234 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1236 *sstring = cpl_sprintf(
"%ld", svalue);
1237 *ostring = cpl_sprintf(
"%ld", ovalue);
1242 case CPL_TYPE_FLOAT: {
1243 const double svalue = (double)cpl_propertylist_get_float(
self, key);
1244 const double ovalue = (double)cpl_propertylist_get_float(other, key);
1246 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
1248 *sstring = cpl_sprintf(
"%f", svalue);
1249 *ostring = cpl_sprintf(
"%f", ovalue);
1254 case CPL_TYPE_DOUBLE: {
1255 const double svalue = cpl_propertylist_get_double(
self, key);
1256 const double ovalue = cpl_propertylist_get_double(other, key);
1258 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
1260 *sstring = cpl_sprintf(
"%g", svalue);
1261 *ostring = cpl_sprintf(
"%g", ovalue);
1265 case CPL_TYPE_STRING: {
1266 const char * svalue = cpl_propertylist_get_string(
self, key);
1267 const char * ovalue = cpl_propertylist_get_string(other, key);
1269 equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
1271 *sstring = cpl_strdup(svalue);
1272 *ostring = cpl_strdup(ovalue);
1285 assert( *sstring != NULL );
1286 assert( *ostring != NULL );