irplib_framelist.c

00001 /* $Id: irplib_framelist.c,v 1.25 2007/08/02 12:32:31 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: 2007/08/02 12:32:31 $
00024  * $Revision: 1.25 $
00025  * $Name: uves-3_9_0 $
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         cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00335                               "The list of %d frame(s) has no frames "
00336                               "with tag: %s", self->size, tag);
00337         irplib_framelist_delete(new);
00338         new = NULL;
00339     }
00340 
00341     return new;
00342 
00343 }
00344 
00345 /*----------------------------------------------------------------------------*/
00355 /*----------------------------------------------------------------------------*/
00356 irplib_framelist * irplib_framelist_extract_regexp(const irplib_framelist* self,
00357                                                    const char * regexp,
00358                                                    cpl_boolean invert)
00359 {
00360 
00361     irplib_framelist * new;
00362     int error;
00363     int i, newsize;
00364     const int xor = invert == CPL_FALSE ? 0 : 1;
00365     regex_t re;
00366 
00367 
00368     cpl_ensure(self   != NULL, CPL_ERROR_NULL_INPUT, NULL);
00369     cpl_ensure(regexp != NULL, CPL_ERROR_NULL_INPUT, NULL);
00370 
00371     error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
00372     cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, NULL);
00373 
00374     new = irplib_framelist_new();
00375     newsize = 0;
00376 
00377     for (i = 0; i < self->size; i++) {
00378         const cpl_frame * frame = self->frame[i];
00379         const char * tag = cpl_frame_get_tag(frame);
00380         cpl_frame * copy;
00381 
00382         if (tag == NULL) {
00383             /* The frame is ill-formed */
00384             irplib_framelist_delete(new);
00385             regfree(&re);
00386             cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00387         }
00388 
00389         if ((regexec(&re, tag, (size_t)0, NULL, 0) == REG_NOMATCH ? 1 : 0)
00390             ^ xor) continue;
00391 
00392         copy = cpl_frame_duplicate(frame);
00393 
00394         error = (int)irplib_framelist_set(new, copy, newsize);
00395         assert(error == CPL_ERROR_NONE);
00396 
00397         if (self->propertylist[i] != NULL) new->propertylist[newsize]
00398             = cpl_propertylist_duplicate(self->propertylist[i]);
00399 
00400         newsize++;
00401 
00402     }
00403 
00404     regfree(&re);
00405 
00406     assert( newsize == new->size );
00407 
00408     if (newsize == 0) {
00409         cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00410                               "The list of %d frame(s) has no frames "
00411                               "that match: %s", self->size, regexp);
00412         irplib_framelist_delete(new);
00413         new = NULL;
00414     }
00415 
00416     return new;
00417 }
00418 
00419 
00420 /*----------------------------------------------------------------------------*/
00427 /*----------------------------------------------------------------------------*/
00428 int irplib_framelist_get_size(const irplib_framelist * self)
00429 {
00430 
00431     cpl_ensure(self != NULL,  CPL_ERROR_NULL_INPUT, -1);
00432 
00433     return self->size;
00434 
00435 }
00436 
00437 /*----------------------------------------------------------------------------*/
00445 /*----------------------------------------------------------------------------*/
00446 cpl_frame * irplib_framelist_get(irplib_framelist * self, int pos)
00447 {
00448     return (cpl_frame *)irplib_framelist_get_const(self, pos);
00449 
00450 }
00451 
00452 
00453 /*----------------------------------------------------------------------------*/
00461 /*----------------------------------------------------------------------------*/
00462 const cpl_frame * irplib_framelist_get_const(const irplib_framelist * self,
00463                                              int pos)
00464 {
00465 
00466     cpl_ensure(self != NULL,      CPL_ERROR_NULL_INPUT,          NULL);
00467     cpl_ensure(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT,       NULL);
00468     cpl_ensure(pos <= self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00469 
00470     return self->frame[pos];
00471 
00472 }
00473 
00474 
00475 /*----------------------------------------------------------------------------*/
00484 /*----------------------------------------------------------------------------*/
00485 cpl_error_code irplib_framelist_set_propertylist(irplib_framelist * self,
00486                                                  int pos,
00487                                                  const cpl_propertylist * list)
00488 {
00489 
00490     cpl_ensure_code(self != NULL,      CPL_ERROR_NULL_INPUT);
00491     cpl_ensure_code(list != NULL,      CPL_ERROR_NULL_INPUT);
00492     cpl_ensure_code(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT);
00493     cpl_ensure_code(pos <= self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00494 
00495     cpl_propertylist_delete(self->propertylist[pos]);
00496 
00497     self->propertylist[pos] = cpl_propertylist_duplicate(list);
00498 
00499     cpl_ensure_code(self->propertylist[pos] != NULL, cpl_error_get_code());
00500 
00501     return CPL_ERROR_NONE;
00502 
00503 }
00504 
00505 
00506 /*----------------------------------------------------------------------------*/
00517 /*----------------------------------------------------------------------------*/
00518 cpl_propertylist * irplib_framelist_get_propertylist(irplib_framelist * self,
00519                                                      int pos)
00520 {
00521 
00522     return (cpl_propertylist *)irplib_framelist_get_propertylist_const(self,
00523                                                                        pos);
00524 
00525 }
00526 
00527 
00528 /*----------------------------------------------------------------------------*/
00539 /*----------------------------------------------------------------------------*/
00540 const cpl_propertylist * irplib_framelist_get_propertylist_const(
00541                                                   const irplib_framelist * self,
00542                                                   int pos)
00543 {
00544     cpl_ensure(self != NULL,      CPL_ERROR_NULL_INPUT,          NULL);
00545     cpl_ensure(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT,       NULL);
00546     cpl_ensure(pos <= self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00547 
00548     cpl_ensure(self->propertylist[pos] != NULL,
00549                   CPL_ERROR_DATA_NOT_FOUND, NULL);
00550 
00551     return self->propertylist[pos];
00552 
00553 }
00554 
00555 
00556 /*----------------------------------------------------------------------------*/
00570 /*----------------------------------------------------------------------------*/
00571 cpl_error_code irplib_framelist_load_propertylist(irplib_framelist * self,
00572                                                   int pos, int ind,
00573                                                   const char * regexp,
00574                                                   cpl_boolean invert)
00575 {
00576 
00577     const char * filename;
00578 
00579 
00580     cpl_ensure_code(self   != NULL,    CPL_ERROR_NULL_INPUT);
00581     cpl_ensure_code(regexp != NULL,    CPL_ERROR_NULL_INPUT);
00582     cpl_ensure_code(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT);
00583     cpl_ensure_code(pos <= self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00584 
00585     filename = cpl_frame_get_filename(self->frame[pos]);
00586 
00587     cpl_ensure_code(filename != NULL, cpl_error_get_code());
00588 
00589     cpl_propertylist_delete(self->propertylist[pos]);
00590 
00591     self->propertylist[pos] = cpl_propertylist_load_regexp(filename, ind,
00592                                                            regexp,
00593                                                            invert ? 1 : 0);
00594 
00595     if (self->propertylist[pos] == NULL) {
00596         return cpl_error_set_message(cpl_func, cpl_error_get_code(), "Could "
00597                                      "not load FITS header from '%s' using "
00598                                      "regexp '%s'", filename, regexp);
00599     }
00600 
00601     return CPL_ERROR_NONE;
00602 
00603 }
00604 
00605 
00606 /*----------------------------------------------------------------------------*/
00620 /*----------------------------------------------------------------------------*/
00621 cpl_error_code irplib_framelist_load_propertylist_all(irplib_framelist * self,
00622                                                       int ind,
00623                                                       const char * regexp,
00624                                                       cpl_boolean invert)
00625 {
00626 
00627     int nprops = 0;
00628     int nfiles = 0;
00629     int i;
00630 
00631     cpl_ensure_code(self   != NULL,    CPL_ERROR_NULL_INPUT);
00632     cpl_ensure_code(regexp != NULL,    CPL_ERROR_NULL_INPUT);
00633 
00634     for (i=0; i < self->size; i++) {
00635         if (self->propertylist[i] == NULL)
00636             cpl_ensure_code(!irplib_framelist_load_propertylist(self, i,
00637                                                                 ind,
00638                                                                 regexp,
00639                                                                 invert),
00640                                cpl_error_get_code());
00641         /* Counting just for diagnostics - this actually causes
00642            the whole list to be reiterated :-( */
00643         nprops += cpl_propertylist_get_size(self->propertylist[i]);
00644         nfiles++;
00645     }
00646 
00647     cpl_msg_info(cpl_func, "List of %d frames has %d properties", nfiles,
00648                  nprops);
00649 
00650     return CPL_ERROR_NONE;
00651 
00652 }
00653 
00654 
00655 
00656 /*----------------------------------------------------------------------------*/
00664 /*----------------------------------------------------------------------------*/
00665 cpl_error_code irplib_framelist_set_tag_all(irplib_framelist * self,
00666                                             const char * tag)
00667 {
00668 
00669     int i;
00670 
00671     cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00672     cpl_ensure_code(tag  != NULL, CPL_ERROR_NULL_INPUT);
00673 
00674     for (i=0; i < self->size; i++)
00675         cpl_ensure_code(!cpl_frame_set_tag(self->frame[i], tag),
00676                            cpl_error_get_code());
00677 
00678     return CPL_ERROR_NONE;
00679 }
00680 
00681 
00682 /*----------------------------------------------------------------------------*/
00696 /*----------------------------------------------------------------------------*/
00697 cpl_error_code irplib_framelist_set(irplib_framelist * self, cpl_frame * frame,
00698                                     int pos)
00699 {
00700 
00701     cpl_ensure_code(self  != NULL,     CPL_ERROR_NULL_INPUT);
00702     cpl_ensure_code(frame != NULL,     CPL_ERROR_NULL_INPUT);
00703     cpl_ensure_code(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT);
00704 
00705     if (pos == self->size) {
00706 
00707         self->size++;
00708 
00709         irplib_framelist_set_size(self);
00710 
00711     } else {
00712 
00713         cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00714 
00715         cpl_frame_delete(self->frame[pos]);
00716         cpl_propertylist_delete(self->propertylist[pos]);
00717     }
00718 
00719     self->frame[pos] = frame;
00720     self->propertylist[pos] = NULL;
00721 
00722     return CPL_ERROR_NONE;
00723 
00724 }
00725 
00726 /*----------------------------------------------------------------------------*/
00735 /*----------------------------------------------------------------------------*/
00736 cpl_error_code irplib_framelist_erase(irplib_framelist * self, int pos)
00737 {
00738 
00739     int i;
00740 
00741     cpl_ensure_code(self  != NULL,    CPL_ERROR_NULL_INPUT);
00742     cpl_ensure_code(pos >= 0,         CPL_ERROR_ILLEGAL_INPUT);
00743     cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00744 
00745 
00746     /* Delete the specified frame and its propertylist */
00747     cpl_frame_delete(self->frame[pos]);
00748     cpl_propertylist_delete(self->propertylist[pos]);
00749 
00750     /* Move following frames down one position */
00751     for (i = pos+1; i < self->size; i++) {
00752 
00753         self->frame[i-1] = self->frame[i];
00754 
00755         self->propertylist[i-1] = self->propertylist[i];
00756 
00757     }
00758 
00759     self->size--;
00760 
00761     irplib_framelist_set_size(self);
00762 
00763     return CPL_ERROR_NONE;
00764 
00765 }
00766 
00767 
00768 
00769 /*----------------------------------------------------------------------------*/
00785 /*----------------------------------------------------------------------------*/
00786 cpl_frame * irplib_framelist_unset(irplib_framelist * self, int pos,
00787                                    cpl_propertylist ** plist)
00788 
00789 {
00790     cpl_frame * frame;
00791     int i;
00792 
00793 
00794     cpl_ensure(self  != NULL,    CPL_ERROR_NULL_INPUT, NULL);
00795     cpl_ensure(pos >= 0,         CPL_ERROR_ILLEGAL_INPUT, NULL);
00796     cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00797 
00798     /* Get the specified frame and its propertylist */
00799     frame = self->frame[pos];
00800 
00801     if (plist != NULL)
00802         *plist = self->propertylist[pos];
00803     else
00804         cpl_propertylist_delete(self->propertylist[pos]);
00805 
00806 
00807     /* Move following frames down one position */
00808     for (i = pos+1; i < self->size; i++) {
00809 
00810         self->frame[i-1] = self->frame[i];
00811 
00812         self->propertylist[i-1] = self->propertylist[i];
00813 
00814     }
00815 
00816     self->size--;
00817 
00818     irplib_framelist_set_size(self);
00819 
00820     return frame;
00821 
00822 }
00823 
00824 /*----------------------------------------------------------------------------*/
00831 /*----------------------------------------------------------------------------*/
00832 void irplib_framelist_empty(irplib_framelist * self)
00833 {
00834 
00835     if (self != NULL) {
00836 
00837         /* Deallocate all frames and their propertylists */
00838         while (self->size > 0) {
00839             self->size--;
00840             cpl_frame_delete(self->frame[self->size]);
00841             cpl_propertylist_delete(self->propertylist[self->size]);
00842 
00843         }
00844         
00845         /* Deallocate the arrays */
00846         irplib_framelist_set_size(self);
00847 
00848     }
00849 }
00850 
00851 
00852 
00853 /*----------------------------------------------------------------------------*/
00891 /*----------------------------------------------------------------------------*/
00892 cpl_error_code irplib_framelist_contains(const irplib_framelist * self,
00893                                          const char * key, cpl_type type,
00894                                          cpl_boolean is_equal, double fp_tol)
00895 {
00896 
00897     char * value_0;
00898     char * value_i;
00899     cpl_type type_0 = CPL_TYPE_INVALID;
00900     int i;
00901 
00902 
00903     cpl_ensure_code(self  != NULL, CPL_ERROR_NULL_INPUT);
00904     cpl_ensure_code(key   != NULL, CPL_ERROR_NULL_INPUT);
00905     cpl_ensure_code(fp_tol >= 0.0, CPL_ERROR_ILLEGAL_INPUT);
00906 
00907     for (i=0; i < self->size; i++) {
00908         cpl_type type_i;
00909 
00910 
00911         if (self->propertylist[i] == NULL) continue;
00912 
00913         type_i = cpl_propertylist_get_type(self->propertylist[i], key);
00914 
00915         if (type_i == CPL_TYPE_INVALID) {
00916             if (type == CPL_TYPE_INVALID)
00917                 cpl_error_set_message(cpl_func, cpl_error_get_code(), "FITS "
00918                                       "key '%s' is missing from file %s", key,
00919                                       cpl_frame_get_filename(self->frame[i]));
00920             else
00921                 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00922                                       "FITS key '%s' [%s] is missing from file "
00923                                       "%s", key, irplib_type_as_string(type),
00924                                       cpl_frame_get_filename(self->frame[i]));
00925             return cpl_error_get_code();
00926         }
00927 
00928         if (type != CPL_TYPE_INVALID && type_i != type) {
00929             return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
00930                                          "FITS key '%s' has type %s instead of "
00931                                          "%s in file %s", key,
00932                                          irplib_type_as_string(type_i),
00933                                          irplib_type_as_string(type),
00934                                          cpl_frame_get_filename(self->frame[i]));
00935         }
00936 
00937         if (!is_equal) continue;
00938 
00939         if (type_0 == CPL_TYPE_INVALID) {
00940             type_0 = type_i;
00941             continue;
00942         }
00943 
00944         if (type_i != type_0) {
00945             assert( type == CPL_TYPE_INVALID );
00946             return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
00947                                          "FITS key '%s' has different types "
00948                                          "(%s <=> %s) in files %s and %s", key,
00949                                          irplib_type_as_string(type_0),
00950                                          irplib_type_as_string(type_i),
00951                                          cpl_frame_get_filename(self->frame[0]),
00952                                          cpl_frame_get_filename(self->frame[i]));
00953         }
00954 
00955         if (irplib_property_equal(self->propertylist[0], self->propertylist[i],
00956                                   key, type_0, fp_tol, &value_0, &value_i))
00957             continue;
00958 
00959         if ((type_0 == CPL_TYPE_FLOAT || type_0 == CPL_TYPE_DOUBLE)
00960             && fp_tol > 0.0) {
00961             cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "FITS"
00962                                   " key '%s' [%s] has values that differ by "
00963                                   "more than %g (%s <=> %s) in files %s and %s",
00964                                   key, irplib_type_as_string(type_0), fp_tol,
00965                                   value_0, value_i,
00966                                   cpl_frame_get_filename(self->frame[0]),
00967                                   cpl_frame_get_filename(self->frame[i]));
00968         } else {
00969             cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
00970                                   "FITS key '%s' [%s] has different values "
00971                                   "(%s <=> %s) in files %s and %s", key,
00972                                   irplib_type_as_string(type_0),
00973                                   value_0, value_i,
00974                                   cpl_frame_get_filename(self->frame[0]),
00975                                   cpl_frame_get_filename(self->frame[i]));
00976         }
00977         cpl_free(value_0);
00978         cpl_free(value_i);
00979 
00980         return cpl_error_get_code();
00981     }        
00982 
00983     return CPL_ERROR_NONE;
00984 
00985 }
00986 
00987 
00988 /*----------------------------------------------------------------------------*/
01001 /*----------------------------------------------------------------------------*/
01002 cpl_imagelist * irplib_imagelist_load_framelist(const irplib_framelist * self,
01003                                                 cpl_type pixeltype,
01004                                                 int planenum,
01005                                                 int extnum)
01006 {
01007 
01008     cpl_imagelist * list = NULL;
01009     cpl_image     * image = NULL;
01010     int i;
01011 
01012 
01013     cpl_ensure(self != NULL,  CPL_ERROR_NULL_INPUT,          NULL);
01014     cpl_ensure(extnum >= 0,   CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01015     cpl_ensure(planenum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01016 
01017     list = cpl_imagelist_new();
01018 
01019     for (i=0; i < self->size; i++, image = NULL) {
01020         const char * filename = cpl_frame_get_filename(self->frame[i]);
01021         cpl_error_code error;
01022 
01023         if (filename == NULL) break;
01024 
01025         image = cpl_image_load(filename, pixeltype, planenum, extnum);
01026         if (image == NULL) {
01027             (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
01028                                         "Could not load FITS-image from plane "
01029                                         "%d in extension %d in file %s",
01030                                         planenum, extnum, filename);
01031             break;
01032         }
01033 
01034         error = cpl_imagelist_set(list, image, i);
01035         assert(error == CPL_ERROR_NONE);
01036     }
01037 
01038     cpl_image_delete(image);
01039     
01040     if (cpl_imagelist_get_size(list) != self->size) {
01041         cpl_imagelist_delete(list);
01042         list = NULL;
01043         assert(cpl_error_get_code() != CPL_ERROR_NONE);
01044     }
01045 
01046     return list;
01047 
01048 }
01049 
01050 
01054 /*----------------------------------------------------------------------------*/
01066 /*----------------------------------------------------------------------------*/
01067 static void irplib_framelist_set_size(irplib_framelist * self)
01068 {
01069 
01070 
01071     assert( self != NULL);
01072 
01073     if (self->size == 0) {
01074         /* The list has been emptied */
01075         cpl_free(self->frame);
01076         cpl_free(self->propertylist);
01077         self->frame = NULL;
01078         self->propertylist = NULL;
01079     } else {
01080         /* Update the size of the arrays */
01081 
01082         self->frame = cpl_realloc(self->frame, self->size * sizeof(cpl_frame*));
01083         self->propertylist =
01084             cpl_realloc(self->propertylist,
01085                         self->size * sizeof(cpl_propertylist*));
01086     }
01087 
01088 }
01089 
01090 /*----------------------------------------------------------------------------*/
01114 /*----------------------------------------------------------------------------*/
01115 static cpl_boolean irplib_property_equal(const cpl_propertylist * self,
01116                                          const cpl_propertylist * other,
01117                                          const char * key, cpl_type type,
01118                                          double fp_tol,
01119                                          char ** sstring, char ** ostring)
01120 {
01121 
01122     cpl_boolean equal;
01123 
01124 
01125     assert(self    != NULL);
01126     assert(other   != NULL);
01127     assert(key     != NULL);
01128     assert(sstring != NULL);
01129     assert(ostring != NULL);
01130 
01131     /* FIXME: disable for better performance also with debugging */
01132     assert(cpl_propertylist_get_type(other, key) == type);
01133     assert(fp_tol >= 0.0);
01134 
01135     switch (type) {
01136 
01137     case CPL_TYPE_CHAR: {
01138         const char svalue = cpl_propertylist_get_char(self, key);
01139         const char ovalue = cpl_propertylist_get_char(other, key);
01140 
01141         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01142         if (!equal) {
01143             *sstring = cpl_sprintf("%c", svalue);
01144             *ostring = cpl_sprintf("%c", ovalue);
01145         }
01146         break;
01147     }
01148 
01149     case CPL_TYPE_BOOL: {
01150         const int svalue = cpl_propertylist_get_bool(self, key);
01151         const int ovalue = cpl_propertylist_get_bool(other, key);
01152 
01153         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01154         if (!equal) {
01155             *sstring = cpl_strdup(svalue == 0 ? "F" : "T");
01156             *ostring = cpl_strdup(ovalue == 0 ? "F" : "T");
01157         }
01158         break;
01159     }
01160 
01161     case CPL_TYPE_INT: {
01162         const int svalue = cpl_propertylist_get_int(self, key);
01163         const int ovalue = cpl_propertylist_get_int(other, key);
01164 
01165         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01166         if (!equal) {
01167             *sstring = cpl_sprintf("%d", svalue);
01168             *ostring = cpl_sprintf("%d", ovalue);
01169         }
01170         break;
01171     }
01172 
01173     case CPL_TYPE_LONG: {
01174         const long svalue = cpl_propertylist_get_long(self, key);
01175         const long ovalue = cpl_propertylist_get_long(other, key);
01176 
01177         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01178         if (!equal) {
01179             *sstring = cpl_sprintf("%ld", svalue);
01180             *ostring = cpl_sprintf("%ld", ovalue);
01181         }
01182         break;
01183     }
01184 
01185     case CPL_TYPE_FLOAT: {
01186         const double svalue = (double)cpl_propertylist_get_float(self, key);
01187         const double ovalue = (double)cpl_propertylist_get_float(other, key);
01188 
01189         equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01190         if (!equal) {
01191             *sstring = cpl_sprintf("%f", svalue);
01192             *ostring = cpl_sprintf("%f", ovalue);
01193         }
01194         break;
01195     }
01196 
01197     case CPL_TYPE_DOUBLE: {
01198         const double svalue = cpl_propertylist_get_double(self, key);
01199         const double ovalue = cpl_propertylist_get_double(other, key);
01200 
01201         equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01202         if (!equal) {
01203             *sstring = cpl_sprintf("%g", svalue);
01204             *ostring = cpl_sprintf("%g", ovalue);
01205         }
01206         break;
01207     }
01208     case CPL_TYPE_STRING: {
01209         const char * svalue = cpl_propertylist_get_string(self, key);
01210         const char * ovalue = cpl_propertylist_get_string(other, key);
01211 
01212         equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
01213         if (!equal) {
01214             *sstring = cpl_strdup(svalue);
01215             *ostring = cpl_strdup(ovalue);
01216         }
01217         break;
01218     }
01219     default:
01220         /* Unknown property type */
01221         assert( 0 );
01222 
01223         equal = CPL_FALSE; /* In case of -DNDEBUG */
01224 
01225     }
01226 
01227     if (!equal) {
01228         assert( *sstring != NULL );
01229         assert( *ostring != NULL );
01230     }
01231 
01232     return equal;
01233 
01234 }
01235 
01236 
01237 
01238 /*----------------------------------------------------------------------------*/
01247 /*----------------------------------------------------------------------------*/
01248 static const char * irplib_type_as_string(cpl_type type)
01249 {
01250 
01251     const char * self;
01252 
01253 
01254     switch (type) {
01255 
01256     case CPL_TYPE_CHAR:
01257         self = "char";
01258         break;
01259 
01260     case CPL_TYPE_BOOL:
01261         self = "boolean";
01262         break;
01263 
01264     case CPL_TYPE_INT:
01265         self = "int";
01266         break;
01267 
01268     case CPL_TYPE_LONG:
01269         self = "long";
01270         break;
01271 
01272     case CPL_TYPE_FLOAT:
01273         self = "float";
01274         break;
01275 
01276     case CPL_TYPE_DOUBLE:
01277         self = "double";
01278         break;
01279 
01280     case CPL_TYPE_STRING:
01281         self = "string";
01282         break;
01283 
01284     default:
01285 
01286         cpl_ensure(0, CPL_ERROR_UNSUPPORTED_MODE, "");
01287 
01288     }
01289 
01290     return self;
01291 
01292 }

Generated on Fri Apr 18 14:11:41 2008 for UVES Pipeline Reference Manual by  doxygen 1.5.1