DETMON Pipeline Reference Manual  1.2.4
irplib_framelist.c
1 /* $Id: irplib_framelist.c,v 1.30 2013/02/27 16:05:13 jtaylor Exp $
2  *
3  * This file is part of the irplib package
4  * Copyright (C) 2002,2003 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: jtaylor $
23  * $Date: 2013/02/27 16:05:13 $
24  * $Revision: 1.30 $
25  * $Name: detmon-1_2_4 $
26  */
27 
28 
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 
33 
34 /*-----------------------------------------------------------------------------
35  Includes
36  -----------------------------------------------------------------------------*/
37 
38 #include "irplib_framelist.h"
39 #include "irplib_utils.h"
40 #include <cpl.h>
41 
42 #include <stdio.h>
43 #include <string.h>
44 #include <sys/types.h>
45 #include <regex.h>
46 #include <math.h>
47 #include <assert.h>
48 
49 
50 /*-----------------------------------------------------------------------------
51  New types
52  -----------------------------------------------------------------------------*/
53 
54 /* @cond */
55 struct _irplib_framelist_ {
56  int size;
57  cpl_frame ** frame;
58  cpl_propertylist ** propertylist;
59 
60 };
61 /* @endcond */
62 
63 /*-----------------------------------------------------------------------------
64  Private funcions
65  -----------------------------------------------------------------------------*/
66 
67 static void irplib_framelist_set_size(irplib_framelist *)
68 #if defined __GNUC__ && __GNUC__ >= 4
69  __attribute__((nonnull))
70 #endif
71 ;
72 
73 static cpl_boolean irplib_property_equal(const cpl_propertylist *,
74  const cpl_propertylist *,
75  const char *, cpl_type, double,
76  char **, char **)
77 #if defined __GNUC__ && __GNUC__ >= 4
78  __attribute__((nonnull))
79 #endif
80 ;
81 
82 /*----------------------------------------------------------------------------*/
161 /*----------------------------------------------------------------------------*/
162 
165 /*-----------------------------------------------------------------------------
166  Function codes
167  -----------------------------------------------------------------------------*/
168 
169 /*----------------------------------------------------------------------------*/
177 /*----------------------------------------------------------------------------*/
178 irplib_framelist * irplib_framelist_new(void)
179 {
180 
181  return (irplib_framelist *) cpl_calloc(1, sizeof(irplib_framelist));
182 
183 }
184 
185 /*----------------------------------------------------------------------------*/
190 /*----------------------------------------------------------------------------*/
191 void irplib_framelist_delete(irplib_framelist * self)
192 {
193 
195  cpl_free(self);
196 }
197 
198 
199 /*----------------------------------------------------------------------------*/
208 /*----------------------------------------------------------------------------*/
209 irplib_framelist * irplib_framelist_cast(const cpl_frameset * frameset)
210 {
211 
212  irplib_framelist * self;
213  const cpl_frame * frame;
214  int i;
215 
216 
217  cpl_ensure(frameset != NULL, CPL_ERROR_NULL_INPUT, NULL);
218 
219  /* The function cannot fail now */
220  self = irplib_framelist_new();
221 
222  for (i = 0, frame = cpl_frameset_get_first_const(frameset);
223  frame != NULL;
224  i++, frame = cpl_frameset_get_next_const(frameset)) {
225 
226  cpl_frame * copy = cpl_frame_duplicate(frame);
227 
228  const cpl_error_code error = irplib_framelist_set(self, copy, i);
229 
230  assert(error == CPL_ERROR_NONE);
231 
232  }
233 
234  assert(self->size == cpl_frameset_get_size(frameset));
235 
236  return self;
237 
238 }
239 
240 
241 /*----------------------------------------------------------------------------*/
250 /*----------------------------------------------------------------------------*/
251 cpl_frameset * irplib_frameset_cast(const irplib_framelist * self)
252 {
253 
254  cpl_frameset * new;
255  int i;
256 
257  cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
258 
259  /* The function cannot fail now */
260  new = cpl_frameset_new();
261 
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);
265 
266  assert(error == CPL_ERROR_NONE);
267 
268  }
269 
270  assert(self->size == cpl_frameset_get_size(new));
271 
272  return new;
273 
274 }
275 
276 
277 /*----------------------------------------------------------------------------*/
289 /*----------------------------------------------------------------------------*/
290 irplib_framelist * irplib_framelist_extract(const irplib_framelist * self,
291  const char * tag)
292 {
293 
294  irplib_framelist * new;
295  int i, newsize;
296 
297 
298  cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
299  cpl_ensure(tag != NULL, CPL_ERROR_NULL_INPUT, NULL);
300 
301  new = irplib_framelist_new();
302  newsize = 0;
303 
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);
307  cpl_frame * copy;
308  cpl_error_code error;
309 
310  if (ftag == NULL) {
311  /* The frame is ill-formed */
313  cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
314  }
315 
316  if (strcmp(tag, ftag)) continue;
317 
318  copy = cpl_frame_duplicate(frame);
319 
320  error = irplib_framelist_set(new, copy, newsize);
321  assert(error == CPL_ERROR_NONE);
322 
323  if (self->propertylist[i] != NULL) new->propertylist[newsize]
324  = cpl_propertylist_duplicate(self->propertylist[i]);
325 
326  newsize++;
327  }
328 
329  assert( newsize == new->size );
330 
331  if (newsize == 0) {
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);
336 #else
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");
340 #endif
342  new = NULL;
343  }
344 
345  return new;
346 
347 }
348 
349 /*----------------------------------------------------------------------------*/
359 /*----------------------------------------------------------------------------*/
360 irplib_framelist * irplib_framelist_extract_regexp(const irplib_framelist* self,
361  const char * regexp,
362  cpl_boolean invert)
363 {
364 
365  irplib_framelist * new;
366  int error;
367  int i, newsize;
368  const int xor = invert == CPL_FALSE ? 0 : 1;
369  regex_t re;
370 
371 
372  cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
373  cpl_ensure(regexp != NULL, CPL_ERROR_NULL_INPUT, NULL);
374 
375  error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
376  cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, NULL);
377 
378  new = irplib_framelist_new();
379  newsize = 0;
380 
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);
384  cpl_frame * copy;
385 
386  if (tag == NULL) {
387  /* The frame is ill-formed */
389  regfree(&re);
390  cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
391  }
392 
393  if ((regexec(&re, tag, (size_t)0, NULL, 0) == REG_NOMATCH ? 1 : 0)
394  ^ xor) continue;
395 
396  copy = cpl_frame_duplicate(frame);
397 
398  error = (int)irplib_framelist_set(new, copy, newsize);
399  assert(error == CPL_ERROR_NONE);
400 
401  if (self->propertylist[i] != NULL) new->propertylist[newsize]
402  = cpl_propertylist_duplicate(self->propertylist[i]);
403 
404  newsize++;
405 
406  }
407 
408  regfree(&re);
409 
410  assert( newsize == new->size );
411 
412  if (newsize == 0) {
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);
417 #else
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");
421 #endif
423  new = NULL;
424  }
425 
426  return new;
427 }
428 
429 
430 /*----------------------------------------------------------------------------*/
437 /*----------------------------------------------------------------------------*/
438 int irplib_framelist_get_size(const irplib_framelist * self)
439 {
440 
441  cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, -1);
442 
443  return self->size;
444 
445 }
446 
447 /*----------------------------------------------------------------------------*/
455 /*----------------------------------------------------------------------------*/
456 cpl_frame * irplib_framelist_get(irplib_framelist * self, int pos)
457 {
458  IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
459  return (cpl_frame *)irplib_framelist_get_const(self, pos);
460  IRPLIB_DIAG_PRAGMA_POP;
461 }
462 
463 
464 /*----------------------------------------------------------------------------*/
472 /*----------------------------------------------------------------------------*/
473 const cpl_frame * irplib_framelist_get_const(const irplib_framelist * self,
474  int pos)
475 {
476 
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);
480 
481  return self->frame[pos];
482 
483 }
484 
485 
486 /*----------------------------------------------------------------------------*/
495 /*----------------------------------------------------------------------------*/
496 cpl_error_code irplib_framelist_set_propertylist(irplib_framelist * self,
497  int pos,
498  const cpl_propertylist * list)
499 {
500 
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);
505 
506  cpl_propertylist_delete(self->propertylist[pos]);
507 
508  self->propertylist[pos] = cpl_propertylist_duplicate(list);
509 
510  cpl_ensure_code(self->propertylist[pos] != NULL, cpl_error_get_code());
511 
512  return CPL_ERROR_NONE;
513 
514 }
515 
516 
517 /*----------------------------------------------------------------------------*/
528 /*----------------------------------------------------------------------------*/
529 cpl_propertylist * irplib_framelist_get_propertylist(irplib_framelist * self,
530  int pos)
531 {
532 
533  IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
534  return (cpl_propertylist *)irplib_framelist_get_propertylist_const(self,
535  pos);
536  IRPLIB_DIAG_PRAGMA_POP;
537 }
538 
539 
540 /*----------------------------------------------------------------------------*/
551 /*----------------------------------------------------------------------------*/
553  const irplib_framelist * self,
554  int pos)
555 {
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);
559 
560  cpl_ensure(self->propertylist[pos] != NULL,
561  CPL_ERROR_DATA_NOT_FOUND, NULL);
562 
563  return self->propertylist[pos];
564 
565 }
566 
567 
568 /*----------------------------------------------------------------------------*/
582 /*----------------------------------------------------------------------------*/
583 cpl_error_code irplib_framelist_load_propertylist(irplib_framelist * self,
584  int pos, int ind,
585  const char * regexp,
586  cpl_boolean invert)
587 {
588 
589  const char * filename;
590 
591 
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);
596 
597  filename = cpl_frame_get_filename(self->frame[pos]);
598 
599  cpl_ensure_code(filename != NULL, cpl_error_get_code());
600 
601  cpl_propertylist_delete(self->propertylist[pos]);
602 
603  self->propertylist[pos] = cpl_propertylist_load_regexp(filename, ind,
604  regexp,
605  invert ? 1 : 0);
606 
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);
612 #else
613  return cpl_error_set_message(cpl_func, cpl_error_get_code(),
614  "Could not load FITS header");
615 #endif
616  }
617 
618  return CPL_ERROR_NONE;
619 
620 }
621 
622 
623 /*----------------------------------------------------------------------------*/
637 /*----------------------------------------------------------------------------*/
638 cpl_error_code irplib_framelist_load_propertylist_all(irplib_framelist * self,
639  int ind,
640  const char * regexp,
641  cpl_boolean invert)
642 {
643 
644  int nprops = 0;
645  int nfiles = 0;
646  int i;
647 
648  cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
649  cpl_ensure_code(regexp != NULL, CPL_ERROR_NULL_INPUT);
650 
651  for (i=0; i < self->size; i++) {
652  if (self->propertylist[i] == NULL)
653  cpl_ensure_code(!irplib_framelist_load_propertylist(self, i,
654  ind,
655  regexp,
656  invert),
657  cpl_error_get_code());
658  /* Counting just for diagnostics - this actually causes
659  the whole list to be reiterated :-( */
660  nprops += cpl_propertylist_get_size(self->propertylist[i]);
661  nfiles++;
662  }
663 
664  cpl_msg_info(cpl_func, "List of %d frames has %d properties", nfiles,
665  nprops);
666 
667  return CPL_ERROR_NONE;
668 
669 }
670 
671 
672 
673 /*----------------------------------------------------------------------------*/
681 /*----------------------------------------------------------------------------*/
682 cpl_error_code irplib_framelist_set_tag_all(irplib_framelist * self,
683  const char * tag)
684 {
685 
686  int i;
687 
688  cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
689  cpl_ensure_code(tag != NULL, CPL_ERROR_NULL_INPUT);
690 
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());
694 
695  return CPL_ERROR_NONE;
696 }
697 
698 
699 /*----------------------------------------------------------------------------*/
713 /*----------------------------------------------------------------------------*/
714 cpl_error_code irplib_framelist_set(irplib_framelist * self, cpl_frame * frame,
715  int pos)
716 {
717 
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);
721 
722  if (pos == self->size) {
723 
724  self->size++;
725 
726  irplib_framelist_set_size(self);
727 
728  } else {
729 
730  cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
731 
732  cpl_frame_delete(self->frame[pos]);
733  cpl_propertylist_delete(self->propertylist[pos]);
734  }
735 
736  self->frame[pos] = frame;
737  self->propertylist[pos] = NULL;
738 
739  return CPL_ERROR_NONE;
740 
741 }
742 
743 /*----------------------------------------------------------------------------*/
752 /*----------------------------------------------------------------------------*/
753 cpl_error_code irplib_framelist_erase(irplib_framelist * self, int pos)
754 {
755 
756  int i;
757 
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);
761 
762 
763  /* Delete the specified frame and its propertylist */
764  cpl_frame_delete(self->frame[pos]);
765  cpl_propertylist_delete(self->propertylist[pos]);
766 
767  /* Move following frames down one position */
768  for (i = pos+1; i < self->size; i++) {
769 
770  self->frame[i-1] = self->frame[i];
771 
772  self->propertylist[i-1] = self->propertylist[i];
773 
774  }
775 
776  self->size--;
777 
778  irplib_framelist_set_size(self);
779 
780  return CPL_ERROR_NONE;
781 
782 }
783 
784 
785 
786 /*----------------------------------------------------------------------------*/
802 /*----------------------------------------------------------------------------*/
803 cpl_frame * irplib_framelist_unset(irplib_framelist * self, int pos,
804  cpl_propertylist ** plist)
805 
806 {
807  cpl_frame * frame;
808  int i;
809 
810 
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);
814 
815  /* Get the specified frame and its propertylist */
816  frame = self->frame[pos];
817 
818  if (plist != NULL)
819  *plist = self->propertylist[pos];
820  else
821  cpl_propertylist_delete(self->propertylist[pos]);
822 
823 
824  /* Move following frames down one position */
825  for (i = pos+1; i < self->size; i++) {
826 
827  self->frame[i-1] = self->frame[i];
828 
829  self->propertylist[i-1] = self->propertylist[i];
830 
831  }
832 
833  self->size--;
834 
835  irplib_framelist_set_size(self);
836 
837  return frame;
838 
839 }
840 
841 /*----------------------------------------------------------------------------*/
848 /*----------------------------------------------------------------------------*/
849 void irplib_framelist_empty(irplib_framelist * self)
850 {
851 
852  if (self != NULL) {
853 
854  /* Deallocate all frames and their propertylists */
855  while (self->size > 0) {
856  self->size--;
857  cpl_frame_delete(self->frame[self->size]);
858  cpl_propertylist_delete(self->propertylist[self->size]);
859 
860  }
861 
862  /* Deallocate the arrays */
863  irplib_framelist_set_size(self);
864 
865  }
866 }
867 
868 
869 
870 /*----------------------------------------------------------------------------*/
908 /*----------------------------------------------------------------------------*/
909 cpl_error_code irplib_framelist_contains(const irplib_framelist * self,
910  const char * key, cpl_type type,
911  cpl_boolean is_equal, double fp_tol)
912 {
913 
914  char * value_0;
915  char * value_i;
916  cpl_type type_0 = CPL_TYPE_INVALID;
917  int i, ifirst = -1; /* First non-NULL propertylist */
918 
919 
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);
923 
924  for (i=0; i < self->size; i++) {
925  cpl_type type_i;
926 
927 
928  if (self->propertylist[i] == NULL) continue;
929  if (ifirst < 0) ifirst = i;
930 
931  type_i = cpl_propertylist_get_type(self->propertylist[i], key);
932 
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]));
939  else
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]));
944 #else
945  cpl_error_set_message(cpl_func, cpl_error_get_code(),
946  "A FITS key is missing from a file");
947  else
948  cpl_error_set_message(cpl_func, cpl_error_get_code(),
949  "A FITS key is missing from a file");
950 #endif
951  return cpl_error_get_code();
952  }
953 
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]));
962 #else
963  return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
964  "A FITS key had an unexpected type");
965 #endif
966 
967  }
968 
969  if (!is_equal) continue;
970 
971  if (type_0 == CPL_TYPE_INVALID) {
972  type_0 = type_i;
973  continue;
974  }
975 
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]));
986 #else
987  return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
988  "A FITS key has different types in "
989  "two files");
990 #endif
991  }
992 
993  if (irplib_property_equal(self->propertylist[ifirst],
994  self->propertylist[i],
995  key, type_0, fp_tol, &value_0, &value_i))
996  continue;
997 
998  if ((type_0 == CPL_TYPE_FLOAT || type_0 == CPL_TYPE_DOUBLE)
999  && fp_tol > 0.0) {
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,
1005  value_0, value_i,
1006  cpl_frame_get_filename(self->frame[0]),
1007  cpl_frame_get_filename(self->frame[i]));
1008 #else
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");
1012 #endif
1013  } else {
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),
1019  value_0, value_i,
1020  cpl_frame_get_filename(self->frame[0]),
1021  cpl_frame_get_filename(self->frame[i]));
1022 #else
1023  cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "A "
1024  "FITS key has different values in two files");
1025 #endif
1026  }
1027  cpl_free(value_0);
1028  cpl_free(value_i);
1029 
1030  return cpl_error_get_code();
1031  }
1032 
1033  return CPL_ERROR_NONE;
1034 
1035 }
1036 
1037 
1038 /*----------------------------------------------------------------------------*/
1051 /*----------------------------------------------------------------------------*/
1052 cpl_imagelist * irplib_imagelist_load_framelist(const irplib_framelist * self,
1053  cpl_type pixeltype,
1054  int planenum,
1055  int extnum)
1056 {
1057 
1058  cpl_imagelist * list = NULL;
1059  cpl_image * image = NULL;
1060  int i;
1061 
1062 
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);
1066 
1067  list = cpl_imagelist_new();
1068 
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;
1072 
1073  if (filename == NULL) break;
1074 
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);
1082 #else
1083  (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
1084  "Could not load FITS-image");
1085 #endif
1086  break;
1087  }
1088 
1089  error = cpl_imagelist_set(list, image, i);
1090  assert(error == CPL_ERROR_NONE);
1091  }
1092 
1093  cpl_image_delete(image);
1094 
1095  if (cpl_imagelist_get_size(list) != self->size) {
1096  cpl_imagelist_delete(list);
1097  list = NULL;
1098  assert(cpl_error_get_code() != CPL_ERROR_NONE);
1099  }
1100 
1101  return list;
1102 
1103 }
1104 
1105 
1109 /*----------------------------------------------------------------------------*/
1121 /*----------------------------------------------------------------------------*/
1122 static void irplib_framelist_set_size(irplib_framelist * self)
1123 {
1124 
1125 
1126  assert( self != NULL);
1127 
1128  if (self->size == 0) {
1129  /* The list has been emptied */
1130  cpl_free(self->frame);
1131  cpl_free(self->propertylist);
1132  self->frame = NULL;
1133  self->propertylist = NULL;
1134  } else {
1135  /* Update the size of the arrays */
1136 
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*));
1141  }
1142 
1143 }
1144 
1145 /*----------------------------------------------------------------------------*/
1169 /*----------------------------------------------------------------------------*/
1170 static cpl_boolean irplib_property_equal(const cpl_propertylist * self,
1171  const cpl_propertylist * other,
1172  const char * key, cpl_type type,
1173  double fp_tol,
1174  char ** sstring, char ** ostring)
1175 {
1176 
1177  cpl_boolean equal;
1178 
1179 
1180  assert(self != NULL);
1181  assert(other != NULL);
1182  assert(key != NULL);
1183  assert(sstring != NULL);
1184  assert(ostring != NULL);
1185 
1186  /* FIXME: disable for better performance also with debugging */
1187  assert(cpl_propertylist_get_type(other, key) == type);
1188  assert(fp_tol >= 0.0);
1189 
1190  if (self == other) return CPL_TRUE;
1191 
1192  switch (type) {
1193 
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);
1197 
1198  equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1199  if (!equal) {
1200  *sstring = cpl_sprintf("%c", svalue);
1201  *ostring = cpl_sprintf("%c", ovalue);
1202  }
1203  break;
1204  }
1205 
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);
1209 
1210  equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1211  if (!equal) {
1212  *sstring = cpl_strdup(svalue == 0 ? "F" : "T");
1213  *ostring = cpl_strdup(ovalue == 0 ? "F" : "T");
1214  }
1215  break;
1216  }
1217 
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);
1221 
1222  equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1223  if (!equal) {
1224  *sstring = cpl_sprintf("%d", svalue);
1225  *ostring = cpl_sprintf("%d", ovalue);
1226  }
1227  break;
1228  }
1229 
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);
1233 
1234  equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
1235  if (!equal) {
1236  *sstring = cpl_sprintf("%ld", svalue);
1237  *ostring = cpl_sprintf("%ld", ovalue);
1238  }
1239  break;
1240  }
1241 
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);
1245 
1246  equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
1247  if (!equal) {
1248  *sstring = cpl_sprintf("%f", svalue);
1249  *ostring = cpl_sprintf("%f", ovalue);
1250  }
1251  break;
1252  }
1253 
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);
1257 
1258  equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
1259  if (!equal) {
1260  *sstring = cpl_sprintf("%g", svalue);
1261  *ostring = cpl_sprintf("%g", ovalue);
1262  }
1263  break;
1264  }
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);
1268 
1269  equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
1270  if (!equal) {
1271  *sstring = cpl_strdup(svalue);
1272  *ostring = cpl_strdup(ovalue);
1273  }
1274  break;
1275  }
1276  default:
1277  /* Unknown property type */
1278  assert( 0 );
1279 
1280  equal = CPL_FALSE; /* In case of -DNDEBUG */
1281 
1282  }
1283 
1284  if (!equal) {
1285  assert( *sstring != NULL );
1286  assert( *ostring != NULL );
1287  }
1288 
1289  return equal;
1290 
1291 }