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;
208 cpl_ensure(frameset != NULL, CPL_ERROR_NULL_INPUT, NULL);
213 for (i = 0; i < cpl_frameset_get_size(frameset); i++)
215 const cpl_frame * frame = cpl_frameset_get_position_const(frameset, i);
217 cpl_frame * copy = cpl_frame_duplicate(frame);
221 assert(error == CPL_ERROR_NONE);
225 assert(self->size == cpl_frameset_get_size(frameset));
248 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
251 new = cpl_frameset_new();
253 for (i = 0; i <
self->size; i++) {
254 cpl_frame * frame = cpl_frame_duplicate(self->frame[i]);
255 const cpl_error_code error = cpl_frameset_insert(
new, frame);
257 assert(error == CPL_ERROR_NONE);
261 assert(self->size == cpl_frameset_get_size(
new));
285 irplib_framelist *
new;
289 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
290 cpl_ensure(tag != NULL, CPL_ERROR_NULL_INPUT, NULL);
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);
299 cpl_error_code error;
304 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
307 if (strcmp(tag, ftag))
continue;
309 copy = cpl_frame_duplicate(frame);
312 assert(error == CPL_ERROR_NONE);
314 if (self->propertylist[i] != NULL)
new->propertylist[newsize]
315 = cpl_propertylist_duplicate(self->propertylist[i]);
320 assert( newsize == new->size );
323 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
324 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
325 "The list of %d frame(s) has no frames "
326 "with tag: %s", self->size, tag);
328 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
329 "The list of frame(s) has no frames "
330 "with the given tag");
356 irplib_framelist *
new;
359 const int xor_val = (invert == CPL_FALSE ? 0 : 1);
363 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
364 cpl_ensure(regexp != NULL, CPL_ERROR_NULL_INPUT, NULL);
366 error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
367 cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, NULL);
372 for (i = 0; i <
self->size; i++) {
373 const cpl_frame * frame =
self->frame[i];
374 const char * tag = cpl_frame_get_tag(frame);
381 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
384 if ((regexec(&re, tag, (
size_t)0, NULL, 0) == REG_NOMATCH ? 1 : 0)
387 copy = cpl_frame_duplicate(frame);
390 assert(error == CPL_ERROR_NONE);
392 if (self->propertylist[i] != NULL)
new->propertylist[newsize]
393 = cpl_propertylist_duplicate(self->propertylist[i]);
401 assert( newsize == new->size );
404 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
405 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
406 "The list of %d frame(s) has no frames "
407 "that match: %s", self->size, regexp);
409 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
410 "The list of frames has no frames "
411 "that match the regular expression");
432 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, -1);
449 IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
451 IRPLIB_DIAG_PRAGMA_POP;
468 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
469 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
470 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
472 return self->frame[pos];
489 const cpl_propertylist * list)
492 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
493 cpl_ensure_code(list != NULL, CPL_ERROR_NULL_INPUT);
494 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
495 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
497 cpl_propertylist_delete(self->propertylist[pos]);
499 self->propertylist[pos] = cpl_propertylist_duplicate(list);
501 cpl_ensure_code(self->propertylist[pos] != NULL, cpl_error_get_code());
503 return CPL_ERROR_NONE;
524 IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
527 IRPLIB_DIAG_PRAGMA_POP;
544 const irplib_framelist *
self,
547 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
548 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
549 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
551 cpl_ensure(self->propertylist[pos] != NULL,
552 CPL_ERROR_DATA_NOT_FOUND, NULL);
554 return self->propertylist[pos];
580 const char * filename;
583 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
584 cpl_ensure_code(regexp != NULL, CPL_ERROR_NULL_INPUT);
585 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
586 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
588 filename = cpl_frame_get_filename(self->frame[pos]);
590 cpl_ensure_code(filename != NULL, cpl_error_get_code());
592 cpl_propertylist_delete(self->propertylist[pos]);
594 self->propertylist[pos] = cpl_propertylist_load_regexp(filename, ind,
598 if (self->propertylist[pos] == NULL) {
599 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
600 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
"Could "
601 "not load FITS header from '%s' using "
602 "regexp '%s'", filename, regexp);
604 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
605 "Could not load FITS header");
609 return CPL_ERROR_NONE;
639 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
640 cpl_ensure_code(regexp != NULL, CPL_ERROR_NULL_INPUT);
642 for (i=0; i <
self->size; i++) {
643 if (self->propertylist[i] == NULL)
648 cpl_error_get_code());
651 nprops += cpl_propertylist_get_size(self->propertylist[i]);
655 cpl_msg_info(cpl_func,
"List of %d frames has %d properties", nfiles,
658 return CPL_ERROR_NONE;
679 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
680 cpl_ensure_code(tag != NULL, CPL_ERROR_NULL_INPUT);
682 for (i=0; i <
self->size; i++)
683 cpl_ensure_code(!cpl_frame_set_tag(self->frame[i], tag),
684 cpl_error_get_code());
686 return CPL_ERROR_NONE;
709 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
710 cpl_ensure_code(frame != NULL, CPL_ERROR_NULL_INPUT);
711 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
713 if (pos == self->size) {
717 irplib_framelist_set_size(
self);
721 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
723 cpl_frame_delete(self->frame[pos]);
724 cpl_propertylist_delete(self->propertylist[pos]);
727 self->frame[pos] = frame;
728 self->propertylist[pos] = NULL;
730 return CPL_ERROR_NONE;
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);
755 cpl_frame_delete(self->frame[pos]);
756 cpl_propertylist_delete(self->propertylist[pos]);
759 for (i = pos+1; i <
self->size; i++) {
761 self->frame[i-1] =
self->frame[i];
763 self->propertylist[i-1] =
self->propertylist[i];
769 irplib_framelist_set_size(
self);
771 return CPL_ERROR_NONE;
795 cpl_propertylist ** plist)
802 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
803 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
804 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
807 frame =
self->frame[pos];
810 *plist =
self->propertylist[pos];
812 cpl_propertylist_delete(self->propertylist[pos]);
816 for (i = pos+1; i <
self->size; i++) {
818 self->frame[i-1] =
self->frame[i];
820 self->propertylist[i-1] =
self->propertylist[i];
826 irplib_framelist_set_size(
self);
846 while (self->size > 0) {
848 cpl_frame_delete(self->frame[self->size]);
849 cpl_propertylist_delete(self->propertylist[self->size]);
854 irplib_framelist_set_size(
self);
901 const char * key, cpl_type type,
902 cpl_boolean is_equal,
double fp_tol)
907 cpl_type type_0 = CPL_TYPE_INVALID;
911 cpl_ensure_code(
self != NULL, CPL_ERROR_NULL_INPUT);
912 cpl_ensure_code(key != NULL, CPL_ERROR_NULL_INPUT);
913 cpl_ensure_code(fp_tol >= 0.0, CPL_ERROR_ILLEGAL_INPUT);
915 for (i=0; i <
self->size; i++) {
919 if (self->propertylist[i] == NULL)
continue;
920 if (ifirst < 0) ifirst = i;
922 type_i = cpl_propertylist_get_type(self->propertylist[i], key);
924 if (type_i == CPL_TYPE_INVALID) {
925 if (type == CPL_TYPE_INVALID)
926 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
927 cpl_error_set_message(cpl_func, cpl_error_get_code(),
"FITS "
928 "key '%s' is missing from file %s", key,
929 cpl_frame_get_filename(self->frame[i]));
931 cpl_error_set_message(cpl_func, cpl_error_get_code(),
932 "FITS key '%s' [%s] is missing from file "
933 "%s", key, cpl_type_get_name(type),
934 cpl_frame_get_filename(self->frame[i]));
936 cpl_error_set_message(cpl_func, cpl_error_get_code(),
937 "A FITS key is missing from a file");
939 cpl_error_set_message(cpl_func, cpl_error_get_code(),
940 "A FITS key is missing from a file");
942 return cpl_error_get_code();
945 if (type != CPL_TYPE_INVALID && type_i != type) {
946 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
947 return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
948 "FITS key '%s' has type %s instead of "
949 "%s in file %s", key,
950 cpl_type_get_name(type_i),
951 cpl_type_get_name(type),
952 cpl_frame_get_filename(self->frame[i]));
954 return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
955 "A FITS key had an unexpected type");
960 if (!is_equal)
continue;
962 if (type_0 == CPL_TYPE_INVALID) {
967 if (type_i != type_0) {
968 assert( type == CPL_TYPE_INVALID );
969 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
970 return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
971 "FITS key '%s' has different types "
972 "(%s <=> %s) in files %s and %s", key,
973 cpl_type_get_name(type_0),
974 cpl_type_get_name(type_i),
975 cpl_frame_get_filename(self->frame[0]),
976 cpl_frame_get_filename(self->frame[i]));
978 return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
979 "A FITS key has different types in "
984 if (irplib_property_equal(self->propertylist[ifirst],
985 self->propertylist[i],
986 key, type_0, fp_tol, &value_0, &value_i))
989 if ((type_0 == CPL_TYPE_FLOAT || type_0 == CPL_TYPE_DOUBLE)
991 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
992 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
"FITS"
993 " key '%s' [%s] has values that differ by "
994 "more than %g (%s <=> %s) in files %s and %s",
995 key, cpl_type_get_name(type_0), fp_tol,
997 cpl_frame_get_filename(self->frame[0]),
998 cpl_frame_get_filename(self->frame[i]));
1000 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
"A "
1001 "FITS key has values that differ by more "
1002 "than the allowed tolerance in two file");
1005 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1006 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
1007 "FITS key '%s' [%s] has different values "
1008 "(%s <=> %s) in files %s and %s", key,
1009 cpl_type_get_name(type_0),
1011 cpl_frame_get_filename(self->frame[0]),
1012 cpl_frame_get_filename(self->frame[i]));
1014 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
"A "
1015 "FITS key has different values in two files");
1021 return cpl_error_get_code();
1024 return CPL_ERROR_NONE;
1049 cpl_imagelist * list = NULL;
1050 cpl_image * image = NULL;
1054 cpl_ensure(
self != NULL, CPL_ERROR_NULL_INPUT, NULL);
1055 cpl_ensure(extnum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
1056 cpl_ensure(planenum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
1058 list = cpl_imagelist_new();
1060 for (i=0; i <
self->size; i++, image = NULL) {
1061 const char * filename = cpl_frame_get_filename(self->frame[i]);
1062 cpl_error_code error;
1064 if (filename == NULL)
break;
1066 image = cpl_image_load(filename, pixeltype, planenum, extnum);
1067 if (image == NULL) {
1068 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
1069 (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
1070 "Could not load FITS-image from plane "
1071 "%d in extension %d in file %s",
1072 planenum, extnum, filename);
1074 (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
1075 "Could not load FITS-image");
1080 error = cpl_imagelist_set(list, image, i);
1081 assert(error == CPL_ERROR_NONE);
1084 cpl_image_delete(image);
1086 if (cpl_imagelist_get_size(list) != self->size) {
1087 cpl_imagelist_delete(list);
1089 assert(cpl_error_get_code() != CPL_ERROR_NONE);
1113 static void irplib_framelist_set_size(irplib_framelist *
self)
1117 assert(
self != NULL);
1119 if (self->size == 0) {
1121 cpl_free(self->frame);
1122 cpl_free(self->propertylist);
1124 self->propertylist = NULL;
1128 self->frame = cpl_realloc(self->frame, self->size *
sizeof(cpl_frame*));
1129 self->propertylist =
1130 cpl_realloc(self->propertylist,
1131 self->size *
sizeof(cpl_propertylist*));
1161 static cpl_boolean irplib_property_equal(
const cpl_propertylist *
self,
1162 const cpl_propertylist * other,
1163 const char * key, cpl_type type,
1165 char ** sstring,
char ** ostring)
1171 assert(
self != NULL);
1172 assert(other != NULL);
1173 assert(key != NULL);
1174 assert(sstring != NULL);
1175 assert(ostring != NULL);
1178 assert(cpl_propertylist_get_type(other, key) == type);
1179 assert(fp_tol >= 0.0);
1181 if (
self == other)
return CPL_TRUE;
1185 case CPL_TYPE_CHAR: {
1186 const char svalue = cpl_propertylist_get_char(
self, key);
1187 const char ovalue = cpl_propertylist_get_char(other, key);
1189 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1191 *sstring = cpl_sprintf(
"%c", svalue);
1192 *ostring = cpl_sprintf(
"%c", ovalue);
1197 case CPL_TYPE_BOOL: {
1198 const int svalue = cpl_propertylist_get_bool(
self, key);
1199 const int ovalue = cpl_propertylist_get_bool(other, key);
1201 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1203 *sstring = cpl_strdup(svalue == 0 ?
"F" :
"T");
1204 *ostring = cpl_strdup(ovalue == 0 ?
"F" :
"T");
1209 case CPL_TYPE_INT: {
1210 const int svalue = cpl_propertylist_get_int(
self, key);
1211 const int ovalue = cpl_propertylist_get_int(other, key);
1213 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1215 *sstring = cpl_sprintf(
"%d", svalue);
1216 *ostring = cpl_sprintf(
"%d", ovalue);
1221 case CPL_TYPE_LONG: {
1222 const long svalue = cpl_propertylist_get_long(
self, key);
1223 const long ovalue = cpl_propertylist_get_long(other, key);
1225 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1227 *sstring = cpl_sprintf(
"%ld", svalue);
1228 *ostring = cpl_sprintf(
"%ld", ovalue);
1233 case CPL_TYPE_FLOAT: {
1234 const double svalue = (double)cpl_propertylist_get_float(
self, key);
1235 const double ovalue = (double)cpl_propertylist_get_float(other, key);
1237 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
1239 *sstring = cpl_sprintf(
"%f", svalue);
1240 *ostring = cpl_sprintf(
"%f", ovalue);
1245 case CPL_TYPE_DOUBLE: {
1246 const double svalue = cpl_propertylist_get_double(
self, key);
1247 const double ovalue = cpl_propertylist_get_double(other, key);
1249 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
1251 *sstring = cpl_sprintf(
"%g", svalue);
1252 *ostring = cpl_sprintf(
"%g", ovalue);
1256 case CPL_TYPE_STRING: {
1257 const char * svalue = cpl_propertylist_get_string(
self, key);
1258 const char * ovalue = cpl_propertylist_get_string(other, key);
1260 equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
1262 *sstring = cpl_strdup(svalue);
1263 *ostring = cpl_strdup(ovalue);
1276 assert( *sstring != NULL );
1277 assert( *ostring != NULL );
cpl_imagelist * irplib_imagelist_load_framelist(const irplib_framelist *self, cpl_type pixeltype, int planenum, int extnum)
Load an imagelist from a framelist.
cpl_frameset * irplib_frameset_cast(const irplib_framelist *self)
Create a CPL frameset from an irplib_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_set(irplib_framelist *self, cpl_frame *frame, int pos)
Add a frame to 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.
const cpl_propertylist * irplib_framelist_get_propertylist_const(const irplib_framelist *self, int pos)
Get the propertylist of the specified frame in the framelist.
void irplib_framelist_empty(irplib_framelist *self)
Erase all frames from a 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_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_frame * irplib_framelist_get(irplib_framelist *self, int pos)
Get the specified frame from the framelist.
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.
irplib_framelist * irplib_framelist_extract(const irplib_framelist *self, const char *tag)
Extract the frames with the given tag from a framelist.
const cpl_frame * irplib_framelist_get_const(const irplib_framelist *self, int pos)
Get the specified frame from the framelist.
void irplib_framelist_delete(irplib_framelist *self)
Deallocate an irplib_framelist with its frames and properties.
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.
cpl_propertylist * irplib_framelist_get_propertylist(irplib_framelist *self, int pos)
Get the propertylist of the specified frame in the 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.
irplib_framelist * irplib_framelist_cast(const cpl_frameset *frameset)
Create an irplib_framelist from a cpl_framelist.
irplib_framelist * irplib_framelist_new(void)
Create an empty framelist.
int irplib_framelist_get_size(const irplib_framelist *self)
Get the size of a framelist.
cpl_error_code irplib_framelist_erase(irplib_framelist *self, int pos)
Erase a frame from a framelist and delete it and its propertylist.