irplib_framelist.c

00001 /* $Id: irplib_framelist.c,v 1.24 2007/03/26 09:48:58 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/03/26 09:48:58 $
00024  * $Revision: 1.24 $
00025  * $Name: uves-3_3_1 $
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 /* Needed to get irplib_sprintf() */
00048 #include "irplib_utils.h"
00049 #include "irplib_error.h"
00050 #include "irplib_framelist.h"
00051 
00052 
00053 /*-----------------------------------------------------------------------------
00054                                  New types
00055  -----------------------------------------------------------------------------*/
00056 
00057 /* @cond */
00058 struct _irplib_framelist_ {
00059     int size;
00060     cpl_frame        ** frame;
00061     cpl_propertylist ** propertylist;
00062 
00063 };
00064 /* @endcond */
00065 
00066 /*-----------------------------------------------------------------------------
00067                                  Private funcions
00068  -----------------------------------------------------------------------------*/
00069 
00070 static void irplib_framelist_set_size(irplib_framelist *)
00071 #if defined __GNUC__ &&  __GNUC__ >= 4
00072     __attribute__((nonnull))
00073 #endif
00074 ;
00075 
00076 static cpl_boolean irplib_property_equal(const cpl_propertylist *,
00077                                          const cpl_propertylist *,
00078                                          const char *, cpl_type, double,
00079                                          char **, char **)
00080 #if defined __GNUC__ &&  __GNUC__ >= 4
00081     __attribute__((nonnull))
00082 #endif
00083 ;
00084 
00085 static const char * irplib_type_as_string(cpl_type);
00086 
00087 /*----------------------------------------------------------------------------*/
00166 /*----------------------------------------------------------------------------*/
00167 
00170 /*-----------------------------------------------------------------------------
00171                             Function codes
00172  -----------------------------------------------------------------------------*/
00173 
00174 /*----------------------------------------------------------------------------*/
00182 /*----------------------------------------------------------------------------*/
00183 irplib_framelist * irplib_framelist_new(void)
00184 {
00185 
00186     return (irplib_framelist *) cpl_calloc(1, sizeof(irplib_framelist));
00187 
00188 }
00189 
00190 /*----------------------------------------------------------------------------*/
00195 /*----------------------------------------------------------------------------*/
00196 void irplib_framelist_delete(irplib_framelist * self)
00197 {
00198 
00199     irplib_framelist_empty(self);
00200     cpl_free(self);
00201 }
00202 
00203 
00204 /*----------------------------------------------------------------------------*/
00213 /*----------------------------------------------------------------------------*/
00214 irplib_framelist * irplib_framelist_cast(const cpl_frameset * frameset)
00215 {
00216 
00217     irplib_framelist * self;
00218     const cpl_frame * frame;
00219     int i;
00220 
00221 
00222     cpl_ensure(frameset != NULL, CPL_ERROR_NULL_INPUT, NULL);
00223 
00224     /* The function cannot fail now */
00225     self = irplib_framelist_new();
00226 
00227     for (i = 0, frame = cpl_frameset_get_first(frameset);
00228          frame != NULL;
00229          i++, frame = cpl_frameset_get_next(frameset)) {
00230 
00231         cpl_frame * copy = cpl_frame_duplicate(frame);
00232 
00233         const cpl_error_code error = irplib_framelist_set(self, copy, i);
00234 
00235         assert(error == CPL_ERROR_NONE);
00236 
00237     }
00238 
00239     assert(self->size == cpl_frameset_get_size(frameset));
00240 
00241     return self;
00242 
00243 }
00244 
00245 
00246 /*----------------------------------------------------------------------------*/
00255 /*----------------------------------------------------------------------------*/
00256 cpl_frameset * irplib_frameset_cast(const irplib_framelist * self)
00257 {
00258 
00259     cpl_frameset * new;
00260     int i;
00261 
00262     cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00263 
00264     /* The function cannot fail now */
00265     new = cpl_frameset_new();
00266 
00267     for (i = 0; i < self->size; i++) {
00268         cpl_frame * frame = cpl_frame_duplicate(self->frame[i]);
00269         const cpl_error_code error = cpl_frameset_insert(new, frame);
00270 
00271         assert(error == CPL_ERROR_NONE);
00272 
00273     }
00274 
00275     assert(self->size == cpl_frameset_get_size(new));
00276 
00277     return new;
00278 
00279 }
00280 
00281 
00282 /*----------------------------------------------------------------------------*/
00294 /*----------------------------------------------------------------------------*/
00295 irplib_framelist * irplib_framelist_extract(const irplib_framelist * self,
00296                                             const char * tag)
00297 {
00298 
00299     irplib_framelist * new;
00300     int i, newsize;
00301 
00302 
00303     cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00304     cpl_ensure(tag  != NULL, CPL_ERROR_NULL_INPUT, NULL);
00305 
00306     new = irplib_framelist_new();
00307     newsize = 0;
00308 
00309     for (i = 0; i < self->size; i++) {
00310         const cpl_frame * frame = self->frame[i];
00311         const char * ftag = cpl_frame_get_tag(frame);
00312         cpl_frame * copy;
00313         cpl_error_code error;
00314 
00315         if (ftag == NULL) {
00316             /* The frame is ill-formed */
00317             irplib_framelist_delete(new);
00318             cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00319         }
00320 
00321         if (strcmp(tag, ftag)) continue;
00322 
00323         copy = cpl_frame_duplicate(frame);
00324 
00325         error = irplib_framelist_set(new, copy, newsize);
00326         assert(error == CPL_ERROR_NONE);
00327 
00328         if (self->propertylist[i] != NULL) new->propertylist[newsize]
00329             = cpl_propertylist_duplicate(self->propertylist[i]);
00330 
00331         newsize++;
00332     }
00333 
00334     assert( newsize == new->size );
00335 
00336     if (newsize == 0) {
00337         irplib_error_push(CPL_ERROR_DATA_NOT_FOUND,
00338                           ("The list of %d frame(s) has no frames with "
00339                            "tag: %s", self->size, tag));
00340         irplib_framelist_delete(new);
00341         new = NULL;
00342     }
00343 
00344     return new;
00345 
00346 }
00347 
00348 /*----------------------------------------------------------------------------*/
00358 /*----------------------------------------------------------------------------*/
00359 irplib_framelist * irplib_framelist_extract_regexp(const irplib_framelist* self,
00360                                                    const char * regexp,
00361                                                    cpl_boolean invert)
00362 {
00363 
00364     irplib_framelist * new;
00365     int error;
00366     int i, newsize;
00367     const int xor = invert == CPL_FALSE ? 0 : 1;
00368     regex_t re;
00369 
00370 
00371     cpl_ensure(self   != NULL, CPL_ERROR_NULL_INPUT, NULL);
00372     cpl_ensure(regexp != NULL, CPL_ERROR_NULL_INPUT, NULL);
00373 
00374     error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
00375     cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, NULL);
00376 
00377     new = irplib_framelist_new();
00378     newsize = 0;
00379 
00380     for (i = 0; i < self->size; i++) {
00381         const cpl_frame * frame = self->frame[i];
00382         const char * tag = cpl_frame_get_tag(frame);
00383         cpl_frame * copy;
00384 
00385         if (tag == NULL) {
00386             /* The frame is ill-formed */
00387             irplib_framelist_delete(new);
00388             regfree(&re);
00389             cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00390         }
00391 
00392         if ((regexec(&re, tag, (size_t)0, NULL, 0) == REG_NOMATCH ? 1 : 0)
00393             ^ xor) continue;
00394 
00395         copy = cpl_frame_duplicate(frame);
00396 
00397         error = (int)irplib_framelist_set(new, copy, newsize);
00398         assert(error == CPL_ERROR_NONE);
00399 
00400         if (self->propertylist[i] != NULL) new->propertylist[newsize]
00401             = cpl_propertylist_duplicate(self->propertylist[i]);
00402 
00403         newsize++;
00404 
00405     }
00406 
00407     regfree(&re);
00408 
00409     assert( newsize == new->size );
00410 
00411     if (newsize == 0) {
00412         irplib_error_push(CPL_ERROR_DATA_NOT_FOUND,
00413                           ("The list of %d frame(s) has no frames that "
00414                            "match: %s", self->size, regexp));
00415         irplib_framelist_delete(new);
00416         new = NULL;
00417     }
00418 
00419     return new;
00420 }
00421 
00422 
00423 /*----------------------------------------------------------------------------*/
00430 /*----------------------------------------------------------------------------*/
00431 int irplib_framelist_get_size(const irplib_framelist * self)
00432 {
00433 
00434     cpl_ensure(self != NULL,  CPL_ERROR_NULL_INPUT, -1);
00435 
00436     return self->size;
00437 
00438 }
00439 
00440 /*----------------------------------------------------------------------------*/
00448 /*----------------------------------------------------------------------------*/
00449 cpl_frame * irplib_framelist_get(irplib_framelist * self, int pos)
00450 {
00451     return (cpl_frame *)irplib_framelist_get_const(self, pos);
00452 
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     return (cpl_propertylist *)irplib_framelist_get_propertylist_const(self,
00526                                                                        pos);
00527 
00528 }
00529 
00530 
00531 /*----------------------------------------------------------------------------*/
00542 /*----------------------------------------------------------------------------*/
00543 const cpl_propertylist * irplib_framelist_get_propertylist_const(
00544                                                   const irplib_framelist * self,
00545                                                   int pos)
00546 {
00547     cpl_ensure(self != NULL,      CPL_ERROR_NULL_INPUT,          NULL);
00548     cpl_ensure(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT,       NULL);
00549     cpl_ensure(pos <= self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00550 
00551     cpl_ensure(self->propertylist[pos] != NULL,
00552                   CPL_ERROR_DATA_NOT_FOUND, NULL);
00553 
00554     return self->propertylist[pos];
00555 
00556 }
00557 
00558 
00559 /*----------------------------------------------------------------------------*/
00573 /*----------------------------------------------------------------------------*/
00574 cpl_error_code irplib_framelist_load_propertylist(irplib_framelist * self,
00575                                                   int pos, int ind,
00576                                                   const char * regexp,
00577                                                   cpl_boolean invert)
00578 {
00579 
00580     const char * filename;
00581 
00582 
00583     cpl_ensure_code(self   != NULL,    CPL_ERROR_NULL_INPUT);
00584     cpl_ensure_code(regexp != NULL,    CPL_ERROR_NULL_INPUT);
00585     cpl_ensure_code(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT);
00586     cpl_ensure_code(pos <= self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00587 
00588     filename = cpl_frame_get_filename(self->frame[pos]);
00589 
00590     cpl_ensure_code(filename != NULL, cpl_error_get_code());
00591 
00592     cpl_propertylist_delete(self->propertylist[pos]);
00593 
00594     self->propertylist[pos] = cpl_propertylist_load_regexp(filename, ind,
00595                                                            regexp,
00596                                                            invert ? 1 : 0);
00597 
00598     if (self->propertylist[pos] == NULL) {
00599         irplib_error_push(cpl_error_get_code(),
00600                           ("Could not load FITS header from '%s' using regexp "
00601                            "'%s'", filename, regexp));
00602         return cpl_error_get_code();
00603     }
00604 
00605     return CPL_ERROR_NONE;
00606 
00607 }
00608 
00609 
00610 /*----------------------------------------------------------------------------*/
00624 /*----------------------------------------------------------------------------*/
00625 cpl_error_code irplib_framelist_load_propertylist_all(irplib_framelist * self,
00626                                                       int ind,
00627                                                       const char * regexp,
00628                                                       cpl_boolean invert)
00629 {
00630 
00631     int nprops = 0;
00632     int nfiles = 0;
00633     int i;
00634 
00635     cpl_ensure_code(self   != NULL,    CPL_ERROR_NULL_INPUT);
00636     cpl_ensure_code(regexp != NULL,    CPL_ERROR_NULL_INPUT);
00637 
00638     for (i=0; i < self->size; i++) {
00639         if (self->propertylist[i] == NULL)
00640             cpl_ensure_code(!irplib_framelist_load_propertylist(self, i,
00641                                                                 ind,
00642                                                                 regexp,
00643                                                                 invert),
00644                                cpl_error_get_code());
00645         /* Counting just for diagnostics - this actually causes
00646            the whole list to be reiterated :-( */
00647         nprops += cpl_propertylist_get_size(self->propertylist[i]);
00648         nfiles++;
00649     }
00650 
00651     cpl_msg_info(cpl_func, "List of %d frames has %d properties", nfiles,
00652                  nprops);
00653 
00654     return CPL_ERROR_NONE;
00655 
00656 }
00657 
00658 
00659 
00660 /*----------------------------------------------------------------------------*/
00668 /*----------------------------------------------------------------------------*/
00669 cpl_error_code irplib_framelist_set_tag_all(irplib_framelist * self,
00670                                             const char * tag)
00671 {
00672 
00673     int i;
00674 
00675     cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00676     cpl_ensure_code(tag  != NULL, CPL_ERROR_NULL_INPUT);
00677 
00678     for (i=0; i < self->size; i++)
00679         cpl_ensure_code(!cpl_frame_set_tag(self->frame[i], tag),
00680                            cpl_error_get_code());
00681 
00682     return CPL_ERROR_NONE;
00683 }
00684 
00685 
00686 /*----------------------------------------------------------------------------*/
00700 /*----------------------------------------------------------------------------*/
00701 cpl_error_code irplib_framelist_set(irplib_framelist * self, cpl_frame * frame,
00702                                     int pos)
00703 {
00704 
00705     cpl_ensure_code(self  != NULL,     CPL_ERROR_NULL_INPUT);
00706     cpl_ensure_code(frame != NULL,     CPL_ERROR_NULL_INPUT);
00707     cpl_ensure_code(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT);
00708 
00709     if (pos == self->size) {
00710 
00711         self->size++;
00712 
00713         irplib_framelist_set_size(self);
00714 
00715     } else {
00716 
00717         cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00718 
00719         cpl_frame_delete(self->frame[pos]);
00720         cpl_propertylist_delete(self->propertylist[pos]);
00721     }
00722 
00723     self->frame[pos] = frame;
00724     self->propertylist[pos] = NULL;
00725 
00726     return CPL_ERROR_NONE;
00727 
00728 }
00729 
00730 /*----------------------------------------------------------------------------*/
00739 /*----------------------------------------------------------------------------*/
00740 cpl_error_code irplib_framelist_erase(irplib_framelist * self, int pos)
00741 {
00742 
00743     int i;
00744 
00745     cpl_ensure_code(self  != NULL,    CPL_ERROR_NULL_INPUT);
00746     cpl_ensure_code(pos >= 0,         CPL_ERROR_ILLEGAL_INPUT);
00747     cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00748 
00749 
00750     /* Delete the specified frame and its propertylist */
00751     cpl_frame_delete(self->frame[pos]);
00752     cpl_propertylist_delete(self->propertylist[pos]);
00753 
00754     /* Move following frames down one position */
00755     for (i = pos+1; i < self->size; i++) {
00756 
00757         self->frame[i-1] = self->frame[i];
00758 
00759         self->propertylist[i-1] = self->propertylist[i];
00760 
00761     }
00762 
00763     self->size--;
00764 
00765     irplib_framelist_set_size(self);
00766 
00767     return CPL_ERROR_NONE;
00768 
00769 }
00770 
00771 
00772 
00773 /*----------------------------------------------------------------------------*/
00789 /*----------------------------------------------------------------------------*/
00790 cpl_frame * irplib_framelist_unset(irplib_framelist * self, int pos,
00791                                    cpl_propertylist ** plist)
00792 
00793 {
00794     cpl_frame * frame;
00795     int i;
00796 
00797 
00798     cpl_ensure(self  != NULL,    CPL_ERROR_NULL_INPUT, NULL);
00799     cpl_ensure(pos >= 0,         CPL_ERROR_ILLEGAL_INPUT, NULL);
00800     cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00801 
00802     /* Get the specified frame and its propertylist */
00803     frame = self->frame[pos];
00804 
00805     if (plist != NULL)
00806         *plist = self->propertylist[pos];
00807     else
00808         cpl_propertylist_delete(self->propertylist[pos]);
00809 
00810 
00811     /* Move following frames down one position */
00812     for (i = pos+1; i < self->size; i++) {
00813 
00814         self->frame[i-1] = self->frame[i];
00815 
00816         self->propertylist[i-1] = self->propertylist[i];
00817 
00818     }
00819 
00820     self->size--;
00821 
00822     irplib_framelist_set_size(self);
00823 
00824     return frame;
00825 
00826 }
00827 
00828 /*----------------------------------------------------------------------------*/
00835 /*----------------------------------------------------------------------------*/
00836 void irplib_framelist_empty(irplib_framelist * self)
00837 {
00838 
00839     if (self != NULL) {
00840 
00841         /* Deallocate all frames and their propertylists */
00842         while (self->size > 0) {
00843             self->size--;
00844             cpl_frame_delete(self->frame[self->size]);
00845             cpl_propertylist_delete(self->propertylist[self->size]);
00846 
00847         }
00848         
00849         /* Deallocate the arrays */
00850         irplib_framelist_set_size(self);
00851 
00852     }
00853 }
00854 
00855 
00856 
00857 /*----------------------------------------------------------------------------*/
00895 /*----------------------------------------------------------------------------*/
00896 cpl_error_code irplib_framelist_contains(const irplib_framelist * self,
00897                                          const char * key, cpl_type type,
00898                                          cpl_boolean is_equal, double fp_tol)
00899 {
00900 
00901     char * value_0;
00902     char * value_i;
00903     cpl_type type_0 = CPL_TYPE_INVALID;
00904     int i;
00905 
00906 
00907     cpl_ensure_code(self  != NULL, CPL_ERROR_NULL_INPUT);
00908     cpl_ensure_code(key   != NULL, CPL_ERROR_NULL_INPUT);
00909     cpl_ensure_code(fp_tol >= 0.0, CPL_ERROR_ILLEGAL_INPUT);
00910 
00911     for (i=0; i < self->size; i++) {
00912         cpl_type type_i;
00913 
00914 
00915         if (self->propertylist[i] == NULL) continue;
00916 
00917         type_i = cpl_propertylist_get_type(self->propertylist[i], key);
00918 
00919         if (type_i == CPL_TYPE_INVALID) {
00920             if (type == CPL_TYPE_INVALID)
00921                 irplib_error_push(cpl_error_get_code(),
00922                                   ("FITS key '%s' is missing from file %s", key,
00923                                    cpl_frame_get_filename(self->frame[i])));
00924             else
00925                 irplib_error_push(cpl_error_get_code(),
00926                                   ("FITS key '%s' [%s] is missing from "
00927                                    "file %s", key, irplib_type_as_string(type),
00928                                    cpl_frame_get_filename(self->frame[i])));
00929             return cpl_error_get_code();
00930         }
00931 
00932         if (type != CPL_TYPE_INVALID && type_i != type) {
00933             irplib_error_push(CPL_ERROR_INVALID_TYPE,
00934                               ("FITS key '%s' has type %s instead of %s in "
00935                                "file %s", key, irplib_type_as_string(type_i),
00936                                irplib_type_as_string(type),
00937                                cpl_frame_get_filename(self->frame[i])));
00938             return cpl_error_get_code();
00939         }
00940 
00941         if (!is_equal) continue;
00942 
00943         if (type_0 == CPL_TYPE_INVALID) {
00944             type_0 = type_i;
00945             continue;
00946         }
00947 
00948         if (type_i != type_0) {
00949             assert( type == CPL_TYPE_INVALID );
00950             irplib_error_push(CPL_ERROR_TYPE_MISMATCH,
00951                               ("FITS key '%s' has different types "
00952                                "(%s <=> %s) in files %s and %s", key,
00953                                irplib_type_as_string(type_0),
00954                                irplib_type_as_string(type_i),
00955                                cpl_frame_get_filename(self->frame[0]),
00956                                cpl_frame_get_filename(self->frame[i])));
00957             return cpl_error_get_code();
00958         }
00959 
00960         if (irplib_property_equal(self->propertylist[0], self->propertylist[i],
00961                                   key, type_0, fp_tol, &value_0, &value_i))
00962             continue;
00963 
00964         if ((type_0 == CPL_TYPE_FLOAT || type_0 == CPL_TYPE_DOUBLE)
00965             && fp_tol > 0.0) {
00966             irplib_error_push(CPL_ERROR_INCOMPATIBLE_INPUT,
00967                               ("FITS key '%s' [%s] has values that differ by "
00968                                "more than %g (%s <=> %s) in files %s and %s",
00969                                key, irplib_type_as_string(type_0), fp_tol,
00970                                value_0, value_i,
00971                                cpl_frame_get_filename(self->frame[0]),
00972                                cpl_frame_get_filename(self->frame[i])));
00973         } else {
00974             irplib_error_push(CPL_ERROR_INCOMPATIBLE_INPUT,
00975                               ("FITS key '%s' [%s] has different "
00976                                "values (%s <=> %s) in files %s and %s", key,
00977                                irplib_type_as_string(type_0),
00978                                value_0, value_i,
00979                                cpl_frame_get_filename(self->frame[0]),
00980                                cpl_frame_get_filename(self->frame[i])));
00981         }
00982         cpl_free(value_0);
00983         cpl_free(value_i);
00984 
00985         return cpl_error_get_code();
00986     }        
00987 
00988     return CPL_ERROR_NONE;
00989 
00990 }
00991 
00992 
00993 /*----------------------------------------------------------------------------*/
01006 /*----------------------------------------------------------------------------*/
01007 cpl_imagelist * irplib_imagelist_load_framelist(const irplib_framelist * self,
01008                                                 cpl_type pixeltype,
01009                                                 int planenum,
01010                                                 int extnum)
01011 {
01012 
01013     cpl_imagelist * list = NULL;
01014     cpl_image     * image = NULL;
01015     int i;
01016 
01017 
01018     cpl_ensure(self != NULL,  CPL_ERROR_NULL_INPUT,          NULL);
01019     cpl_ensure(extnum >= 0,   CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01020     cpl_ensure(planenum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01021 
01022     list = cpl_imagelist_new();
01023 
01024     for (i=0; i < self->size; i++, image = NULL) {
01025         const char * filename = cpl_frame_get_filename(self->frame[i]);
01026         cpl_error_code error;
01027 
01028         if (filename == NULL) break;
01029 
01030         image = cpl_image_load(filename, pixeltype, planenum, extnum);
01031         if (image == NULL) {
01032             irplib_error_push(cpl_error_get_code(),
01033                               ("Could not load FITS-image from plane %d "
01034                                "in extension %d in file %s", planenum, extnum,
01035                                filename));
01036             break;
01037         }
01038 
01039         error = cpl_imagelist_set(list, image, i);
01040         assert(error == CPL_ERROR_NONE);
01041     }
01042 
01043     cpl_image_delete(image);
01044     
01045     if (cpl_imagelist_get_size(list) != self->size) {
01046         cpl_imagelist_delete(list);
01047         list = NULL;
01048         assert(cpl_error_get_code() != CPL_ERROR_NONE);
01049     }
01050 
01051     return list;
01052 
01053 }
01054 
01055 
01059 /*----------------------------------------------------------------------------*/
01071 /*----------------------------------------------------------------------------*/
01072 static void irplib_framelist_set_size(irplib_framelist * self)
01073 {
01074 
01075 
01076     assert( self != NULL);
01077 
01078     if (self->size == 0) {
01079         /* The list has been emptied */
01080         cpl_free(self->frame);
01081         cpl_free(self->propertylist);
01082         self->frame = NULL;
01083         self->propertylist = NULL;
01084     } else {
01085         /* Update the size of the arrays */
01086 
01087         self->frame = cpl_realloc(self->frame, self->size * sizeof(cpl_frame*));
01088         self->propertylist =
01089             cpl_realloc(self->propertylist,
01090                         self->size * sizeof(cpl_propertylist*));
01091     }
01092 
01093 }
01094 
01095 /*----------------------------------------------------------------------------*/
01119 /*----------------------------------------------------------------------------*/
01120 static cpl_boolean irplib_property_equal(const cpl_propertylist * self,
01121                                          const cpl_propertylist * other,
01122                                          const char * key, cpl_type type,
01123                                          double fp_tol,
01124                                          char ** sstring, char ** ostring)
01125 {
01126 
01127     cpl_boolean equal;
01128 
01129 
01130     assert(self    != NULL);
01131     assert(other   != NULL);
01132     assert(key     != NULL);
01133     assert(sstring != NULL);
01134     assert(ostring != NULL);
01135 
01136     /* FIXME: disable for better performance also with debugging */
01137     assert(cpl_propertylist_get_type(other, key) == type);
01138     assert(fp_tol >= 0.0);
01139 
01140     switch (type) {
01141 
01142     case CPL_TYPE_CHAR: {
01143         const char svalue = cpl_propertylist_get_char(self, key);
01144         const char ovalue = cpl_propertylist_get_char(other, key);
01145 
01146         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01147         if (!equal) {
01148             *sstring = irplib_sprintf("%c", svalue);
01149             *ostring = irplib_sprintf("%c", ovalue);
01150         }
01151         break;
01152     }
01153 
01154     case CPL_TYPE_BOOL: {
01155         const int svalue = cpl_propertylist_get_bool(self, key);
01156         const int ovalue = cpl_propertylist_get_bool(other, key);
01157 
01158         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01159         if (!equal) {
01160             *sstring = cpl_strdup(svalue == 0 ? "F" : "T");
01161             *ostring = cpl_strdup(ovalue == 0 ? "F" : "T");
01162         }
01163         break;
01164     }
01165 
01166     case CPL_TYPE_INT: {
01167         const int svalue = cpl_propertylist_get_int(self, key);
01168         const int ovalue = cpl_propertylist_get_int(other, key);
01169 
01170         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01171         if (!equal) {
01172             *sstring = irplib_sprintf("%d", svalue);
01173             *ostring = irplib_sprintf("%d", ovalue);
01174         }
01175         break;
01176     }
01177 
01178     case CPL_TYPE_LONG: {
01179         const long svalue = cpl_propertylist_get_long(self, key);
01180         const long ovalue = cpl_propertylist_get_long(other, key);
01181 
01182         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01183         if (!equal) {
01184             *sstring = irplib_sprintf("%ld", svalue);
01185             *ostring = irplib_sprintf("%ld", ovalue);
01186         }
01187         break;
01188     }
01189 
01190     case CPL_TYPE_FLOAT: {
01191         const double svalue = (double)cpl_propertylist_get_float(self, key);
01192         const double ovalue = (double)cpl_propertylist_get_float(other, key);
01193 
01194         equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01195         if (!equal) {
01196             *sstring = irplib_sprintf("%f", svalue);
01197             *ostring = irplib_sprintf("%f", ovalue);
01198         }
01199         break;
01200     }
01201 
01202     case CPL_TYPE_DOUBLE: {
01203         const double svalue = cpl_propertylist_get_double(self, key);
01204         const double ovalue = cpl_propertylist_get_double(other, key);
01205 
01206         equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01207         if (!equal) {
01208             *sstring = irplib_sprintf("%g", svalue);
01209             *ostring = irplib_sprintf("%g", ovalue);
01210         }
01211         break;
01212     }
01213     case CPL_TYPE_STRING: {
01214         const char * svalue = cpl_propertylist_get_string(self, key);
01215         const char * ovalue = cpl_propertylist_get_string(other, key);
01216 
01217         equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
01218         if (!equal) {
01219             *sstring = cpl_strdup(svalue);
01220             *ostring = cpl_strdup(ovalue);
01221         }
01222         break;
01223     }
01224     default:
01225         /* Unknown property type */
01226         assert( 0 );
01227 
01228         equal = CPL_FALSE; /* In case of -DNDEBUG */
01229 
01230     }
01231 
01232     if (!equal) {
01233         assert( *sstring != NULL );
01234         assert( *ostring != NULL );
01235     }
01236 
01237     return equal;
01238 
01239 }
01240 
01241 
01242 
01243 /*----------------------------------------------------------------------------*/
01252 /*----------------------------------------------------------------------------*/
01253 static const char * irplib_type_as_string(cpl_type type)
01254 {
01255 
01256     const char * self;
01257 
01258 
01259     switch (type) {
01260 
01261     case CPL_TYPE_CHAR:
01262         self = "char";
01263         break;
01264 
01265     case CPL_TYPE_BOOL:
01266         self = "boolean";
01267         break;
01268 
01269     case CPL_TYPE_INT:
01270         self = "int";
01271         break;
01272 
01273     case CPL_TYPE_LONG:
01274         self = "long";
01275         break;
01276 
01277     case CPL_TYPE_FLOAT:
01278         self = "float";
01279         break;
01280 
01281     case CPL_TYPE_DOUBLE:
01282         self = "double";
01283         break;
01284 
01285     case CPL_TYPE_STRING:
01286         self = "string";
01287         break;
01288 
01289     default:
01290 
01291         cpl_ensure(0, CPL_ERROR_UNSUPPORTED_MODE, "");
01292 
01293     }
01294 
01295     return self;
01296 
01297 }

Generated on Tue Jun 19 14:39:14 2007 for UVES Pipeline Reference Manual by  doxygen 1.4.6