irplib_framelist.c

00001 /* $Id: irplib_framelist.c,v 1.23 2006/11/23 14:13:17 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: 2006/11/23 14:13:17 $
00024  * $Revision: 1.23 $
00025  * $Name:  $
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", filename));
00601         return cpl_error_get_code();
00602     }
00603 
00604     return CPL_ERROR_NONE;
00605 
00606 }
00607 
00608 
00609 /*----------------------------------------------------------------------------*/
00623 /*----------------------------------------------------------------------------*/
00624 cpl_error_code irplib_framelist_load_propertylist_all(irplib_framelist * self,
00625                                                       int ind,
00626                                                       const char * regexp,
00627                                                       cpl_boolean invert)
00628 {
00629 
00630     int nprops = 0;
00631     int nfiles = 0;
00632     int i;
00633 
00634     cpl_ensure_code(self   != NULL,    CPL_ERROR_NULL_INPUT);
00635     cpl_ensure_code(regexp != NULL,    CPL_ERROR_NULL_INPUT);
00636 
00637     for (i=0; i < self->size; i++) {
00638         if (self->propertylist[i] == NULL)
00639             cpl_ensure_code(!irplib_framelist_load_propertylist(self, i,
00640                                                                 ind,
00641                                                                 regexp,
00642                                                                 invert),
00643                                cpl_error_get_code());
00644         /* Counting just for diagnostics - this actually causes
00645            the whole list to be reiterated :-( */
00646         nprops += cpl_propertylist_get_size(self->propertylist[i]);
00647         nfiles++;
00648     }
00649 
00650     cpl_msg_info(cpl_func, "List of %d frames has %d properties", nfiles,
00651                  nprops);
00652 
00653     return CPL_ERROR_NONE;
00654 
00655 }
00656 
00657 
00658 
00659 /*----------------------------------------------------------------------------*/
00667 /*----------------------------------------------------------------------------*/
00668 cpl_error_code irplib_framelist_set_tag_all(irplib_framelist * self,
00669                                             const char * tag)
00670 {
00671 
00672     int i;
00673 
00674     cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00675     cpl_ensure_code(tag  != NULL, CPL_ERROR_NULL_INPUT);
00676 
00677     for (i=0; i < self->size; i++)
00678         cpl_ensure_code(!cpl_frame_set_tag(self->frame[i], tag),
00679                            cpl_error_get_code());
00680 
00681     return CPL_ERROR_NONE;
00682 }
00683 
00684 
00685 /*----------------------------------------------------------------------------*/
00699 /*----------------------------------------------------------------------------*/
00700 cpl_error_code irplib_framelist_set(irplib_framelist * self, cpl_frame * frame,
00701                                     int pos)
00702 {
00703 
00704     cpl_ensure_code(self  != NULL,     CPL_ERROR_NULL_INPUT);
00705     cpl_ensure_code(frame != NULL,     CPL_ERROR_NULL_INPUT);
00706     cpl_ensure_code(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT);
00707 
00708     if (pos == self->size) {
00709 
00710         self->size++;
00711 
00712         irplib_framelist_set_size(self);
00713 
00714     } else {
00715 
00716         cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00717 
00718         cpl_frame_delete(self->frame[pos]);
00719         cpl_propertylist_delete(self->propertylist[pos]);
00720     }
00721 
00722     self->frame[pos] = frame;
00723     self->propertylist[pos] = NULL;
00724 
00725     return CPL_ERROR_NONE;
00726 
00727 }
00728 
00729 /*----------------------------------------------------------------------------*/
00738 /*----------------------------------------------------------------------------*/
00739 cpl_error_code irplib_framelist_erase(irplib_framelist * self, int pos)
00740 {
00741 
00742     int i;
00743 
00744     cpl_ensure_code(self  != NULL,    CPL_ERROR_NULL_INPUT);
00745     cpl_ensure_code(pos >= 0,         CPL_ERROR_ILLEGAL_INPUT);
00746     cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00747 
00748 
00749     /* Delete the specified frame and its propertylist */
00750     cpl_frame_delete(self->frame[pos]);
00751     cpl_propertylist_delete(self->propertylist[pos]);
00752 
00753     /* Move following frames down one position */
00754     for (i = pos+1; i < self->size; i++) {
00755 
00756         self->frame[i-1] = self->frame[i];
00757 
00758         self->propertylist[i-1] = self->propertylist[i];
00759 
00760     }
00761 
00762     self->size--;
00763 
00764     irplib_framelist_set_size(self);
00765 
00766     return CPL_ERROR_NONE;
00767 
00768 }
00769 
00770 
00771 
00772 /*----------------------------------------------------------------------------*/
00788 /*----------------------------------------------------------------------------*/
00789 cpl_frame * irplib_framelist_unset(irplib_framelist * self, int pos,
00790                                    cpl_propertylist ** plist)
00791 
00792 {
00793     cpl_frame * frame;
00794     int i;
00795 
00796 
00797     cpl_ensure(self  != NULL,    CPL_ERROR_NULL_INPUT, NULL);
00798     cpl_ensure(pos >= 0,         CPL_ERROR_ILLEGAL_INPUT, NULL);
00799     cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00800 
00801     /* Get the specified frame and its propertylist */
00802     frame = self->frame[pos];
00803 
00804     if (plist != NULL)
00805         *plist = self->propertylist[pos];
00806     else
00807         cpl_propertylist_delete(self->propertylist[pos]);
00808 
00809 
00810     /* Move following frames down one position */
00811     for (i = pos+1; i < self->size; i++) {
00812 
00813         self->frame[i-1] = self->frame[i];
00814 
00815         self->propertylist[i-1] = self->propertylist[i];
00816 
00817     }
00818 
00819     self->size--;
00820 
00821     irplib_framelist_set_size(self);
00822 
00823     return frame;
00824 
00825 }
00826 
00827 /*----------------------------------------------------------------------------*/
00834 /*----------------------------------------------------------------------------*/
00835 void irplib_framelist_empty(irplib_framelist * self)
00836 {
00837 
00838     if (self != NULL) {
00839 
00840         /* Deallocate all frames and their propertylists */
00841         while (self->size > 0) {
00842             self->size--;
00843             cpl_frame_delete(self->frame[self->size]);
00844             cpl_propertylist_delete(self->propertylist[self->size]);
00845 
00846         }
00847         
00848         /* Deallocate the arrays */
00849         irplib_framelist_set_size(self);
00850 
00851     }
00852 }
00853 
00854 
00855 
00856 /*----------------------------------------------------------------------------*/
00894 /*----------------------------------------------------------------------------*/
00895 cpl_error_code irplib_framelist_contains(const irplib_framelist * self,
00896                                          const char * key, cpl_type type,
00897                                          cpl_boolean is_equal, double fp_tol)
00898 {
00899 
00900     char * value_0;
00901     char * value_i;
00902     cpl_type type_0 = CPL_TYPE_INVALID;
00903     int i;
00904 
00905 
00906     cpl_ensure_code(self  != NULL, CPL_ERROR_NULL_INPUT);
00907     cpl_ensure_code(key   != NULL, CPL_ERROR_NULL_INPUT);
00908     cpl_ensure_code(fp_tol >= 0.0, CPL_ERROR_ILLEGAL_INPUT);
00909 
00910     for (i=0; i < self->size; i++) {
00911         cpl_type type_i;
00912 
00913 
00914         if (self->propertylist[i] == NULL) continue;
00915 
00916         type_i = cpl_propertylist_get_type(self->propertylist[i], key);
00917 
00918         if (type_i == CPL_TYPE_INVALID) {
00919             if (type == CPL_TYPE_INVALID)
00920                 irplib_error_push(cpl_error_get_code(),
00921                                   ("FITS key '%s' is missing from file %s", key,
00922                                    cpl_frame_get_filename(self->frame[i])));
00923             else
00924                 irplib_error_push(cpl_error_get_code(),
00925                                   ("FITS key '%s' [%s] is missing from "
00926                                    "file %s", key, irplib_type_as_string(type),
00927                                    cpl_frame_get_filename(self->frame[i])));
00928             return cpl_error_get_code();
00929         }
00930 
00931         if (type != CPL_TYPE_INVALID && type_i != type) {
00932             irplib_error_push(CPL_ERROR_INVALID_TYPE,
00933                               ("FITS key '%s' has type %s instead of %s in "
00934                                "file %s", key, irplib_type_as_string(type_i),
00935                                irplib_type_as_string(type),
00936                                cpl_frame_get_filename(self->frame[i])));
00937             return cpl_error_get_code();
00938         }
00939 
00940         if (!is_equal) continue;
00941 
00942         if (type_0 == CPL_TYPE_INVALID) {
00943             type_0 = type_i;
00944             continue;
00945         }
00946 
00947         if (type_i != type_0) {
00948             assert( type == CPL_TYPE_INVALID );
00949             irplib_error_push(CPL_ERROR_TYPE_MISMATCH,
00950                               ("FITS key '%s' has different types "
00951                                "(%s <=> %s) in files %s and %s", key,
00952                                irplib_type_as_string(type_0),
00953                                irplib_type_as_string(type_i),
00954                                cpl_frame_get_filename(self->frame[0]),
00955                                cpl_frame_get_filename(self->frame[i])));
00956             return cpl_error_get_code();
00957         }
00958 
00959         if (irplib_property_equal(self->propertylist[0], self->propertylist[i],
00960                                   key, type_0, fp_tol, &value_0, &value_i))
00961             continue;
00962 
00963         if ((type_0 == CPL_TYPE_FLOAT || type_0 == CPL_TYPE_DOUBLE)
00964             && fp_tol > 0.0) {
00965             irplib_error_push(CPL_ERROR_INCOMPATIBLE_INPUT,
00966                               ("FITS key '%s' [%s] has values that differ by "
00967                                "more than %g (%s <=> %s) in files %s and %s",
00968                                key, irplib_type_as_string(type_0), fp_tol,
00969                                value_0, value_i,
00970                                cpl_frame_get_filename(self->frame[0]),
00971                                cpl_frame_get_filename(self->frame[i])));
00972         } else {
00973             irplib_error_push(CPL_ERROR_INCOMPATIBLE_INPUT,
00974                               ("FITS key '%s' [%s] has different "
00975                                "values (%s <=> %s) in files %s and %s", key,
00976                                irplib_type_as_string(type_0),
00977                                value_0, value_i,
00978                                cpl_frame_get_filename(self->frame[0]),
00979                                cpl_frame_get_filename(self->frame[i])));
00980         }
00981         cpl_free(value_0);
00982         cpl_free(value_i);
00983 
00984         return cpl_error_get_code();
00985     }        
00986 
00987     return CPL_ERROR_NONE;
00988 
00989 }
00990 
00991 
00992 /*----------------------------------------------------------------------------*/
01005 /*----------------------------------------------------------------------------*/
01006 cpl_imagelist * irplib_imagelist_load_framelist(const irplib_framelist * self,
01007                                                 cpl_type pixeltype,
01008                                                 int planenum,
01009                                                 int extnum)
01010 {
01011 
01012     cpl_imagelist * list = NULL;
01013     cpl_image     * image = NULL;
01014     int i;
01015 
01016 
01017     cpl_ensure(self != NULL,  CPL_ERROR_NULL_INPUT,          NULL);
01018     cpl_ensure(extnum >= 0,   CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01019     cpl_ensure(planenum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01020 
01021     list = cpl_imagelist_new();
01022 
01023     for (i=0; i < self->size; i++, image = NULL) {
01024         const char * filename = cpl_frame_get_filename(self->frame[i]);
01025         cpl_error_code error;
01026 
01027         if (filename == NULL) break;
01028 
01029         image = cpl_image_load(filename, pixeltype, planenum, extnum);
01030         if (image == NULL) {
01031             irplib_error_push(cpl_error_get_code(),
01032                               ("Could not load FITS-image from plane %d "
01033                                "in extension %d in file %s", planenum, extnum,
01034                                filename));
01035             break;
01036         }
01037 
01038         error = cpl_imagelist_set(list, image, i);
01039         assert(error == CPL_ERROR_NONE);
01040     }
01041 
01042     cpl_image_delete(image);
01043     
01044     if (cpl_imagelist_get_size(list) != self->size) {
01045         cpl_imagelist_delete(list);
01046         list = NULL;
01047         assert(cpl_error_get_code() != CPL_ERROR_NONE);
01048     }
01049 
01050     return list;
01051 
01052 }
01053 
01054 
01058 /*----------------------------------------------------------------------------*/
01070 /*----------------------------------------------------------------------------*/
01071 static void irplib_framelist_set_size(irplib_framelist * self)
01072 {
01073 
01074 
01075     assert( self != NULL);
01076 
01077     if (self->size == 0) {
01078         /* The list has been emptied */
01079         cpl_free(self->frame);
01080         cpl_free(self->propertylist);
01081         self->frame = NULL;
01082         self->propertylist = NULL;
01083     } else {
01084         /* Update the size of the arrays */
01085 
01086         self->frame = cpl_realloc(self->frame, self->size * sizeof(cpl_frame*));
01087         self->propertylist =
01088             cpl_realloc(self->propertylist,
01089                         self->size * sizeof(cpl_propertylist*));
01090     }
01091 
01092 }
01093 
01094 /*----------------------------------------------------------------------------*/
01118 /*----------------------------------------------------------------------------*/
01119 static cpl_boolean irplib_property_equal(const cpl_propertylist * self,
01120                                          const cpl_propertylist * other,
01121                                          const char * key, cpl_type type,
01122                                          double fp_tol,
01123                                          char ** sstring, char ** ostring)
01124 {
01125 
01126     cpl_boolean equal;
01127 
01128 
01129     assert(self    != NULL);
01130     assert(other   != NULL);
01131     assert(key     != NULL);
01132     assert(sstring != NULL);
01133     assert(ostring != NULL);
01134 
01135     /* FIXME: disable for better performance also with debugging */
01136     assert(cpl_propertylist_get_type(other, key) == type);
01137     assert(fp_tol >= 0.0);
01138 
01139     switch (type) {
01140 
01141     case CPL_TYPE_CHAR: {
01142         const char svalue = cpl_propertylist_get_char(self, key);
01143         const char ovalue = cpl_propertylist_get_char(other, key);
01144 
01145         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01146         if (!equal) {
01147             *sstring = irplib_sprintf("%c", svalue);
01148             *ostring = irplib_sprintf("%c", ovalue);
01149         }
01150         break;
01151     }
01152 
01153     case CPL_TYPE_BOOL: {
01154         const int svalue = cpl_propertylist_get_bool(self, key);
01155         const int ovalue = cpl_propertylist_get_bool(other, key);
01156 
01157         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01158         if (!equal) {
01159             *sstring = cpl_strdup(svalue == 0 ? "F" : "T");
01160             *ostring = cpl_strdup(ovalue == 0 ? "F" : "T");
01161         }
01162         break;
01163     }
01164 
01165     case CPL_TYPE_INT: {
01166         const int svalue = cpl_propertylist_get_int(self, key);
01167         const int ovalue = cpl_propertylist_get_int(other, key);
01168 
01169         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01170         if (!equal) {
01171             *sstring = irplib_sprintf("%d", svalue);
01172             *ostring = irplib_sprintf("%d", ovalue);
01173         }
01174         break;
01175     }
01176 
01177     case CPL_TYPE_LONG: {
01178         const long svalue = cpl_propertylist_get_long(self, key);
01179         const long ovalue = cpl_propertylist_get_long(other, key);
01180 
01181         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01182         if (!equal) {
01183             *sstring = irplib_sprintf("%ld", svalue);
01184             *ostring = irplib_sprintf("%ld", ovalue);
01185         }
01186         break;
01187     }
01188 
01189     case CPL_TYPE_FLOAT: {
01190         const double svalue = (double)cpl_propertylist_get_float(self, key);
01191         const double ovalue = (double)cpl_propertylist_get_float(other, key);
01192 
01193         equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01194         if (!equal) {
01195             *sstring = irplib_sprintf("%f", svalue);
01196             *ostring = irplib_sprintf("%f", ovalue);
01197         }
01198         break;
01199     }
01200 
01201     case CPL_TYPE_DOUBLE: {
01202         const double svalue = cpl_propertylist_get_double(self, key);
01203         const double ovalue = cpl_propertylist_get_double(other, key);
01204 
01205         equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01206         if (!equal) {
01207             *sstring = irplib_sprintf("%g", svalue);
01208             *ostring = irplib_sprintf("%g", ovalue);
01209         }
01210         break;
01211     }
01212     case CPL_TYPE_STRING: {
01213         const char * svalue = cpl_propertylist_get_string(self, key);
01214         const char * ovalue = cpl_propertylist_get_string(other, key);
01215 
01216         equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
01217         if (!equal) {
01218             *sstring = cpl_strdup(svalue);
01219             *ostring = cpl_strdup(ovalue);
01220         }
01221         break;
01222     }
01223     default:
01224         /* Unknown property type */
01225         assert( 0 );
01226 
01227         equal = CPL_FALSE; /* In case of -DNDEBUG */
01228 
01229     }
01230 
01231     if (!equal) {
01232         assert( *sstring != NULL );
01233         assert( *ostring != NULL );
01234     }
01235 
01236     return equal;
01237 
01238 }
01239 
01240 
01241 
01242 /*----------------------------------------------------------------------------*/
01251 /*----------------------------------------------------------------------------*/
01252 static const char * irplib_type_as_string(cpl_type type)
01253 {
01254 
01255     const char * self;
01256 
01257 
01258     switch (type) {
01259 
01260     case CPL_TYPE_CHAR:
01261         self = "char";
01262         break;
01263 
01264     case CPL_TYPE_BOOL:
01265         self = "boolean";
01266         break;
01267 
01268     case CPL_TYPE_INT:
01269         self = "int";
01270         break;
01271 
01272     case CPL_TYPE_LONG:
01273         self = "long";
01274         break;
01275 
01276     case CPL_TYPE_FLOAT:
01277         self = "float";
01278         break;
01279 
01280     case CPL_TYPE_DOUBLE:
01281         self = "double";
01282         break;
01283 
01284     case CPL_TYPE_STRING:
01285         self = "string";
01286         break;
01287 
01288     default:
01289 
01290         cpl_ensure(0, CPL_ERROR_UNSUPPORTED_MODE, "");
01291 
01292     }
01293 
01294     return self;
01295 
01296 }

Generated on Wed Jan 17 08:33:41 2007 for SINFONI Pipeline Reference Manual by  doxygen 1.4.4