SINFONI Pipeline Reference Manual  2.6.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 #include <cpl.h>
33 
34 #include <stdio.h>
35 #include <string.h>
36 #include <sys/types.h>
37 #include <regex.h>
38 #include <math.h>
39 #include <assert.h>
40 
41 
42 /*-----------------------------------------------------------------------------
43  New types
44  -----------------------------------------------------------------------------*/
45 
46 /* @cond */
47 struct _irplib_framelist_ {
48  int size;
49  cpl_frame ** frame;
50  cpl_propertylist ** propertylist;
51 
52 };
53 /* @endcond */
54 
55 /*-----------------------------------------------------------------------------
56  Private funcions
57  -----------------------------------------------------------------------------*/
58 
59 static void irplib_framelist_set_size(irplib_framelist *)
60 #if defined __GNUC__ && __GNUC__ >= 4
61  __attribute__((nonnull))
62 #endif
63 ;
64 
65 static cpl_boolean irplib_property_equal(const cpl_propertylist *,
66  const cpl_propertylist *,
67  const char *, cpl_type, double,
68  char **, char **)
69 #if defined __GNUC__ && __GNUC__ >= 4
70  __attribute__((nonnull))
71 #endif
72 ;
73 
74 /*----------------------------------------------------------------------------*/
153 /*----------------------------------------------------------------------------*/
154 
157 /*-----------------------------------------------------------------------------
158  Function codes
159  -----------------------------------------------------------------------------*/
160 
161 /*----------------------------------------------------------------------------*/
169 /*----------------------------------------------------------------------------*/
170 irplib_framelist * irplib_framelist_new(void)
171 {
172 
173  return (irplib_framelist *) cpl_calloc(1, sizeof(irplib_framelist));
174 
175 }
176 
177 /*----------------------------------------------------------------------------*/
182 /*----------------------------------------------------------------------------*/
183 void irplib_framelist_delete(irplib_framelist * self)
184 {
185 
187  cpl_free(self);
188 }
189 
190 
191 /*----------------------------------------------------------------------------*/
200 /*----------------------------------------------------------------------------*/
201 irplib_framelist * irplib_framelist_cast(const cpl_frameset * frameset)
202 {
203 
204  irplib_framelist * self;
205  int i;
206 
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  {
215  const cpl_frame * frame = cpl_frameset_get_position_const(frameset, i);
216 
217  cpl_frame * copy = cpl_frame_duplicate(frame);
218 
219  const cpl_error_code error = irplib_framelist_set(self, copy, i);
220 
221  assert(error == CPL_ERROR_NONE);
222 
223  }
224 
225  assert(self->size == cpl_frameset_get_size(frameset));
226 
227  return self;
228 
229 }
230 
231 
232 /*----------------------------------------------------------------------------*/
241 /*----------------------------------------------------------------------------*/
242 cpl_frameset * irplib_frameset_cast(const irplib_framelist * self)
243 {
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  const cpl_error_code error = cpl_frameset_insert(new, frame);
256 
257  assert(error == CPL_ERROR_NONE);
258 
259  }
260 
261  assert(self->size == cpl_frameset_get_size(new));
262 
263  return new;
264 
265 }
266 
267 
268 /*----------------------------------------------------------------------------*/
280 /*----------------------------------------------------------------------------*/
281 irplib_framelist * irplib_framelist_extract(const irplib_framelist * self,
282  const char * tag)
283 {
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 error;
300 
301  if (ftag == NULL) {
302  /* The frame is ill-formed */
304  cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
305  }
306 
307  if (strcmp(tag, ftag)) continue;
308 
309  copy = cpl_frame_duplicate(frame);
310 
311  error = irplib_framelist_set(new, copy, newsize);
312  assert(error == CPL_ERROR_NONE);
313 
314  if (self->propertylist[i] != NULL) new->propertylist[newsize]
315  = cpl_propertylist_duplicate(self->propertylist[i]);
316 
317  newsize++;
318  }
319 
320  assert( newsize == new->size );
321 
322  if (newsize == 0) {
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);
327 #else
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");
331 #endif
333  new = NULL;
334  }
335 
336  return new;
337 
338 }
339 
340 /*----------------------------------------------------------------------------*/
350 /*----------------------------------------------------------------------------*/
351 irplib_framelist * irplib_framelist_extract_regexp(const irplib_framelist* self,
352  const char * regexp,
353  cpl_boolean invert)
354 {
355 
356  irplib_framelist * new;
357  int error;
358  int i, newsize;
359  const int xor_val = (invert == CPL_FALSE ? 0 : 1);
360  regex_t re;
361 
362 
363  cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
364  cpl_ensure(regexp != NULL, CPL_ERROR_NULL_INPUT, NULL);
365 
366  error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
367  cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, NULL);
368 
369  new = irplib_framelist_new();
370  newsize = 0;
371 
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);
375  cpl_frame * copy;
376 
377  if (tag == NULL) {
378  /* The frame is ill-formed */
380  regfree(&re);
381  cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
382  }
383 
384  if ((regexec(&re, tag, (size_t)0, NULL, 0) == REG_NOMATCH ? 1 : 0)
385  ^ xor_val) continue;
386 
387  copy = cpl_frame_duplicate(frame);
388 
389  error = (int)irplib_framelist_set(new, copy, newsize);
390  assert(error == CPL_ERROR_NONE);
391 
392  if (self->propertylist[i] != NULL) new->propertylist[newsize]
393  = cpl_propertylist_duplicate(self->propertylist[i]);
394 
395  newsize++;
396 
397  }
398 
399  regfree(&re);
400 
401  assert( newsize == new->size );
402 
403  if (newsize == 0) {
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);
408 #else
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");
412 #endif
414  new = NULL;
415  }
416 
417  return new;
418 }
419 
420 
421 /*----------------------------------------------------------------------------*/
428 /*----------------------------------------------------------------------------*/
429 int irplib_framelist_get_size(const irplib_framelist * self)
430 {
431 
432  cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, -1);
433 
434  return self->size;
435 
436 }
437 
438 /*----------------------------------------------------------------------------*/
446 /*----------------------------------------------------------------------------*/
447 cpl_frame * irplib_framelist_get(irplib_framelist * self, int pos)
448 {
449  IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
450  return (cpl_frame *)irplib_framelist_get_const(self, pos);
451  IRPLIB_DIAG_PRAGMA_POP;
452 }
453 
454 
455 /*----------------------------------------------------------------------------*/
463 /*----------------------------------------------------------------------------*/
464 const cpl_frame * irplib_framelist_get_const(const irplib_framelist * self,
465  int pos)
466 {
467 
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);
471 
472  return self->frame[pos];
473 
474 }
475 
476 
477 /*----------------------------------------------------------------------------*/
486 /*----------------------------------------------------------------------------*/
487 cpl_error_code irplib_framelist_set_propertylist(irplib_framelist * self,
488  int pos,
489  const cpl_propertylist * list)
490 {
491 
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);
496 
497  cpl_propertylist_delete(self->propertylist[pos]);
498 
499  self->propertylist[pos] = cpl_propertylist_duplicate(list);
500 
501  cpl_ensure_code(self->propertylist[pos] != NULL, cpl_error_get_code());
502 
503  return CPL_ERROR_NONE;
504 
505 }
506 
507 
508 /*----------------------------------------------------------------------------*/
519 /*----------------------------------------------------------------------------*/
520 cpl_propertylist * irplib_framelist_get_propertylist(irplib_framelist * self,
521  int pos)
522 {
523 
524  IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
525  return (cpl_propertylist *)irplib_framelist_get_propertylist_const(self,
526  pos);
527  IRPLIB_DIAG_PRAGMA_POP;
528 }
529 
530 
531 /*----------------------------------------------------------------------------*/
542 /*----------------------------------------------------------------------------*/
544  const irplib_framelist * self,
545  int pos)
546 {
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);
550 
551  cpl_ensure(self->propertylist[pos] != NULL,
552  CPL_ERROR_DATA_NOT_FOUND, NULL);
553 
554  return self->propertylist[pos];
555 
556 }
557 
558 
559 /*----------------------------------------------------------------------------*/
573 /*----------------------------------------------------------------------------*/
574 cpl_error_code irplib_framelist_load_propertylist(irplib_framelist * self,
575  int pos, int ind,
576  const char * regexp,
577  cpl_boolean invert)
578 {
579 
580  const char * filename;
581 
582 
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);
587 
588  filename = cpl_frame_get_filename(self->frame[pos]);
589 
590  cpl_ensure_code(filename != NULL, cpl_error_get_code());
591 
592  cpl_propertylist_delete(self->propertylist[pos]);
593 
594  self->propertylist[pos] = cpl_propertylist_load_regexp(filename, ind,
595  regexp,
596  invert ? 1 : 0);
597 
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);
603 #else
604  return cpl_error_set_message(cpl_func, cpl_error_get_code(),
605  "Could not load FITS header");
606 #endif
607  }
608 
609  return CPL_ERROR_NONE;
610 
611 }
612 
613 
614 /*----------------------------------------------------------------------------*/
628 /*----------------------------------------------------------------------------*/
629 cpl_error_code irplib_framelist_load_propertylist_all(irplib_framelist * self,
630  int ind,
631  const char * regexp,
632  cpl_boolean invert)
633 {
634 
635  int nprops = 0;
636  int nfiles = 0;
637  int i;
638 
639  cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
640  cpl_ensure_code(regexp != NULL, CPL_ERROR_NULL_INPUT);
641 
642  for (i=0; i < self->size; i++) {
643  if (self->propertylist[i] == NULL)
644  cpl_ensure_code(!irplib_framelist_load_propertylist(self, i,
645  ind,
646  regexp,
647  invert),
648  cpl_error_get_code());
649  /* Counting just for diagnostics - this actually causes
650  the whole list to be reiterated :-( */
651  nprops += cpl_propertylist_get_size(self->propertylist[i]);
652  nfiles++;
653  }
654 
655  cpl_msg_info(cpl_func, "List of %d frames has %d properties", nfiles,
656  nprops);
657 
658  return CPL_ERROR_NONE;
659 
660 }
661 
662 
663 
664 /*----------------------------------------------------------------------------*/
672 /*----------------------------------------------------------------------------*/
673 cpl_error_code irplib_framelist_set_tag_all(irplib_framelist * self,
674  const char * tag)
675 {
676 
677  int i;
678 
679  cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
680  cpl_ensure_code(tag != NULL, CPL_ERROR_NULL_INPUT);
681 
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());
685 
686  return CPL_ERROR_NONE;
687 }
688 
689 
690 /*----------------------------------------------------------------------------*/
704 /*----------------------------------------------------------------------------*/
705 cpl_error_code irplib_framelist_set(irplib_framelist * self, cpl_frame * frame,
706  int pos)
707 {
708 
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);
712 
713  if (pos == self->size) {
714 
715  self->size++;
716 
717  irplib_framelist_set_size(self);
718 
719  } else {
720 
721  cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
722 
723  cpl_frame_delete(self->frame[pos]);
724  cpl_propertylist_delete(self->propertylist[pos]);
725  }
726 
727  self->frame[pos] = frame;
728  self->propertylist[pos] = NULL;
729 
730  return CPL_ERROR_NONE;
731 
732 }
733 
734 /*----------------------------------------------------------------------------*/
743 /*----------------------------------------------------------------------------*/
744 cpl_error_code irplib_framelist_erase(irplib_framelist * self, int pos)
745 {
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 
761  self->frame[i-1] = self->frame[i];
762 
763  self->propertylist[i-1] = self->propertylist[i];
764 
765  }
766 
767  self->size--;
768 
769  irplib_framelist_set_size(self);
770 
771  return CPL_ERROR_NONE;
772 
773 }
774 
775 
776 
777 /*----------------------------------------------------------------------------*/
793 /*----------------------------------------------------------------------------*/
794 cpl_frame * irplib_framelist_unset(irplib_framelist * self, int pos,
795  cpl_propertylist ** plist)
796 
797 {
798  cpl_frame * frame;
799  int i;
800 
801 
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);
805 
806  /* Get the specified frame and its propertylist */
807  frame = self->frame[pos];
808 
809  if (plist != NULL)
810  *plist = self->propertylist[pos];
811  else
812  cpl_propertylist_delete(self->propertylist[pos]);
813 
814 
815  /* Move following frames down one position */
816  for (i = pos+1; i < self->size; i++) {
817 
818  self->frame[i-1] = self->frame[i];
819 
820  self->propertylist[i-1] = self->propertylist[i];
821 
822  }
823 
824  self->size--;
825 
826  irplib_framelist_set_size(self);
827 
828  return frame;
829 
830 }
831 
832 /*----------------------------------------------------------------------------*/
839 /*----------------------------------------------------------------------------*/
840 void irplib_framelist_empty(irplib_framelist * self)
841 {
842 
843  if (self != NULL) {
844 
845  /* Deallocate all frames and their propertylists */
846  while (self->size > 0) {
847  self->size--;
848  cpl_frame_delete(self->frame[self->size]);
849  cpl_propertylist_delete(self->propertylist[self->size]);
850 
851  }
852 
853  /* Deallocate the arrays */
854  irplib_framelist_set_size(self);
855 
856  }
857 }
858 
859 
860 
861 /*----------------------------------------------------------------------------*/
899 /*----------------------------------------------------------------------------*/
900 cpl_error_code irplib_framelist_contains(const irplib_framelist * self,
901  const char * key, cpl_type type,
902  cpl_boolean is_equal, double fp_tol)
903 {
904 
905  char * value_0;
906  char * value_i;
907  cpl_type type_0 = CPL_TYPE_INVALID;
908  int i, ifirst = -1; /* First non-NULL propertylist */
909 
910 
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);
914 
915  for (i=0; i < self->size; i++) {
916  cpl_type type_i;
917 
918 
919  if (self->propertylist[i] == NULL) continue;
920  if (ifirst < 0) ifirst = i;
921 
922  type_i = cpl_propertylist_get_type(self->propertylist[i], key);
923 
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]));
930  else
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]));
935 #else
936  cpl_error_set_message(cpl_func, cpl_error_get_code(),
937  "A FITS key is missing from a file");
938  else
939  cpl_error_set_message(cpl_func, cpl_error_get_code(),
940  "A FITS key is missing from a file");
941 #endif
942  return cpl_error_get_code();
943  }
944 
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]));
953 #else
954  return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
955  "A FITS key had an unexpected type");
956 #endif
957 
958  }
959 
960  if (!is_equal) continue;
961 
962  if (type_0 == CPL_TYPE_INVALID) {
963  type_0 = type_i;
964  continue;
965  }
966 
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]));
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],
986  key, type_0, fp_tol, &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, "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,
996  value_0, value_i,
997  cpl_frame_get_filename(self->frame[0]),
998  cpl_frame_get_filename(self->frame[i]));
999 #else
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");
1003 #endif
1004  } else {
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),
1010  value_0, value_i,
1011  cpl_frame_get_filename(self->frame[0]),
1012  cpl_frame_get_filename(self->frame[i]));
1013 #else
1014  cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "A "
1015  "FITS key has different values in two files");
1016 #endif
1017  }
1018  cpl_free(value_0);
1019  cpl_free(value_i);
1020 
1021  return cpl_error_get_code();
1022  }
1023 
1024  return CPL_ERROR_NONE;
1025 
1026 }
1027 
1028 
1029 /*----------------------------------------------------------------------------*/
1042 /*----------------------------------------------------------------------------*/
1043 cpl_imagelist * irplib_imagelist_load_framelist(const irplib_framelist * self,
1044  cpl_type pixeltype,
1045  int planenum,
1046  int extnum)
1047 {
1048 
1049  cpl_imagelist * list = NULL;
1050  cpl_image * image = NULL;
1051  int i;
1052 
1053 
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);
1057 
1058  list = cpl_imagelist_new();
1059 
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;
1063 
1064  if (filename == NULL) break;
1065 
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);
1073 #else
1074  (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
1075  "Could not load FITS-image");
1076 #endif
1077  break;
1078  }
1079 
1080  error = cpl_imagelist_set(list, image, i);
1081  assert(error == CPL_ERROR_NONE);
1082  }
1083 
1084  cpl_image_delete(image);
1085 
1086  if (cpl_imagelist_get_size(list) != self->size) {
1087  cpl_imagelist_delete(list);
1088  list = NULL;
1089  assert(cpl_error_get_code() != CPL_ERROR_NONE);
1090  }
1091 
1092  return list;
1093 
1094 }
1095 
1096 
1100 /*----------------------------------------------------------------------------*/
1112 /*----------------------------------------------------------------------------*/
1113 static void irplib_framelist_set_size(irplib_framelist * self)
1114 {
1115 
1116 
1117  assert( self != NULL);
1118 
1119  if (self->size == 0) {
1120  /* The list has been emptied */
1121  cpl_free(self->frame);
1122  cpl_free(self->propertylist);
1123  self->frame = NULL;
1124  self->propertylist = NULL;
1125  } else {
1126  /* Update the size of the arrays */
1127 
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*));
1132  }
1133 
1134 }
1135 
1136 /*----------------------------------------------------------------------------*/
1160 /*----------------------------------------------------------------------------*/
1161 static cpl_boolean irplib_property_equal(const cpl_propertylist * self,
1162  const cpl_propertylist * other,
1163  const char * key, cpl_type type,
1164  double fp_tol,
1165  char ** sstring, char ** ostring)
1166 {
1167 
1168  cpl_boolean equal;
1169 
1170 
1171  assert(self != NULL);
1172  assert(other != NULL);
1173  assert(key != NULL);
1174  assert(sstring != NULL);
1175  assert(ostring != NULL);
1176 
1177  /* FIXME: disable for better performance also with debugging */
1178  assert(cpl_propertylist_get_type(other, key) == type);
1179  assert(fp_tol >= 0.0);
1180 
1181  if (self == other) return CPL_TRUE;
1182 
1183  switch (type) {
1184 
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);
1188 
1189  equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1190  if (!equal) {
1191  *sstring = cpl_sprintf("%c", svalue);
1192  *ostring = cpl_sprintf("%c", ovalue);
1193  }
1194  break;
1195  }
1196 
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);
1200 
1201  equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1202  if (!equal) {
1203  *sstring = cpl_strdup(svalue == 0 ? "F" : "T");
1204  *ostring = cpl_strdup(ovalue == 0 ? "F" : "T");
1205  }
1206  break;
1207  }
1208 
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);
1212 
1213  equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1214  if (!equal) {
1215  *sstring = cpl_sprintf("%d", svalue);
1216  *ostring = cpl_sprintf("%d", ovalue);
1217  }
1218  break;
1219  }
1220 
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);
1224 
1225  equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1226  if (!equal) {
1227  *sstring = cpl_sprintf("%ld", svalue);
1228  *ostring = cpl_sprintf("%ld", ovalue);
1229  }
1230  break;
1231  }
1232 
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);
1236 
1237  equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
1238  if (!equal) {
1239  *sstring = cpl_sprintf("%f", svalue);
1240  *ostring = cpl_sprintf("%f", ovalue);
1241  }
1242  break;
1243  }
1244 
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);
1248 
1249  equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
1250  if (!equal) {
1251  *sstring = cpl_sprintf("%g", svalue);
1252  *ostring = cpl_sprintf("%g", ovalue);
1253  }
1254  break;
1255  }
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);
1259 
1260  equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
1261  if (!equal) {
1262  *sstring = cpl_strdup(svalue);
1263  *ostring = cpl_strdup(ovalue);
1264  }
1265  break;
1266  }
1267  default:
1268  /* Unknown property type */
1269  assert( 0 );
1270 
1271  equal = CPL_FALSE; /* In case of -DNDEBUG */
1272 
1273  }
1274 
1275  if (!equal) {
1276  assert( *sstring != NULL );
1277  assert( *ostring != NULL );
1278  }
1279 
1280  return equal;
1281 
1282 }
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.