irplib_framelist.c

00001 /* $Id: irplib_framelist.c,v 1.27 2009/02/17 10:15:46 llundin Exp $
00002  *
00003  * This file is part of the irplib package 
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2009/02/17 10:15:46 $
00024  * $Revision: 1.27 $
00025  * $Name: naco-4_1_2 $
00026  */
00027 
00028 
00029 #ifdef HAVE_CONFIG_H
00030 #include <config.h>
00031 #endif
00032 
00033 
00034 /*-----------------------------------------------------------------------------
00035                                  Includes
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                                  New types
00052  -----------------------------------------------------------------------------*/
00053 
00054 /* @cond */
00055 struct _irplib_framelist_ {
00056     int size;
00057     cpl_frame        ** frame;
00058     cpl_propertylist ** propertylist;
00059 
00060 };
00061 /* @endcond */
00062 
00063 /*-----------------------------------------------------------------------------
00064                                  Private funcions
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                             Function codes
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     /* The function cannot fail now */
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     /* The function cannot fail now */
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             /* The frame is ill-formed */
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             /* The frame is ill-formed */
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         /* Counting just for diagnostics - this actually causes
00659            the whole list to be reiterated :-( */
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     /* Delete the specified frame and its propertylist */
00764     cpl_frame_delete(self->frame[pos]);
00765     cpl_propertylist_delete(self->propertylist[pos]);
00766 
00767     /* Move following frames down one position */
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     /* Get the specified frame and its propertylist */
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     /* Move following frames down one position */
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         /* Deallocate all frames and their propertylists */
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         /* Deallocate the arrays */
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         /* The list has been emptied */
01128         cpl_free(self->frame);
01129         cpl_free(self->propertylist);
01130         self->frame = NULL;
01131         self->propertylist = NULL;
01132     } else {
01133         /* Update the size of the arrays */
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     /* FIXME: disable for better performance also with debugging */
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         /* Unknown property type */
01274         assert( 0 );
01275 
01276         equal = CPL_FALSE; /* In case of -DNDEBUG */
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 }

Generated on Fri Jul 3 11:23:57 2009 for NACO Pipeline Reference Manual by  doxygen 1.5.8