00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifdef HAVE_CONFIG_H
00030 #include <config.h>
00031 #endif
00032
00033
00034
00035
00036
00037
00038 #include <stdio.h>
00039 #include <string.h>
00040 #include <sys/types.h>
00041 #include <regex.h>
00042 #include <math.h>
00043 #include <assert.h>
00044
00045 #include <cpl.h>
00046
00047 #include "irplib_framelist.h"
00048
00049
00050
00051
00052
00053
00054
00055 struct _irplib_framelist_ {
00056 int size;
00057 cpl_frame ** frame;
00058 cpl_propertylist ** propertylist;
00059
00060 };
00061
00062
00063
00064
00065
00066
00067 static void irplib_framelist_set_size(irplib_framelist *)
00068 #if defined __GNUC__ && __GNUC__ >= 4
00069 __attribute__((nonnull))
00070 #endif
00071 ;
00072
00073 static cpl_boolean irplib_property_equal(const cpl_propertylist *,
00074 const cpl_propertylist *,
00075 const char *, cpl_type, double,
00076 char **, char **)
00077 #if defined __GNUC__ && __GNUC__ >= 4
00078 __attribute__((nonnull))
00079 #endif
00080 ;
00081
00082 static const char * irplib_type_as_string(cpl_type);
00083
00084
00163
00164
00167
00168
00169
00170
00171
00179
00180 irplib_framelist * irplib_framelist_new(void)
00181 {
00182
00183 return (irplib_framelist *) cpl_calloc(1, sizeof(irplib_framelist));
00184
00185 }
00186
00187
00192
00193 void irplib_framelist_delete(irplib_framelist * self)
00194 {
00195
00196 irplib_framelist_empty(self);
00197 cpl_free(self);
00198 }
00199
00200
00201
00210
00211 irplib_framelist * irplib_framelist_cast(const cpl_frameset * frameset)
00212 {
00213
00214 irplib_framelist * self;
00215 const cpl_frame * frame;
00216 int i;
00217
00218
00219 cpl_ensure(frameset != NULL, CPL_ERROR_NULL_INPUT, NULL);
00220
00221
00222 self = irplib_framelist_new();
00223
00224 for (i = 0, frame = cpl_frameset_get_first_const(frameset);
00225 frame != NULL;
00226 i++, frame = cpl_frameset_get_next_const(frameset)) {
00227
00228 cpl_frame * copy = cpl_frame_duplicate(frame);
00229
00230 const cpl_error_code error = irplib_framelist_set(self, copy, i);
00231
00232 assert(error == CPL_ERROR_NONE);
00233
00234 }
00235
00236 assert(self->size == cpl_frameset_get_size(frameset));
00237
00238 return self;
00239
00240 }
00241
00242
00243
00252
00253 cpl_frameset * irplib_frameset_cast(const irplib_framelist * self)
00254 {
00255
00256 cpl_frameset * new;
00257 int i;
00258
00259 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00260
00261
00262 new = cpl_frameset_new();
00263
00264 for (i = 0; i < self->size; i++) {
00265 cpl_frame * frame = cpl_frame_duplicate(self->frame[i]);
00266 const cpl_error_code error = cpl_frameset_insert(new, frame);
00267
00268 assert(error == CPL_ERROR_NONE);
00269
00270 }
00271
00272 assert(self->size == cpl_frameset_get_size(new));
00273
00274 return new;
00275
00276 }
00277
00278
00279
00291
00292 irplib_framelist * irplib_framelist_extract(const irplib_framelist * self,
00293 const char * tag)
00294 {
00295
00296 irplib_framelist * new;
00297 int i, newsize;
00298
00299
00300 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00301 cpl_ensure(tag != NULL, CPL_ERROR_NULL_INPUT, NULL);
00302
00303 new = irplib_framelist_new();
00304 newsize = 0;
00305
00306 for (i = 0; i < self->size; i++) {
00307 const cpl_frame * frame = self->frame[i];
00308 const char * ftag = cpl_frame_get_tag(frame);
00309 cpl_frame * copy;
00310 cpl_error_code error;
00311
00312 if (ftag == NULL) {
00313
00314 irplib_framelist_delete(new);
00315 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00316 }
00317
00318 if (strcmp(tag, ftag)) continue;
00319
00320 copy = cpl_frame_duplicate(frame);
00321
00322 error = irplib_framelist_set(new, copy, newsize);
00323 assert(error == CPL_ERROR_NONE);
00324
00325 if (self->propertylist[i] != NULL) new->propertylist[newsize]
00326 = cpl_propertylist_duplicate(self->propertylist[i]);
00327
00328 newsize++;
00329 }
00330
00331 assert( newsize == new->size );
00332
00333 if (newsize == 0) {
00334 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00335 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00336 "The list of %d frame(s) has no frames "
00337 "with tag: %s", self->size, tag);
00338 #else
00339 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00340 "The list of frame(s) has no frames "
00341 "with the given tag");
00342 #endif
00343 irplib_framelist_delete(new);
00344 new = NULL;
00345 }
00346
00347 return new;
00348
00349 }
00350
00351
00361
00362 irplib_framelist * irplib_framelist_extract_regexp(const irplib_framelist* self,
00363 const char * regexp,
00364 cpl_boolean invert)
00365 {
00366
00367 irplib_framelist * new;
00368 int error;
00369 int i, newsize;
00370 const int xor = invert == CPL_FALSE ? 0 : 1;
00371 regex_t re;
00372
00373
00374 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00375 cpl_ensure(regexp != NULL, CPL_ERROR_NULL_INPUT, NULL);
00376
00377 error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
00378 cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, NULL);
00379
00380 new = irplib_framelist_new();
00381 newsize = 0;
00382
00383 for (i = 0; i < self->size; i++) {
00384 const cpl_frame * frame = self->frame[i];
00385 const char * tag = cpl_frame_get_tag(frame);
00386 cpl_frame * copy;
00387
00388 if (tag == NULL) {
00389
00390 irplib_framelist_delete(new);
00391 regfree(&re);
00392 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00393 }
00394
00395 if ((regexec(&re, tag, (size_t)0, NULL, 0) == REG_NOMATCH ? 1 : 0)
00396 ^ xor) continue;
00397
00398 copy = cpl_frame_duplicate(frame);
00399
00400 error = (int)irplib_framelist_set(new, copy, newsize);
00401 assert(error == CPL_ERROR_NONE);
00402
00403 if (self->propertylist[i] != NULL) new->propertylist[newsize]
00404 = cpl_propertylist_duplicate(self->propertylist[i]);
00405
00406 newsize++;
00407
00408 }
00409
00410 regfree(&re);
00411
00412 assert( newsize == new->size );
00413
00414 if (newsize == 0) {
00415 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00416 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00417 "The list of %d frame(s) has no frames "
00418 "that match: %s", self->size, regexp);
00419 #else
00420 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00421 "The list of frames has no frames "
00422 "that match the regular expression");
00423 #endif
00424 irplib_framelist_delete(new);
00425 new = NULL;
00426 }
00427
00428 return new;
00429 }
00430
00431
00432
00439
00440 int irplib_framelist_get_size(const irplib_framelist * self)
00441 {
00442
00443 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, -1);
00444
00445 return self->size;
00446
00447 }
00448
00449
00457
00458 cpl_frame * irplib_framelist_get(irplib_framelist * self, int pos)
00459 {
00460 return (cpl_frame *)irplib_framelist_get_const(self, pos);
00461
00462 }
00463
00464
00465
00473
00474 const cpl_frame * irplib_framelist_get_const(const irplib_framelist * self,
00475 int pos)
00476 {
00477
00478 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00479 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00480 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00481
00482 return self->frame[pos];
00483
00484 }
00485
00486
00487
00496
00497 cpl_error_code irplib_framelist_set_propertylist(irplib_framelist * self,
00498 int pos,
00499 const cpl_propertylist * list)
00500 {
00501
00502 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00503 cpl_ensure_code(list != NULL, CPL_ERROR_NULL_INPUT);
00504 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
00505 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00506
00507 cpl_propertylist_delete(self->propertylist[pos]);
00508
00509 self->propertylist[pos] = cpl_propertylist_duplicate(list);
00510
00511 cpl_ensure_code(self->propertylist[pos] != NULL, cpl_error_get_code());
00512
00513 return CPL_ERROR_NONE;
00514
00515 }
00516
00517
00518
00529
00530 cpl_propertylist * irplib_framelist_get_propertylist(irplib_framelist * self,
00531 int pos)
00532 {
00533
00534 return (cpl_propertylist *)irplib_framelist_get_propertylist_const(self,
00535 pos);
00536
00537 }
00538
00539
00540
00551
00552 const cpl_propertylist * irplib_framelist_get_propertylist_const(
00553 const irplib_framelist * self,
00554 int pos)
00555 {
00556 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00557 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00558 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00559
00560 cpl_ensure(self->propertylist[pos] != NULL,
00561 CPL_ERROR_DATA_NOT_FOUND, NULL);
00562
00563 return self->propertylist[pos];
00564
00565 }
00566
00567
00568
00582
00583 cpl_error_code irplib_framelist_load_propertylist(irplib_framelist * self,
00584 int pos, int ind,
00585 const char * regexp,
00586 cpl_boolean invert)
00587 {
00588
00589 const char * filename;
00590
00591
00592 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00593 cpl_ensure_code(regexp != NULL, CPL_ERROR_NULL_INPUT);
00594 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
00595 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00596
00597 filename = cpl_frame_get_filename(self->frame[pos]);
00598
00599 cpl_ensure_code(filename != NULL, cpl_error_get_code());
00600
00601 cpl_propertylist_delete(self->propertylist[pos]);
00602
00603 self->propertylist[pos] = cpl_propertylist_load_regexp(filename, ind,
00604 regexp,
00605 invert ? 1 : 0);
00606
00607 if (self->propertylist[pos] == NULL) {
00608 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00609 return cpl_error_set_message(cpl_func, cpl_error_get_code(), "Could "
00610 "not load FITS header from '%s' using "
00611 "regexp '%s'", filename, regexp);
00612 #else
00613 return cpl_error_set_message(cpl_func, cpl_error_get_code(),
00614 "Could not load FITS header");
00615 #endif
00616 }
00617
00618 return CPL_ERROR_NONE;
00619
00620 }
00621
00622
00623
00637
00638 cpl_error_code irplib_framelist_load_propertylist_all(irplib_framelist * self,
00639 int ind,
00640 const char * regexp,
00641 cpl_boolean invert)
00642 {
00643
00644 int nprops = 0;
00645 int nfiles = 0;
00646 int i;
00647
00648 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00649 cpl_ensure_code(regexp != NULL, CPL_ERROR_NULL_INPUT);
00650
00651 for (i=0; i < self->size; i++) {
00652 if (self->propertylist[i] == NULL)
00653 cpl_ensure_code(!irplib_framelist_load_propertylist(self, i,
00654 ind,
00655 regexp,
00656 invert),
00657 cpl_error_get_code());
00658
00659
00660 nprops += cpl_propertylist_get_size(self->propertylist[i]);
00661 nfiles++;
00662 }
00663
00664 cpl_msg_info(cpl_func, "List of %d frames has %d properties", nfiles,
00665 nprops);
00666
00667 return CPL_ERROR_NONE;
00668
00669 }
00670
00671
00672
00673
00681
00682 cpl_error_code irplib_framelist_set_tag_all(irplib_framelist * self,
00683 const char * tag)
00684 {
00685
00686 int i;
00687
00688 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00689 cpl_ensure_code(tag != NULL, CPL_ERROR_NULL_INPUT);
00690
00691 for (i=0; i < self->size; i++)
00692 cpl_ensure_code(!cpl_frame_set_tag(self->frame[i], tag),
00693 cpl_error_get_code());
00694
00695 return CPL_ERROR_NONE;
00696 }
00697
00698
00699
00713
00714 cpl_error_code irplib_framelist_set(irplib_framelist * self, cpl_frame * frame,
00715 int pos)
00716 {
00717
00718 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00719 cpl_ensure_code(frame != NULL, CPL_ERROR_NULL_INPUT);
00720 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
00721
00722 if (pos == self->size) {
00723
00724 self->size++;
00725
00726 irplib_framelist_set_size(self);
00727
00728 } else {
00729
00730 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00731
00732 cpl_frame_delete(self->frame[pos]);
00733 cpl_propertylist_delete(self->propertylist[pos]);
00734 }
00735
00736 self->frame[pos] = frame;
00737 self->propertylist[pos] = NULL;
00738
00739 return CPL_ERROR_NONE;
00740
00741 }
00742
00743
00752
00753 cpl_error_code irplib_framelist_erase(irplib_framelist * self, int pos)
00754 {
00755
00756 int i;
00757
00758 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00759 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
00760 cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00761
00762
00763
00764 cpl_frame_delete(self->frame[pos]);
00765 cpl_propertylist_delete(self->propertylist[pos]);
00766
00767
00768 for (i = pos+1; i < self->size; i++) {
00769
00770 self->frame[i-1] = self->frame[i];
00771
00772 self->propertylist[i-1] = self->propertylist[i];
00773
00774 }
00775
00776 self->size--;
00777
00778 irplib_framelist_set_size(self);
00779
00780 return CPL_ERROR_NONE;
00781
00782 }
00783
00784
00785
00786
00802
00803 cpl_frame * irplib_framelist_unset(irplib_framelist * self, int pos,
00804 cpl_propertylist ** plist)
00805
00806 {
00807 cpl_frame * frame;
00808 int i;
00809
00810
00811 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00812 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00813 cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00814
00815
00816 frame = self->frame[pos];
00817
00818 if (plist != NULL)
00819 *plist = self->propertylist[pos];
00820 else
00821 cpl_propertylist_delete(self->propertylist[pos]);
00822
00823
00824
00825 for (i = pos+1; i < self->size; i++) {
00826
00827 self->frame[i-1] = self->frame[i];
00828
00829 self->propertylist[i-1] = self->propertylist[i];
00830
00831 }
00832
00833 self->size--;
00834
00835 irplib_framelist_set_size(self);
00836
00837 return frame;
00838
00839 }
00840
00841
00848
00849 void irplib_framelist_empty(irplib_framelist * self)
00850 {
00851
00852 if (self != NULL) {
00853
00854
00855 while (self->size > 0) {
00856 self->size--;
00857 cpl_frame_delete(self->frame[self->size]);
00858 cpl_propertylist_delete(self->propertylist[self->size]);
00859
00860 }
00861
00862
00863 irplib_framelist_set_size(self);
00864
00865 }
00866 }
00867
00868
00869
00870
00908
00909 cpl_error_code irplib_framelist_contains(const irplib_framelist * self,
00910 const char * key, cpl_type type,
00911 cpl_boolean is_equal, double fp_tol)
00912 {
00913
00914 char * value_0;
00915 char * value_i;
00916 cpl_type type_0 = CPL_TYPE_INVALID;
00917 int i;
00918
00919
00920 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00921 cpl_ensure_code(key != NULL, CPL_ERROR_NULL_INPUT);
00922 cpl_ensure_code(fp_tol >= 0.0, CPL_ERROR_ILLEGAL_INPUT);
00923
00924 for (i=0; i < self->size; i++) {
00925 cpl_type type_i;
00926
00927
00928 if (self->propertylist[i] == NULL) continue;
00929
00930 type_i = cpl_propertylist_get_type(self->propertylist[i], key);
00931
00932 if (type_i == CPL_TYPE_INVALID) {
00933 if (type == CPL_TYPE_INVALID)
00934 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00935 cpl_error_set_message(cpl_func, cpl_error_get_code(), "FITS "
00936 "key '%s' is missing from file %s", key,
00937 cpl_frame_get_filename(self->frame[i]));
00938 else
00939 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00940 "FITS key '%s' [%s] is missing from file "
00941 "%s", key, irplib_type_as_string(type),
00942 cpl_frame_get_filename(self->frame[i]));
00943 #else
00944 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00945 "A FITS key is missing from a file");
00946 else
00947 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00948 "A FITS key is missing from a file");
00949 #endif
00950 return cpl_error_get_code();
00951 }
00952
00953 if (type != CPL_TYPE_INVALID && type_i != type) {
00954 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00955 return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
00956 "FITS key '%s' has type %s instead of "
00957 "%s in file %s", key,
00958 irplib_type_as_string(type_i),
00959 irplib_type_as_string(type),
00960 cpl_frame_get_filename(self->frame[i]));
00961 #else
00962 return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
00963 "A FITS key had an unexpected type");
00964 #endif
00965
00966 }
00967
00968 if (!is_equal) continue;
00969
00970 if (type_0 == CPL_TYPE_INVALID) {
00971 type_0 = type_i;
00972 continue;
00973 }
00974
00975 if (type_i != type_0) {
00976 assert( type == CPL_TYPE_INVALID );
00977 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00978 return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
00979 "FITS key '%s' has different types "
00980 "(%s <=> %s) in files %s and %s", key,
00981 irplib_type_as_string(type_0),
00982 irplib_type_as_string(type_i),
00983 cpl_frame_get_filename(self->frame[0]),
00984 cpl_frame_get_filename(self->frame[i]));
00985 #else
00986 return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
00987 "A FITS key has different types in "
00988 "two files");
00989 #endif
00990 }
00991
00992 if (irplib_property_equal(self->propertylist[0], self->propertylist[i],
00993 key, type_0, fp_tol, &value_0, &value_i))
00994 continue;
00995
00996 if ((type_0 == CPL_TYPE_FLOAT || type_0 == CPL_TYPE_DOUBLE)
00997 && fp_tol > 0.0) {
00998 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00999 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "FITS"
01000 " key '%s' [%s] has values that differ by "
01001 "more than %g (%s <=> %s) in files %s and %s",
01002 key, irplib_type_as_string(type_0), fp_tol,
01003 value_0, value_i,
01004 cpl_frame_get_filename(self->frame[0]),
01005 cpl_frame_get_filename(self->frame[i]));
01006 #else
01007 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "A "
01008 "FITS key has values that differ by more "
01009 "than the allowed tolerance in two file");
01010 #endif
01011 } else {
01012 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01013 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
01014 "FITS key '%s' [%s] has different values "
01015 "(%s <=> %s) in files %s and %s", key,
01016 irplib_type_as_string(type_0),
01017 value_0, value_i,
01018 cpl_frame_get_filename(self->frame[0]),
01019 cpl_frame_get_filename(self->frame[i]));
01020 #else
01021 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "A "
01022 "FITS key has different values in two files");
01023 #endif
01024 }
01025 cpl_free(value_0);
01026 cpl_free(value_i);
01027
01028 return cpl_error_get_code();
01029 }
01030
01031 return CPL_ERROR_NONE;
01032
01033 }
01034
01035
01036
01049
01050 cpl_imagelist * irplib_imagelist_load_framelist(const irplib_framelist * self,
01051 cpl_type pixeltype,
01052 int planenum,
01053 int extnum)
01054 {
01055
01056 cpl_imagelist * list = NULL;
01057 cpl_image * image = NULL;
01058 int i;
01059
01060
01061 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
01062 cpl_ensure(extnum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01063 cpl_ensure(planenum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01064
01065 list = cpl_imagelist_new();
01066
01067 for (i=0; i < self->size; i++, image = NULL) {
01068 const char * filename = cpl_frame_get_filename(self->frame[i]);
01069 cpl_error_code error;
01070
01071 if (filename == NULL) break;
01072
01073 image = cpl_image_load(filename, pixeltype, planenum, extnum);
01074 if (image == NULL) {
01075 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01076 (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
01077 "Could not load FITS-image from plane "
01078 "%d in extension %d in file %s",
01079 planenum, extnum, filename);
01080 #else
01081 (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
01082 "Could not load FITS-image");
01083 #endif
01084 break;
01085 }
01086
01087 error = cpl_imagelist_set(list, image, i);
01088 assert(error == CPL_ERROR_NONE);
01089 }
01090
01091 cpl_image_delete(image);
01092
01093 if (cpl_imagelist_get_size(list) != self->size) {
01094 cpl_imagelist_delete(list);
01095 list = NULL;
01096 assert(cpl_error_get_code() != CPL_ERROR_NONE);
01097 }
01098
01099 return list;
01100
01101 }
01102
01103
01107
01119
01120 static void irplib_framelist_set_size(irplib_framelist * self)
01121 {
01122
01123
01124 assert( self != NULL);
01125
01126 if (self->size == 0) {
01127
01128 cpl_free(self->frame);
01129 cpl_free(self->propertylist);
01130 self->frame = NULL;
01131 self->propertylist = NULL;
01132 } else {
01133
01134
01135 self->frame = cpl_realloc(self->frame, self->size * sizeof(cpl_frame*));
01136 self->propertylist =
01137 cpl_realloc(self->propertylist,
01138 self->size * sizeof(cpl_propertylist*));
01139 }
01140
01141 }
01142
01143
01167
01168 static cpl_boolean irplib_property_equal(const cpl_propertylist * self,
01169 const cpl_propertylist * other,
01170 const char * key, cpl_type type,
01171 double fp_tol,
01172 char ** sstring, char ** ostring)
01173 {
01174
01175 cpl_boolean equal;
01176
01177
01178 assert(self != NULL);
01179 assert(other != NULL);
01180 assert(key != NULL);
01181 assert(sstring != NULL);
01182 assert(ostring != NULL);
01183
01184
01185 assert(cpl_propertylist_get_type(other, key) == type);
01186 assert(fp_tol >= 0.0);
01187
01188 switch (type) {
01189
01190 case CPL_TYPE_CHAR: {
01191 const char svalue = cpl_propertylist_get_char(self, key);
01192 const char ovalue = cpl_propertylist_get_char(other, key);
01193
01194 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01195 if (!equal) {
01196 *sstring = cpl_sprintf("%c", svalue);
01197 *ostring = cpl_sprintf("%c", ovalue);
01198 }
01199 break;
01200 }
01201
01202 case CPL_TYPE_BOOL: {
01203 const int svalue = cpl_propertylist_get_bool(self, key);
01204 const int ovalue = cpl_propertylist_get_bool(other, key);
01205
01206 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01207 if (!equal) {
01208 *sstring = cpl_strdup(svalue == 0 ? "F" : "T");
01209 *ostring = cpl_strdup(ovalue == 0 ? "F" : "T");
01210 }
01211 break;
01212 }
01213
01214 case CPL_TYPE_INT: {
01215 const int svalue = cpl_propertylist_get_int(self, key);
01216 const int ovalue = cpl_propertylist_get_int(other, key);
01217
01218 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01219 if (!equal) {
01220 *sstring = cpl_sprintf("%d", svalue);
01221 *ostring = cpl_sprintf("%d", ovalue);
01222 }
01223 break;
01224 }
01225
01226 case CPL_TYPE_LONG: {
01227 const long svalue = cpl_propertylist_get_long(self, key);
01228 const long ovalue = cpl_propertylist_get_long(other, key);
01229
01230 equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01231 if (!equal) {
01232 *sstring = cpl_sprintf("%ld", svalue);
01233 *ostring = cpl_sprintf("%ld", ovalue);
01234 }
01235 break;
01236 }
01237
01238 case CPL_TYPE_FLOAT: {
01239 const double svalue = (double)cpl_propertylist_get_float(self, key);
01240 const double ovalue = (double)cpl_propertylist_get_float(other, key);
01241
01242 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01243 if (!equal) {
01244 *sstring = cpl_sprintf("%f", svalue);
01245 *ostring = cpl_sprintf("%f", ovalue);
01246 }
01247 break;
01248 }
01249
01250 case CPL_TYPE_DOUBLE: {
01251 const double svalue = cpl_propertylist_get_double(self, key);
01252 const double ovalue = cpl_propertylist_get_double(other, key);
01253
01254 equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01255 if (!equal) {
01256 *sstring = cpl_sprintf("%g", svalue);
01257 *ostring = cpl_sprintf("%g", ovalue);
01258 }
01259 break;
01260 }
01261 case CPL_TYPE_STRING: {
01262 const char * svalue = cpl_propertylist_get_string(self, key);
01263 const char * ovalue = cpl_propertylist_get_string(other, key);
01264
01265 equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
01266 if (!equal) {
01267 *sstring = cpl_strdup(svalue);
01268 *ostring = cpl_strdup(ovalue);
01269 }
01270 break;
01271 }
01272 default:
01273
01274 assert( 0 );
01275
01276 equal = CPL_FALSE;
01277
01278 }
01279
01280 if (!equal) {
01281 assert( *sstring != NULL );
01282 assert( *ostring != NULL );
01283 }
01284
01285 return equal;
01286
01287 }
01288
01289
01290
01291
01300
01301 static const char * irplib_type_as_string(cpl_type type)
01302 {
01303
01304 const char * self;
01305
01306
01307 switch (type) {
01308
01309 case CPL_TYPE_CHAR:
01310 self = "char";
01311 break;
01312
01313 case CPL_TYPE_BOOL:
01314 self = "boolean";
01315 break;
01316
01317 case CPL_TYPE_INT:
01318 self = "int";
01319 break;
01320
01321 case CPL_TYPE_LONG:
01322 self = "long";
01323 break;
01324
01325 case CPL_TYPE_FLOAT:
01326 self = "float";
01327 break;
01328
01329 case CPL_TYPE_DOUBLE:
01330 self = "double";
01331 break;
01332
01333 case CPL_TYPE_STRING:
01334 self = "string";
01335 break;
01336
01337 default:
01338
01339 cpl_ensure(0, CPL_ERROR_UNSUPPORTED_MODE, "");
01340
01341 }
01342
01343 return self;
01344
01345 }