30#include "irplib_framelist.h"
31#include "irplib_utils.h"
46struct _irplib_framelist_
50 cpl_propertylist **propertylist;
58static void irplib_framelist_set_size(irplib_framelist *)
59#if defined __GNUC__ && __GNUC__ >= 4
60 __attribute__((nonnull))
64static cpl_boolean irplib_property_equal(
const cpl_propertylist *,
65 const cpl_propertylist *,
71#if defined __GNUC__ && __GNUC__ >= 4
72 __attribute__((nonnull))
175 return (irplib_framelist *)cpl_calloc(1,
sizeof(irplib_framelist));
205 irplib_framelist *self;
208 cpl_ensure(frameset != NULL, CPL_ERROR_NULL_INPUT, NULL);
213 for (i = 0; i < cpl_frameset_get_size(frameset); i++) {
214 const cpl_frame *frame = cpl_frameset_get_position_const(frameset, i);
216 cpl_frame *copy = cpl_frame_duplicate(frame);
219 const cpl_error_code error =
223 assert(error == CPL_ERROR_NONE);
226 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]);
256 const cpl_error_code error =
258 cpl_frameset_insert(
new, frame);
260 assert(error == CPL_ERROR_NONE);
263 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);
304 (void)cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
308 if (strcmp(tag, ftag))
311 copy = cpl_frame_duplicate(frame);
314 if (code != CPL_ERROR_NONE)
317 if (self->propertylist[i] != NULL)
318 new->propertylist[newsize] =
319 cpl_propertylist_duplicate(self->propertylist[i]);
324 assert(newsize == new->size);
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 "
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");
360 irplib_framelist *
new;
363 const int xor_val = (invert == CPL_FALSE ? 0 : 1);
367 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
368 cpl_ensure(regexp != NULL, CPL_ERROR_NULL_INPUT, NULL);
370 error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
371 cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, NULL);
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);
385 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
388 if ((regexec(&re, tag, (
size_t)0, NULL, 0) == REG_NOMATCH ? 1 : 0) ^
392 copy = cpl_frame_duplicate(frame);
395 assert(error == CPL_ERROR_NONE);
397 if (self->propertylist[i] != NULL)
398 new->propertylist[newsize] =
399 cpl_propertylist_duplicate(self->propertylist[i]);
406 assert(newsize == new->size);
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 "
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");
438 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, -1);
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);
459 return self->frame[pos];
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)
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);
505 cpl_propertylist_delete(self->propertylist[pos]);
507 self->propertylist[pos] = cpl_propertylist_duplicate(list);
509 cpl_ensure_code(self->propertylist[pos] != NULL, cpl_error_get_code());
511 return CPL_ERROR_NONE;
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);
534 cpl_ensure(self->propertylist[pos] != NULL, CPL_ERROR_DATA_NOT_FOUND, NULL);
536 return self->propertylist[pos];
553const cpl_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);
561 cpl_ensure(self->propertylist[pos] != NULL, 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] =
604 cpl_propertylist_load_regexp(filename, ind, regexp, invert ? 1 : 0);
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(),
610 "not load FITS header from '%s' using "
614 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
615 "Could not load FITS header");
619 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)
655 cpl_error_get_code());
658 nprops += cpl_propertylist_get_size(self->propertylist[i]);
662 cpl_msg_info(cpl_func,
"List of %d frames has %d properties", nfiles,
665 return CPL_ERROR_NONE;
683 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
684 cpl_ensure_code(tag != NULL, CPL_ERROR_NULL_INPUT);
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());
690 return CPL_ERROR_NONE;
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);
716 if (pos == self->size) {
719 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;
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++) {
760 self->frame[i - 1] = self->frame[i];
762 self->propertylist[i - 1] = self->propertylist[i];
767 irplib_framelist_set_size(self);
769 return CPL_ERROR_NONE;
793 cpl_propertylist **plist)
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);
805 frame = self->frame[pos];
808 *plist = self->propertylist[pos];
810 cpl_propertylist_delete(self->propertylist[pos]);
814 for (i = pos + 1; i < self->size; i++) {
815 self->frame[i - 1] = self->frame[i];
817 self->propertylist[i - 1] = self->propertylist[i];
822 irplib_framelist_set_size(self);
840 while (self->size > 0) {
842 cpl_frame_delete(self->frame[self->size]);
843 cpl_propertylist_delete(self->propertylist[self->size]);
847 irplib_framelist_set_size(self);
895 cpl_boolean is_equal,
898 char *value_0 = NULL;
899 char *value_i = NULL;
900 cpl_type type_0 = CPL_TYPE_INVALID;
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);
908 for (i = 0; i < self->size; i++) {
912 if (self->propertylist[i] == NULL)
917 type_i = cpl_propertylist_get_type(self->propertylist[i], key);
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(),
924 "key '%s' is missing from file %s",
926 cpl_frame_get_filename(self->frame[i]));
928 cpl_error_set_message(cpl_func, cpl_error_get_code(),
929 "FITS key '%s' [%s] is missing from file "
931 key, cpl_type_get_name(type),
932 cpl_frame_get_filename(self->frame[i]));
934 cpl_error_set_message(cpl_func, cpl_error_get_code(),
935 "A FITS key is missing from a file");
937 cpl_error_set_message(cpl_func, cpl_error_get_code(),
938 "A FITS key is missing from a file");
940 return cpl_error_get_code();
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 "
948 key, cpl_type_get_name(type_i),
949 cpl_type_get_name(type),
950 cpl_frame_get_filename(
953 return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
954 "A FITS key had an unexpected type");
961 if (type_0 == CPL_TYPE_INVALID) {
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(
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], key, type_0, fp_tol,
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,
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,
1003 "FITS key has values that differ by more "
1004 "than the allowed tolerance in two file");
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,
1014 cpl_frame_get_filename(self->frame[0]),
1015 cpl_frame_get_filename(self->frame[i]));
1017 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
1019 "FITS key has different values in two files");
1025 return cpl_error_get_code();
1028 return CPL_ERROR_NONE;
1052 cpl_imagelist *list = NULL;
1053 cpl_image *image = NULL;
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);
1061 list = cpl_imagelist_new();
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;
1067 if (filename == NULL)
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);
1078 (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
1079 "Could not load FITS-image");
1084 code = cpl_imagelist_set(list, image, i);
1085 if (code != CPL_ERROR_NONE)
1089 cpl_image_delete(image);
1091 if (cpl_imagelist_get_size(list) != self->size) {
1092 cpl_imagelist_delete(list);
1094 (void)cpl_error_set_where(cpl_func);
1118irplib_framelist_set_size(irplib_framelist *self)
1120 assert(self != NULL);
1122 if (self->size == 0) {
1124 cpl_free(self->frame);
1125 cpl_free(self->propertylist);
1127 self->propertylist = NULL;
1129 else if (self->size > 0) {
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 *));
1139 (void)cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
1169irplib_property_equal(
const cpl_propertylist *self,
1170 const cpl_propertylist *other,
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);
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 =
1245 (double)cpl_propertylist_get_float(other, key);
1247 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
1249 *sstring = cpl_sprintf(
"%f", svalue);
1250 *ostring = cpl_sprintf(
"%f", ovalue);
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);
1259 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
1261 *sstring = cpl_sprintf(
"%g", svalue);
1262 *ostring = cpl_sprintf(
"%g", ovalue);
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);
1270 equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
1272 *sstring = cpl_strdup(svalue);
1273 *ostring = cpl_strdup(ovalue);
1286 assert(*sstring != NULL);
1287 assert(*ostring != NULL);
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.