irplib_framelist.c

00001 /* 
00002  * This file is part of the irplib package 
00003  * Copyright (C) 2002,2003 European Southern Observatory
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00018  */
00019 
00020 
00021 #ifdef HAVE_CONFIG_H
00022 #include <config.h>
00023 #endif
00024 
00025 
00026 /*-----------------------------------------------------------------------------
00027                                  Includes
00028  -----------------------------------------------------------------------------*/
00029 
00030 #include "irplib_framelist.h"
00031 #include "irplib_utils.h"
00032 #include <cpl.h>
00033 
00034 #include <stdio.h>
00035 #include <string.h>
00036 #include <sys/types.h>
00037 #include <regex.h>
00038 #include <math.h>
00039 #include <assert.h>
00040 
00041 
00042 /*-----------------------------------------------------------------------------
00043                                  New types
00044  -----------------------------------------------------------------------------*/
00045 
00046 /* @cond */
00047 struct _irplib_framelist_ {
00048     int size;
00049     cpl_frame        ** frame;
00050     cpl_propertylist ** propertylist;
00051 
00052 };
00053 /* @endcond */
00054 
00055 /*-----------------------------------------------------------------------------
00056                                  Private funcions
00057  -----------------------------------------------------------------------------*/
00058 
00059 static void irplib_framelist_set_size(irplib_framelist *)
00060 #if defined __GNUC__ &&  __GNUC__ >= 4
00061     __attribute__((nonnull))
00062 #endif
00063 ;
00064 
00065 static cpl_boolean irplib_property_equal(const cpl_propertylist *,
00066                                          const cpl_propertylist *,
00067                                          const char *, cpl_type, double,
00068                                          char **, char **)
00069 #if defined __GNUC__ &&  __GNUC__ >= 4
00070     __attribute__((nonnull))
00071 #endif
00072 ;
00073 
00074 /*----------------------------------------------------------------------------*/
00153 /*----------------------------------------------------------------------------*/
00154 
00157 /*-----------------------------------------------------------------------------
00158                             Function codes
00159  -----------------------------------------------------------------------------*/
00160 
00161 /*----------------------------------------------------------------------------*/
00169 /*----------------------------------------------------------------------------*/
00170 irplib_framelist * irplib_framelist_new(void)
00171 {
00172 
00173     return (irplib_framelist *) cpl_calloc(1, sizeof(irplib_framelist));
00174 
00175 }
00176 
00177 /*----------------------------------------------------------------------------*/
00182 /*----------------------------------------------------------------------------*/
00183 void irplib_framelist_delete(irplib_framelist * self)
00184 {
00185 
00186     irplib_framelist_empty(self);
00187     cpl_free(self);
00188 }
00189 
00190 
00191 /*----------------------------------------------------------------------------*/
00200 /*----------------------------------------------------------------------------*/
00201 irplib_framelist * irplib_framelist_cast(const cpl_frameset * frameset)
00202 {
00203 
00204     irplib_framelist * self;
00205     const cpl_frame * frame;
00206     int i;
00207 
00208 
00209     cpl_ensure(frameset != NULL, CPL_ERROR_NULL_INPUT, NULL);
00210 
00211     /* The function cannot fail now */
00212     self = irplib_framelist_new();
00213 
00214     for (i = 0; i < cpl_frameset_get_size(frameset); i++) 
00215     {
00216         frame = cpl_frameset_get_position_const(frameset, i);
00217 
00218         cpl_frame * copy = cpl_frame_duplicate(frame);
00219 
00220         const cpl_error_code error = irplib_framelist_set(self, copy, i);
00221 
00222         assert(error == CPL_ERROR_NONE);
00223 
00224     }
00225 
00226     assert(self->size == cpl_frameset_get_size(frameset));
00227 
00228     return self;
00229 
00230 }
00231 
00232 
00233 /*----------------------------------------------------------------------------*/
00242 /*----------------------------------------------------------------------------*/
00243 cpl_frameset * irplib_frameset_cast(const irplib_framelist * self)
00244 {
00245 
00246     cpl_frameset * new;
00247     int i;
00248 
00249     cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00250 
00251     /* The function cannot fail now */
00252     new = cpl_frameset_new();
00253 
00254     for (i = 0; i < self->size; i++) {
00255         cpl_frame * frame = cpl_frame_duplicate(self->frame[i]);
00256         const cpl_error_code error = cpl_frameset_insert(new, frame);
00257 
00258         assert(error == CPL_ERROR_NONE);
00259 
00260     }
00261 
00262     assert(self->size == cpl_frameset_get_size(new));
00263 
00264     return new;
00265 
00266 }
00267 
00268 
00269 /*----------------------------------------------------------------------------*/
00281 /*----------------------------------------------------------------------------*/
00282 irplib_framelist * irplib_framelist_extract(const irplib_framelist * self,
00283                                             const char * tag)
00284 {
00285 
00286     irplib_framelist * new;
00287     int i, newsize;
00288 
00289 
00290     cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00291     cpl_ensure(tag  != NULL, CPL_ERROR_NULL_INPUT, NULL);
00292 
00293     new = irplib_framelist_new();
00294     newsize = 0;
00295 
00296     for (i = 0; i < self->size; i++) {
00297         const cpl_frame * frame = self->frame[i];
00298         const char * ftag = cpl_frame_get_tag(frame);
00299         cpl_frame * copy;
00300         cpl_error_code error;
00301 
00302         if (ftag == NULL) {
00303             /* The frame is ill-formed */
00304             irplib_framelist_delete(new);
00305             cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00306         }
00307 
00308         if (strcmp(tag, ftag)) continue;
00309 
00310         copy = cpl_frame_duplicate(frame);
00311 
00312         error = irplib_framelist_set(new, copy, newsize);
00313         assert(error == CPL_ERROR_NONE);
00314 
00315         if (self->propertylist[i] != NULL) new->propertylist[newsize]
00316             = cpl_propertylist_duplicate(self->propertylist[i]);
00317 
00318         newsize++;
00319     }
00320 
00321     assert( newsize == new->size );
00322 
00323     if (newsize == 0) {
00324 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00325         cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00326                               "The list of %d frame(s) has no frames "
00327                               "with tag: %s", self->size, tag);
00328 #else
00329         cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00330                               "The list of frame(s) has no frames "
00331                               "with the given tag");
00332 #endif
00333         irplib_framelist_delete(new);
00334         new = NULL;
00335     }
00336 
00337     return new;
00338 
00339 }
00340 
00341 /*----------------------------------------------------------------------------*/
00351 /*----------------------------------------------------------------------------*/
00352 irplib_framelist * irplib_framelist_extract_regexp(const irplib_framelist* self,
00353                                                    const char * regexp,
00354                                                    cpl_boolean invert)
00355 {
00356 
00357     irplib_framelist * new;
00358     int error;
00359     int i, newsize;
00360     const int xor = invert == CPL_FALSE ? 0 : 1;
00361     regex_t re;
00362 
00363 
00364     cpl_ensure(self   != NULL, CPL_ERROR_NULL_INPUT, NULL);
00365     cpl_ensure(regexp != NULL, CPL_ERROR_NULL_INPUT, NULL);
00366 
00367     error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
00368     cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, NULL);
00369 
00370     new = irplib_framelist_new();
00371     newsize = 0;
00372 
00373     for (i = 0; i < self->size; i++) {
00374         const cpl_frame * frame = self->frame[i];
00375         const char * tag = cpl_frame_get_tag(frame);
00376         cpl_frame * copy;
00377 
00378         if (tag == NULL) {
00379             /* The frame is ill-formed */
00380             irplib_framelist_delete(new);
00381             regfree(&re);
00382             cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00383         }
00384 
00385         if ((regexec(&re, tag, (size_t)0, NULL, 0) == REG_NOMATCH ? 1 : 0)
00386             ^ xor) continue;
00387 
00388         copy = cpl_frame_duplicate(frame);
00389 
00390         error = (int)irplib_framelist_set(new, copy, newsize);
00391         assert(error == CPL_ERROR_NONE);
00392 
00393         if (self->propertylist[i] != NULL) new->propertylist[newsize]
00394             = cpl_propertylist_duplicate(self->propertylist[i]);
00395 
00396         newsize++;
00397 
00398     }
00399 
00400     regfree(&re);
00401 
00402     assert( newsize == new->size );
00403 
00404     if (newsize == 0) {
00405 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00406         cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00407                               "The list of %d frame(s) has no frames "
00408                               "that match: %s", self->size, regexp);
00409 #else
00410         cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00411                               "The list of frames has no frames "
00412                               "that match the regular expression");
00413 #endif
00414         irplib_framelist_delete(new);
00415         new = NULL;
00416     }
00417 
00418     return new;
00419 }
00420 
00421 
00422 /*----------------------------------------------------------------------------*/
00429 /*----------------------------------------------------------------------------*/
00430 int irplib_framelist_get_size(const irplib_framelist * self)
00431 {
00432 
00433     cpl_ensure(self != NULL,  CPL_ERROR_NULL_INPUT, -1);
00434 
00435     return self->size;
00436 
00437 }
00438 
00439 /*----------------------------------------------------------------------------*/
00447 /*----------------------------------------------------------------------------*/
00448 cpl_frame * irplib_framelist_get(irplib_framelist * self, int pos)
00449 {
00450     IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
00451     return (cpl_frame *)irplib_framelist_get_const(self, pos);
00452     IRPLIB_DIAG_PRAGMA_POP;
00453 }
00454 
00455 
00456 /*----------------------------------------------------------------------------*/
00464 /*----------------------------------------------------------------------------*/
00465 const cpl_frame * irplib_framelist_get_const(const irplib_framelist * self,
00466                                              int pos)
00467 {
00468 
00469     cpl_ensure(self != NULL,      CPL_ERROR_NULL_INPUT,          NULL);
00470     cpl_ensure(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT,       NULL);
00471     cpl_ensure(pos  < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00472 
00473     return self->frame[pos];
00474 
00475 }
00476 
00477 
00478 /*----------------------------------------------------------------------------*/
00487 /*----------------------------------------------------------------------------*/
00488 cpl_error_code irplib_framelist_set_propertylist(irplib_framelist * self,
00489                                                  int pos,
00490                                                  const cpl_propertylist * list)
00491 {
00492 
00493     cpl_ensure_code(self != NULL,      CPL_ERROR_NULL_INPUT);
00494     cpl_ensure_code(list != NULL,      CPL_ERROR_NULL_INPUT);
00495     cpl_ensure_code(pos  >= 0,         CPL_ERROR_ILLEGAL_INPUT);
00496     cpl_ensure_code(pos  < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00497 
00498     cpl_propertylist_delete(self->propertylist[pos]);
00499 
00500     self->propertylist[pos] = cpl_propertylist_duplicate(list);
00501 
00502     cpl_ensure_code(self->propertylist[pos] != NULL, cpl_error_get_code());
00503 
00504     return CPL_ERROR_NONE;
00505 
00506 }
00507 
00508 
00509 /*----------------------------------------------------------------------------*/
00520 /*----------------------------------------------------------------------------*/
00521 cpl_propertylist * irplib_framelist_get_propertylist(irplib_framelist * self,
00522                                                      int pos)
00523 {
00524 
00525     IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
00526     return (cpl_propertylist *)irplib_framelist_get_propertylist_const(self,
00527                                                                        pos);
00528     IRPLIB_DIAG_PRAGMA_POP;
00529 }
00530 
00531 
00532 /*----------------------------------------------------------------------------*/
00543 /*----------------------------------------------------------------------------*/
00544 const cpl_propertylist * irplib_framelist_get_propertylist_const(
00545                                                   const irplib_framelist * self,
00546                                                   int pos)
00547 {
00548     cpl_ensure(self != NULL,      CPL_ERROR_NULL_INPUT,          NULL);
00549     cpl_ensure(pos  >= 0,         CPL_ERROR_ILLEGAL_INPUT,       NULL);
00550     cpl_ensure(pos  < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00551 
00552     cpl_ensure(self->propertylist[pos] != NULL,
00553                   CPL_ERROR_DATA_NOT_FOUND, NULL);
00554 
00555     return self->propertylist[pos];
00556 
00557 }
00558 
00559 
00560 /*----------------------------------------------------------------------------*/
00574 /*----------------------------------------------------------------------------*/
00575 cpl_error_code irplib_framelist_load_propertylist(irplib_framelist * self,
00576                                                   int pos, int ind,
00577                                                   const char * regexp,
00578                                                   cpl_boolean invert)
00579 {
00580 
00581     const char * filename;
00582 
00583 
00584     cpl_ensure_code(self   != NULL,    CPL_ERROR_NULL_INPUT);
00585     cpl_ensure_code(regexp != NULL,    CPL_ERROR_NULL_INPUT);
00586     cpl_ensure_code(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT);
00587     cpl_ensure_code(pos <  self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00588 
00589     filename = cpl_frame_get_filename(self->frame[pos]);
00590 
00591     cpl_ensure_code(filename != NULL, cpl_error_get_code());
00592 
00593     cpl_propertylist_delete(self->propertylist[pos]);
00594 
00595     self->propertylist[pos] = cpl_propertylist_load_regexp(filename, ind,
00596                                                            regexp,
00597                                                            invert ? 1 : 0);
00598 
00599     if (self->propertylist[pos] == NULL) {
00600 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00601         return cpl_error_set_message(cpl_func, cpl_error_get_code(), "Could "
00602                                      "not load FITS header from '%s' using "
00603                                      "regexp '%s'", filename, regexp);
00604 #else
00605         return cpl_error_set_message(cpl_func, cpl_error_get_code(),
00606                                      "Could not load FITS header");
00607 #endif
00608     }
00609 
00610     return CPL_ERROR_NONE;
00611 
00612 }
00613 
00614 
00615 /*----------------------------------------------------------------------------*/
00629 /*----------------------------------------------------------------------------*/
00630 cpl_error_code irplib_framelist_load_propertylist_all(irplib_framelist * self,
00631                                                       int ind,
00632                                                       const char * regexp,
00633                                                       cpl_boolean invert)
00634 {
00635 
00636     int nprops = 0;
00637     int nfiles = 0;
00638     int i;
00639 
00640     cpl_ensure_code(self   != NULL,    CPL_ERROR_NULL_INPUT);
00641     cpl_ensure_code(regexp != NULL,    CPL_ERROR_NULL_INPUT);
00642 
00643     for (i=0; i < self->size; i++) {
00644         if (self->propertylist[i] == NULL)
00645             cpl_ensure_code(!irplib_framelist_load_propertylist(self, i,
00646                                                                 ind,
00647                                                                 regexp,
00648                                                                 invert),
00649                                cpl_error_get_code());
00650         /* Counting just for diagnostics - this actually causes
00651            the whole list to be reiterated :-( */
00652         nprops += cpl_propertylist_get_size(self->propertylist[i]);
00653         nfiles++;
00654     }
00655 
00656     cpl_msg_info(cpl_func, "List of %d frames has %d properties", nfiles,
00657                  nprops);
00658 
00659     return CPL_ERROR_NONE;
00660 
00661 }
00662 
00663 
00664 
00665 /*----------------------------------------------------------------------------*/
00673 /*----------------------------------------------------------------------------*/
00674 cpl_error_code irplib_framelist_set_tag_all(irplib_framelist * self,
00675                                             const char * tag)
00676 {
00677 
00678     int i;
00679 
00680     cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00681     cpl_ensure_code(tag  != NULL, CPL_ERROR_NULL_INPUT);
00682 
00683     for (i=0; i < self->size; i++)
00684         cpl_ensure_code(!cpl_frame_set_tag(self->frame[i], tag),
00685                            cpl_error_get_code());
00686 
00687     return CPL_ERROR_NONE;
00688 }
00689 
00690 
00691 /*----------------------------------------------------------------------------*/
00705 /*----------------------------------------------------------------------------*/
00706 cpl_error_code irplib_framelist_set(irplib_framelist * self, cpl_frame * frame,
00707                                     int pos)
00708 {
00709 
00710     cpl_ensure_code(self  != NULL,     CPL_ERROR_NULL_INPUT);
00711     cpl_ensure_code(frame != NULL,     CPL_ERROR_NULL_INPUT);
00712     cpl_ensure_code(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT);
00713 
00714     if (pos == self->size) {
00715 
00716         self->size++;
00717 
00718         irplib_framelist_set_size(self);
00719 
00720     } else {
00721 
00722         cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00723 
00724         cpl_frame_delete(self->frame[pos]);
00725         cpl_propertylist_delete(self->propertylist[pos]);
00726     }
00727 
00728     self->frame[pos] = frame;
00729     self->propertylist[pos] = NULL;
00730 
00731     return CPL_ERROR_NONE;
00732 
00733 }
00734 
00735 /*----------------------------------------------------------------------------*/
00744 /*----------------------------------------------------------------------------*/
00745 cpl_error_code irplib_framelist_erase(irplib_framelist * self, int pos)
00746 {
00747 
00748     int i;
00749 
00750     cpl_ensure_code(self  != NULL,    CPL_ERROR_NULL_INPUT);
00751     cpl_ensure_code(pos >= 0,         CPL_ERROR_ILLEGAL_INPUT);
00752     cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00753 
00754 
00755     /* Delete the specified frame and its propertylist */
00756     cpl_frame_delete(self->frame[pos]);
00757     cpl_propertylist_delete(self->propertylist[pos]);
00758 
00759     /* Move following frames down one position */
00760     for (i = pos+1; i < self->size; i++) {
00761 
00762         self->frame[i-1] = self->frame[i];
00763 
00764         self->propertylist[i-1] = self->propertylist[i];
00765 
00766     }
00767 
00768     self->size--;
00769 
00770     irplib_framelist_set_size(self);
00771 
00772     return CPL_ERROR_NONE;
00773 
00774 }
00775 
00776 
00777 
00778 /*----------------------------------------------------------------------------*/
00794 /*----------------------------------------------------------------------------*/
00795 cpl_frame * irplib_framelist_unset(irplib_framelist * self, int pos,
00796                                    cpl_propertylist ** plist)
00797 
00798 {
00799     cpl_frame * frame;
00800     int i;
00801 
00802 
00803     cpl_ensure(self  != NULL,    CPL_ERROR_NULL_INPUT, NULL);
00804     cpl_ensure(pos >= 0,         CPL_ERROR_ILLEGAL_INPUT, NULL);
00805     cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00806 
00807     /* Get the specified frame and its propertylist */
00808     frame = self->frame[pos];
00809 
00810     if (plist != NULL)
00811         *plist = self->propertylist[pos];
00812     else
00813         cpl_propertylist_delete(self->propertylist[pos]);
00814 
00815 
00816     /* Move following frames down one position */
00817     for (i = pos+1; i < self->size; i++) {
00818 
00819         self->frame[i-1] = self->frame[i];
00820 
00821         self->propertylist[i-1] = self->propertylist[i];
00822 
00823     }
00824 
00825     self->size--;
00826 
00827     irplib_framelist_set_size(self);
00828 
00829     return frame;
00830 
00831 }
00832 
00833 /*----------------------------------------------------------------------------*/
00840 /*----------------------------------------------------------------------------*/
00841 void irplib_framelist_empty(irplib_framelist * self)
00842 {
00843 
00844     if (self != NULL) {
00845 
00846         /* Deallocate all frames and their propertylists */
00847         while (self->size > 0) {
00848             self->size--;
00849             cpl_frame_delete(self->frame[self->size]);
00850             cpl_propertylist_delete(self->propertylist[self->size]);
00851 
00852         }
00853         
00854         /* Deallocate the arrays */
00855         irplib_framelist_set_size(self);
00856 
00857     }
00858 }
00859 
00860 
00861 
00862 /*----------------------------------------------------------------------------*/
00900 /*----------------------------------------------------------------------------*/
00901 cpl_error_code irplib_framelist_contains(const irplib_framelist * self,
00902                                          const char * key, cpl_type type,
00903                                          cpl_boolean is_equal, double fp_tol)
00904 {
00905 
00906     char * value_0;
00907     char * value_i;
00908     cpl_type type_0 = CPL_TYPE_INVALID;
00909     int i, ifirst = -1;  /* First non-NULL propertylist */
00910 
00911 
00912     cpl_ensure_code(self  != NULL, CPL_ERROR_NULL_INPUT);
00913     cpl_ensure_code(key   != NULL, CPL_ERROR_NULL_INPUT);
00914     cpl_ensure_code(fp_tol >= 0.0, CPL_ERROR_ILLEGAL_INPUT);
00915 
00916     for (i=0; i < self->size; i++) {
00917         cpl_type type_i;
00918 
00919 
00920         if (self->propertylist[i] == NULL) continue;
00921         if (ifirst < 0) ifirst = i;
00922 
00923         type_i = cpl_propertylist_get_type(self->propertylist[i], key);
00924 
00925         if (type_i == CPL_TYPE_INVALID) {
00926             if (type == CPL_TYPE_INVALID)
00927 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00928                 cpl_error_set_message(cpl_func, cpl_error_get_code(), "FITS "
00929                                       "key '%s' is missing from file %s", key,
00930                                       cpl_frame_get_filename(self->frame[i]));
00931             else
00932                 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00933                                       "FITS key '%s' [%s] is missing from file "
00934                                       "%s", key, cpl_type_get_name(type),
00935                                       cpl_frame_get_filename(self->frame[i]));
00936 #else
00937                 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00938                                       "A FITS key is missing from a file");
00939             else
00940                 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00941                                       "A FITS key is missing from a file");
00942 #endif
00943             return cpl_error_get_code();
00944         }
00945 
00946         if (type != CPL_TYPE_INVALID && type_i != type) {
00947 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00948             return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
00949                                          "FITS key '%s' has type %s instead of "
00950                                          "%s in file %s", key,
00951                                          cpl_type_get_name(type_i),
00952                                          cpl_type_get_name(type),
00953                                          cpl_frame_get_filename(self->frame[i]));
00954 #else
00955             return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
00956                                          "A FITS key had an unexpected type");
00957 #endif
00958 
00959         }
00960 
00961         if (!is_equal) continue;
00962 
00963         if (type_0 == CPL_TYPE_INVALID) {
00964             type_0 = type_i;
00965             continue;
00966         }
00967 
00968         if (type_i != type_0) {
00969             assert( type == CPL_TYPE_INVALID );
00970 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00971             return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
00972                                          "FITS key '%s' has different types "
00973                                          "(%s <=> %s) in files %s and %s", key,
00974                                          cpl_type_get_name(type_0),
00975                                          cpl_type_get_name(type_i),
00976                                          cpl_frame_get_filename(self->frame[0]),
00977                                          cpl_frame_get_filename(self->frame[i]));
00978 #else
00979             return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
00980                                          "A FITS key has different types in "
00981                                          "two files");
00982 #endif
00983         }
00984 
00985         if (irplib_property_equal(self->propertylist[ifirst],
00986                                   self->propertylist[i],
00987                                   key, type_0, fp_tol, &value_0, &value_i))
00988             continue;
00989 
00990         if ((type_0 == CPL_TYPE_FLOAT || type_0 == CPL_TYPE_DOUBLE)
00991             && fp_tol > 0.0) {
00992 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00993             cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "FITS"
00994                                   " key '%s' [%s] has values that differ by "
00995                                   "more than %g (%s <=> %s) in files %s and %s",
00996                                   key, cpl_type_get_name(type_0), fp_tol,
00997                                   value_0, value_i,
00998                                   cpl_frame_get_filename(self->frame[0]),
00999                                   cpl_frame_get_filename(self->frame[i]));
01000 #else
01001             cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "A "
01002                                   "FITS key has values that differ by more "
01003                                   "than the allowed tolerance in two file");
01004 #endif
01005         } else {
01006 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01007             cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
01008                                   "FITS key '%s' [%s] has different values "
01009                                   "(%s <=> %s) in files %s and %s", key,
01010                                   cpl_type_get_name(type_0),
01011                                   value_0, value_i,
01012                                   cpl_frame_get_filename(self->frame[0]),
01013                                   cpl_frame_get_filename(self->frame[i]));
01014 #else
01015             cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "A "
01016                                   "FITS key has different values in two files");
01017 #endif
01018         }
01019         cpl_free(value_0);
01020         cpl_free(value_i);
01021 
01022         return cpl_error_get_code();
01023     }        
01024 
01025     return CPL_ERROR_NONE;
01026 
01027 }
01028 
01029 
01030 /*----------------------------------------------------------------------------*/
01043 /*----------------------------------------------------------------------------*/
01044 cpl_imagelist * irplib_imagelist_load_framelist(const irplib_framelist * self,
01045                                                 cpl_type pixeltype,
01046                                                 int planenum,
01047                                                 int extnum)
01048 {
01049 
01050     cpl_imagelist * list = NULL;
01051     cpl_image     * image = NULL;
01052     int i;
01053 
01054 
01055     cpl_ensure(self != NULL,  CPL_ERROR_NULL_INPUT,          NULL);
01056     cpl_ensure(extnum >= 0,   CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01057     cpl_ensure(planenum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01058 
01059     list = cpl_imagelist_new();
01060 
01061     for (i=0; i < self->size; i++, image = NULL) {
01062         const char * filename = cpl_frame_get_filename(self->frame[i]);
01063         cpl_error_code error;
01064 
01065         if (filename == NULL) break;
01066 
01067         image = cpl_image_load(filename, pixeltype, planenum, extnum);
01068         if (image == NULL) {
01069 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01070             (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
01071                                         "Could not load FITS-image from plane "
01072                                         "%d in extension %d in file %s",
01073                                         planenum, extnum, filename);
01074 #else
01075             (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
01076                                         "Could not load FITS-image");
01077 #endif
01078             break;
01079         }
01080 
01081         error = cpl_imagelist_set(list, image, i);
01082         assert(error == CPL_ERROR_NONE);
01083     }
01084 
01085     cpl_image_delete(image);
01086     
01087     if (cpl_imagelist_get_size(list) != self->size) {
01088         cpl_imagelist_delete(list);
01089         list = NULL;
01090         assert(cpl_error_get_code() != CPL_ERROR_NONE);
01091     }
01092 
01093     return list;
01094 
01095 }
01096 
01097 
01101 /*----------------------------------------------------------------------------*/
01113 /*----------------------------------------------------------------------------*/
01114 static void irplib_framelist_set_size(irplib_framelist * self)
01115 {
01116 
01117 
01118     assert( self != NULL);
01119 
01120     if (self->size == 0) {
01121         /* The list has been emptied */
01122         cpl_free(self->frame);
01123         cpl_free(self->propertylist);
01124         self->frame = NULL;
01125         self->propertylist = NULL;
01126     } else {
01127         /* Update the size of the arrays */
01128 
01129         self->frame = cpl_realloc(self->frame, self->size * sizeof(cpl_frame*));
01130         self->propertylist =
01131             cpl_realloc(self->propertylist,
01132                         self->size * sizeof(cpl_propertylist*));
01133     }
01134 
01135 }
01136 
01137 /*----------------------------------------------------------------------------*/
01161 /*----------------------------------------------------------------------------*/
01162 static cpl_boolean irplib_property_equal(const cpl_propertylist * self,
01163                                          const cpl_propertylist * other,
01164                                          const char * key, cpl_type type,
01165                                          double fp_tol,
01166                                          char ** sstring, char ** ostring)
01167 {
01168 
01169     cpl_boolean equal;
01170 
01171 
01172     assert(self    != NULL);
01173     assert(other   != NULL);
01174     assert(key     != NULL);
01175     assert(sstring != NULL);
01176     assert(ostring != NULL);
01177 
01178     /* FIXME: disable for better performance also with debugging */
01179     assert(cpl_propertylist_get_type(other, key) == type);
01180     assert(fp_tol >= 0.0);
01181 
01182     if (self == other) return CPL_TRUE;
01183 
01184     switch (type) {
01185 
01186     case CPL_TYPE_CHAR: {
01187         const char svalue = cpl_propertylist_get_char(self, key);
01188         const char ovalue = cpl_propertylist_get_char(other, key);
01189 
01190         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01191         if (!equal) {
01192             *sstring = cpl_sprintf("%c", svalue);
01193             *ostring = cpl_sprintf("%c", ovalue);
01194         }
01195         break;
01196     }
01197 
01198     case CPL_TYPE_BOOL: {
01199         const int svalue = cpl_propertylist_get_bool(self, key);
01200         const int ovalue = cpl_propertylist_get_bool(other, key);
01201 
01202         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01203         if (!equal) {
01204             *sstring = cpl_strdup(svalue == 0 ? "F" : "T");
01205             *ostring = cpl_strdup(ovalue == 0 ? "F" : "T");
01206         }
01207         break;
01208     }
01209 
01210     case CPL_TYPE_INT: {
01211         const int svalue = cpl_propertylist_get_int(self, key);
01212         const int ovalue = cpl_propertylist_get_int(other, key);
01213 
01214         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01215         if (!equal) {
01216             *sstring = cpl_sprintf("%d", svalue);
01217             *ostring = cpl_sprintf("%d", ovalue);
01218         }
01219         break;
01220     }
01221 
01222     case CPL_TYPE_LONG: {
01223         const long svalue = cpl_propertylist_get_long(self, key);
01224         const long ovalue = cpl_propertylist_get_long(other, key);
01225 
01226         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01227         if (!equal) {
01228             *sstring = cpl_sprintf("%ld", svalue);
01229             *ostring = cpl_sprintf("%ld", ovalue);
01230         }
01231         break;
01232     }
01233 
01234     case CPL_TYPE_FLOAT: {
01235         const double svalue = (double)cpl_propertylist_get_float(self, key);
01236         const double ovalue = (double)cpl_propertylist_get_float(other, key);
01237 
01238         equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01239         if (!equal) {
01240             *sstring = cpl_sprintf("%f", svalue);
01241             *ostring = cpl_sprintf("%f", ovalue);
01242         }
01243         break;
01244     }
01245 
01246     case CPL_TYPE_DOUBLE: {
01247         const double svalue = cpl_propertylist_get_double(self, key);
01248         const double ovalue = cpl_propertylist_get_double(other, key);
01249 
01250         equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01251         if (!equal) {
01252             *sstring = cpl_sprintf("%g", svalue);
01253             *ostring = cpl_sprintf("%g", ovalue);
01254         }
01255         break;
01256     }
01257     case CPL_TYPE_STRING: {
01258         const char * svalue = cpl_propertylist_get_string(self, key);
01259         const char * ovalue = cpl_propertylist_get_string(other, key);
01260 
01261         equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
01262         if (!equal) {
01263             *sstring = cpl_strdup(svalue);
01264             *ostring = cpl_strdup(ovalue);
01265         }
01266         break;
01267     }
01268     default:
01269         /* Unknown property type */
01270         assert( 0 );
01271 
01272         equal = CPL_FALSE; /* In case of -DNDEBUG */
01273 
01274     }
01275 
01276     if (!equal) {
01277         assert( *sstring != NULL );
01278         assert( *ostring != NULL );
01279     }
01280 
01281     return equal;
01282 
01283 }
Generated on Mon Feb 17 15:01:44 2014 for NACO Pipeline Reference Manual by  doxygen 1.6.3