30 #include "irplib_framelist.h"
31 #include "irplib_utils.h"
36 #include <sys/types.h>
47 struct _irplib_framelist_ {
50 cpl_propertylist ** propertylist;
59 static void irplib_framelist_set_size(irplib_framelist *)
60 #if defined __GNUC__ && __GNUC__ >= 4
61 __attribute__((nonnull))
65 static cpl_boolean irplib_property_equal(
const cpl_propertylist *,
66 const cpl_propertylist *,
67 const char *, cpl_type,
double,
69 #if defined __GNUC__ && __GNUC__ >= 4
70 __attribute__((nonnull))
173 return (irplib_framelist *) cpl_calloc(1,
sizeof(irplib_framelist));
204 irplib_framelist *
self;
205 const cpl_frame *
frame;
209 cpl_ensure(frameset != NULL, CPL_ERROR_NULL_INPUT, NULL);
214 for (i = 0; i < cpl_frameset_get_size(frameset); i++)
216 frame = cpl_frameset_get_position_const(frameset, i);
218 cpl_frame * copy = cpl_frame_duplicate(frame);
222 assert(error == CPL_ERROR_NONE);
226 assert(self->size == cpl_frameset_get_size(frameset));
249 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
252 new = cpl_frameset_new();
254 for (i = 0; i <
self->size; i++) {
255 cpl_frame *
frame = cpl_frame_duplicate(self->frame[i]);
256 const cpl_error_code error = cpl_frameset_insert(
new, frame);
258 assert(error == CPL_ERROR_NONE);
262 assert(self->size == cpl_frameset_get_size(
new));
286 irplib_framelist *
new;
290 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
291 cpl_ensure(tag != NULL, CPL_ERROR_NULL_INPUT, NULL);
296 for (i = 0; i <
self->size; i++) {
297 const cpl_frame *
frame =
self->frame[i];
298 const char * ftag = cpl_frame_get_tag(frame);
300 cpl_error_code error;
305 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
308 if (strcmp(tag, ftag))
continue;
310 copy = cpl_frame_duplicate(frame);
313 assert(error == CPL_ERROR_NONE);
315 if (self->propertylist[i] != NULL)
new->propertylist[newsize]
316 = cpl_propertylist_duplicate(self->propertylist[i]);
321 assert( newsize == new->size );
324 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
325 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
326 "The list of %d frame(s) has no frames "
327 "with tag: %s", self->size, tag);
329 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
330 "The list of frame(s) has no frames "
331 "with the given tag");
357 irplib_framelist *
new;
360 const int xor = invert == CPL_FALSE ? 0 : 1;
364 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
365 cpl_ensure(regexp != NULL, CPL_ERROR_NULL_INPUT, NULL);
367 error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
368 cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, NULL);
373 for (i = 0; i <
self->size; i++) {
374 const cpl_frame *
frame =
self->frame[i];
375 const char * tag = cpl_frame_get_tag(frame);
382 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
385 if ((regexec(&re, tag, (
size_t)0, NULL, 0) == REG_NOMATCH ? 1 : 0)
388 copy = cpl_frame_duplicate(frame);
391 assert(error == CPL_ERROR_NONE);
393 if (self->propertylist[i] != NULL)
new->propertylist[newsize]
394 = cpl_propertylist_duplicate(self->propertylist[i]);
402 assert( newsize == new->size );
405 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
406 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
407 "The list of %d frame(s) has no frames "
408 "that match: %s", self->size, regexp);
410 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
411 "The list of frames has no frames "
412 "that match the regular expression");
433 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, -1);
450 IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
452 IRPLIB_DIAG_PRAGMA_POP;
469 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
470 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
471 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
473 return self->frame[pos];
490 const cpl_propertylist * list)
493 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
494 cpl_ensure_code(list != NULL, CPL_ERROR_NULL_INPUT);
495 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
496 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
498 cpl_propertylist_delete(self->propertylist[pos]);
500 self->propertylist[pos] = cpl_propertylist_duplicate(list);
502 cpl_ensure_code(self->propertylist[pos] != NULL, cpl_error_get_code());
504 return CPL_ERROR_NONE;
525 IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
528 IRPLIB_DIAG_PRAGMA_POP;
545 const irplib_framelist *
self,
548 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
549 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
550 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
552 cpl_ensure(self->propertylist[pos] != NULL,
553 CPL_ERROR_DATA_NOT_FOUND, NULL);
555 return self->propertylist[pos];
581 const char * filename;
584 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
585 cpl_ensure_code(regexp != NULL, CPL_ERROR_NULL_INPUT);
586 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
587 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
589 filename = cpl_frame_get_filename(self->frame[pos]);
591 cpl_ensure_code(filename != NULL, cpl_error_get_code());
593 cpl_propertylist_delete(self->propertylist[pos]);
595 self->propertylist[pos] = cpl_propertylist_load_regexp(filename, ind,
599 if (self->propertylist[pos] == NULL) {
600 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
601 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
"Could "
602 "not load FITS header from '%s' using "
603 "regexp '%s'", filename, regexp);
605 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
606 "Could not load FITS header");
610 return CPL_ERROR_NONE;
640 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
641 cpl_ensure_code(regexp != NULL, CPL_ERROR_NULL_INPUT);
643 for (i=0; i <
self->size; i++) {
644 if (self->propertylist[i] == NULL)
649 cpl_error_get_code());
652 nprops += cpl_propertylist_get_size(self->propertylist[i]);
656 cpl_msg_info(cpl_func,
"List of %d frames has %d properties", nfiles,
659 return CPL_ERROR_NONE;
680 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
681 cpl_ensure_code(tag != NULL, CPL_ERROR_NULL_INPUT);
683 for (i=0; i <
self->size; i++)
684 cpl_ensure_code(!cpl_frame_set_tag(self->frame[i], tag),
685 cpl_error_get_code());
687 return CPL_ERROR_NONE;
710 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
711 cpl_ensure_code(frame != NULL, CPL_ERROR_NULL_INPUT);
712 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
714 if (pos == self->size) {
718 irplib_framelist_set_size(
self);
722 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
724 cpl_frame_delete(self->frame[pos]);
725 cpl_propertylist_delete(self->propertylist[pos]);
728 self->frame[pos] = frame;
729 self->propertylist[pos] = NULL;
731 return CPL_ERROR_NONE;
750 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
751 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
752 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
756 cpl_frame_delete(self->frame[pos]);
757 cpl_propertylist_delete(self->propertylist[pos]);
760 for (i = pos+1; i <
self->size; i++) {
762 self->frame[i-1] =
self->frame[i];
764 self->propertylist[i-1] =
self->propertylist[i];
770 irplib_framelist_set_size(
self);
772 return CPL_ERROR_NONE;
796 cpl_propertylist ** plist)
803 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
804 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
805 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
808 frame =
self->frame[pos];
811 *plist =
self->propertylist[pos];
813 cpl_propertylist_delete(self->propertylist[pos]);
817 for (i = pos+1; i <
self->size; i++) {
819 self->frame[i-1] =
self->frame[i];
821 self->propertylist[i-1] =
self->propertylist[i];
827 irplib_framelist_set_size(
self);
847 while (self->size > 0) {
849 cpl_frame_delete(self->frame[self->size]);
850 cpl_propertylist_delete(self->propertylist[self->size]);
855 irplib_framelist_set_size(
self);
902 const char * key, cpl_type type,
903 cpl_boolean is_equal,
double fp_tol)
908 cpl_type type_0 = CPL_TYPE_INVALID;
912 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
913 cpl_ensure_code(key != NULL, CPL_ERROR_NULL_INPUT);
914 cpl_ensure_code(fp_tol >= 0.0, CPL_ERROR_ILLEGAL_INPUT);
916 for (i=0; i <
self->size; i++) {
920 if (self->propertylist[i] == NULL)
continue;
921 if (ifirst < 0) ifirst = i;
923 type_i = cpl_propertylist_get_type(self->propertylist[i], key);
925 if (type_i == CPL_TYPE_INVALID) {
926 if (type == CPL_TYPE_INVALID)
927 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
928 cpl_error_set_message(cpl_func, cpl_error_get_code(),
"FITS "
929 "key '%s' is missing from file %s", key,
930 cpl_frame_get_filename(self->frame[i]));
932 cpl_error_set_message(cpl_func, cpl_error_get_code(),
933 "FITS key '%s' [%s] is missing from file "
934 "%s", key, cpl_type_get_name(type),
935 cpl_frame_get_filename(self->frame[i]));
937 cpl_error_set_message(cpl_func, cpl_error_get_code(),
938 "A FITS key is missing from a file");
940 cpl_error_set_message(cpl_func, cpl_error_get_code(),
941 "A FITS key is missing from a file");
943 return cpl_error_get_code();
946 if (type != CPL_TYPE_INVALID && type_i != type) {
947 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
948 return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
949 "FITS key '%s' has type %s instead of "
950 "%s in file %s", key,
951 cpl_type_get_name(type_i),
952 cpl_type_get_name(type),
953 cpl_frame_get_filename(self->frame[i]));
955 return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
956 "A FITS key had an unexpected type");
961 if (!is_equal)
continue;
963 if (type_0 == CPL_TYPE_INVALID) {
968 if (type_i != type_0) {
969 assert( type == CPL_TYPE_INVALID );
970 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
971 return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
972 "FITS key '%s' has different types "
973 "(%s <=> %s) in files %s and %s", key,
974 cpl_type_get_name(type_0),
975 cpl_type_get_name(type_i),
976 cpl_frame_get_filename(self->frame[0]),
977 cpl_frame_get_filename(self->frame[i]));
979 return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
980 "A FITS key has different types in "
985 if (irplib_property_equal(self->propertylist[ifirst],
986 self->propertylist[i],
987 key, type_0, fp_tol, &value_0, &value_i))
990 if ((type_0 == CPL_TYPE_FLOAT || type_0 == CPL_TYPE_DOUBLE)
992 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
993 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
"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,
998 cpl_frame_get_filename(self->frame[0]),
999 cpl_frame_get_filename(self->frame[i]));
1001 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
"A "
1002 "FITS key has values that differ by more "
1003 "than the allowed tolerance in two file");
1006 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1007 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
1008 "FITS key '%s' [%s] has different values "
1009 "(%s <=> %s) in files %s and %s", key,
1010 cpl_type_get_name(type_0),
1012 cpl_frame_get_filename(self->frame[0]),
1013 cpl_frame_get_filename(self->frame[i]));
1015 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
"A "
1016 "FITS key has different values in two files");
1022 return cpl_error_get_code();
1025 return CPL_ERROR_NONE;
1050 cpl_imagelist * list = NULL;
1051 cpl_image * image = NULL;
1055 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
1056 cpl_ensure(extnum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
1057 cpl_ensure(planenum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
1059 list = cpl_imagelist_new();
1061 for (i=0; i <
self->size; i++, image = NULL) {
1062 const char * filename = cpl_frame_get_filename(self->frame[i]);
1063 cpl_error_code error;
1065 if (filename == NULL)
break;
1067 image = cpl_image_load(filename, pixeltype, planenum, extnum);
1068 if (image == NULL) {
1069 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1070 (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
1071 "Could not load FITS-image from plane "
1072 "%d in extension %d in file %s",
1073 planenum, extnum, filename);
1075 (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
1076 "Could not load FITS-image");
1081 error = cpl_imagelist_set(list, image, i);
1082 assert(error == CPL_ERROR_NONE);
1085 cpl_image_delete(image);
1087 if (cpl_imagelist_get_size(list) != self->size) {
1088 cpl_imagelist_delete(list);
1090 assert(cpl_error_get_code() != CPL_ERROR_NONE);
1114 static void irplib_framelist_set_size(irplib_framelist *
self)
1118 assert(
self != NULL);
1120 if (self->size == 0) {
1122 cpl_free(self->frame);
1123 cpl_free(self->propertylist);
1125 self->propertylist = NULL;
1129 self->frame = cpl_realloc(self->frame, self->size *
sizeof(cpl_frame*));
1130 self->propertylist =
1131 cpl_realloc(self->propertylist,
1132 self->size *
sizeof(cpl_propertylist*));
1162 static cpl_boolean irplib_property_equal(
const cpl_propertylist *
self,
1163 const cpl_propertylist * other,
1164 const char * key, cpl_type type,
1166 char ** sstring,
char ** ostring)
1172 assert(
self != NULL);
1173 assert(other != NULL);
1174 assert(key != NULL);
1175 assert(sstring != NULL);
1176 assert(ostring != NULL);
1179 assert(cpl_propertylist_get_type(other, key) == type);
1180 assert(fp_tol >= 0.0);
1182 if (
self == other)
return CPL_TRUE;
1186 case CPL_TYPE_CHAR: {
1187 const char svalue = cpl_propertylist_get_char(
self, key);
1188 const char ovalue = cpl_propertylist_get_char(other, key);
1190 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1192 *sstring = cpl_sprintf(
"%c", svalue);
1193 *ostring = cpl_sprintf(
"%c", ovalue);
1198 case CPL_TYPE_BOOL: {
1199 const int svalue = cpl_propertylist_get_bool(
self, key);
1200 const int ovalue = cpl_propertylist_get_bool(other, key);
1202 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1204 *sstring = cpl_strdup(svalue == 0 ?
"F" :
"T");
1205 *ostring = cpl_strdup(ovalue == 0 ?
"F" :
"T");
1210 case CPL_TYPE_INT: {
1211 const int svalue = cpl_propertylist_get_int(
self, key);
1212 const int ovalue = cpl_propertylist_get_int(other, key);
1214 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1216 *sstring = cpl_sprintf(
"%d", svalue);
1217 *ostring = cpl_sprintf(
"%d", ovalue);
1222 case CPL_TYPE_LONG: {
1223 const long svalue = cpl_propertylist_get_long(
self, key);
1224 const long ovalue = cpl_propertylist_get_long(other, key);
1226 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1228 *sstring = cpl_sprintf(
"%ld", svalue);
1229 *ostring = cpl_sprintf(
"%ld", ovalue);
1234 case CPL_TYPE_FLOAT: {
1235 const double svalue = (double)cpl_propertylist_get_float(
self, key);
1236 const double ovalue = (double)cpl_propertylist_get_float(other, key);
1238 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
1240 *sstring = cpl_sprintf(
"%f", svalue);
1241 *ostring = cpl_sprintf(
"%f", ovalue);
1246 case CPL_TYPE_DOUBLE: {
1247 const double svalue = cpl_propertylist_get_double(
self, key);
1248 const double ovalue = cpl_propertylist_get_double(other, key);
1250 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
1252 *sstring = cpl_sprintf(
"%g", svalue);
1253 *ostring = cpl_sprintf(
"%g", ovalue);
1257 case CPL_TYPE_STRING: {
1258 const char * svalue = cpl_propertylist_get_string(
self, key);
1259 const char * ovalue = cpl_propertylist_get_string(other, key);
1261 equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
1263 *sstring = cpl_strdup(svalue);
1264 *ostring = cpl_strdup(ovalue);
1277 assert( *sstring != NULL );
1278 assert( *ostring != NULL );