irplib_framelist.c

00001 /* $Id: irplib_framelist.c,v 1.28 2009/05/12 09:57:57 llundin Exp $
00002  *
00003  * This file is part of the irplib package 
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2009/05/12 09:57:57 $
00024  * $Revision: 1.28 $
00025  * $Name: naco-4_3_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 /*----------------------------------------------------------------------------*/
00161 /*----------------------------------------------------------------------------*/
00162 
00165 /*-----------------------------------------------------------------------------
00166                             Function codes
00167  -----------------------------------------------------------------------------*/
00168 
00169 /*----------------------------------------------------------------------------*/
00177 /*----------------------------------------------------------------------------*/
00178 irplib_framelist * irplib_framelist_new(void)
00179 {
00180 
00181     return (irplib_framelist *) cpl_calloc(1, sizeof(irplib_framelist));
00182 
00183 }
00184 
00185 /*----------------------------------------------------------------------------*/
00190 /*----------------------------------------------------------------------------*/
00191 void irplib_framelist_delete(irplib_framelist * self)
00192 {
00193 
00194     irplib_framelist_empty(self);
00195     cpl_free(self);
00196 }
00197 
00198 
00199 /*----------------------------------------------------------------------------*/
00208 /*----------------------------------------------------------------------------*/
00209 irplib_framelist * irplib_framelist_cast(const cpl_frameset * frameset)
00210 {
00211 
00212     irplib_framelist * self;
00213     const cpl_frame * frame;
00214     int i;
00215 
00216 
00217     cpl_ensure(frameset != NULL, CPL_ERROR_NULL_INPUT, NULL);
00218 
00219     /* The function cannot fail now */
00220     self = irplib_framelist_new();
00221 
00222     for (i = 0, frame = cpl_frameset_get_first_const(frameset);
00223          frame != NULL;
00224          i++, frame = cpl_frameset_get_next_const(frameset)) {
00225 
00226         cpl_frame * copy = cpl_frame_duplicate(frame);
00227 
00228         const cpl_error_code error = irplib_framelist_set(self, copy, i);
00229 
00230         assert(error == CPL_ERROR_NONE);
00231 
00232     }
00233 
00234     assert(self->size == cpl_frameset_get_size(frameset));
00235 
00236     return self;
00237 
00238 }
00239 
00240 
00241 /*----------------------------------------------------------------------------*/
00250 /*----------------------------------------------------------------------------*/
00251 cpl_frameset * irplib_frameset_cast(const irplib_framelist * self)
00252 {
00253 
00254     cpl_frameset * new;
00255     int i;
00256 
00257     cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00258 
00259     /* The function cannot fail now */
00260     new = cpl_frameset_new();
00261 
00262     for (i = 0; i < self->size; i++) {
00263         cpl_frame * frame = cpl_frame_duplicate(self->frame[i]);
00264         const cpl_error_code error = cpl_frameset_insert(new, frame);
00265 
00266         assert(error == CPL_ERROR_NONE);
00267 
00268     }
00269 
00270     assert(self->size == cpl_frameset_get_size(new));
00271 
00272     return new;
00273 
00274 }
00275 
00276 
00277 /*----------------------------------------------------------------------------*/
00289 /*----------------------------------------------------------------------------*/
00290 irplib_framelist * irplib_framelist_extract(const irplib_framelist * self,
00291                                             const char * tag)
00292 {
00293 
00294     irplib_framelist * new;
00295     int i, newsize;
00296 
00297 
00298     cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00299     cpl_ensure(tag  != NULL, CPL_ERROR_NULL_INPUT, NULL);
00300 
00301     new = irplib_framelist_new();
00302     newsize = 0;
00303 
00304     for (i = 0; i < self->size; i++) {
00305         const cpl_frame * frame = self->frame[i];
00306         const char * ftag = cpl_frame_get_tag(frame);
00307         cpl_frame * copy;
00308         cpl_error_code error;
00309 
00310         if (ftag == NULL) {
00311             /* The frame is ill-formed */
00312             irplib_framelist_delete(new);
00313             cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00314         }
00315 
00316         if (strcmp(tag, ftag)) continue;
00317 
00318         copy = cpl_frame_duplicate(frame);
00319 
00320         error = irplib_framelist_set(new, copy, newsize);
00321         assert(error == CPL_ERROR_NONE);
00322 
00323         if (self->propertylist[i] != NULL) new->propertylist[newsize]
00324             = cpl_propertylist_duplicate(self->propertylist[i]);
00325 
00326         newsize++;
00327     }
00328 
00329     assert( newsize == new->size );
00330 
00331     if (newsize == 0) {
00332 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00333         cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00334                               "The list of %d frame(s) has no frames "
00335                               "with tag: %s", self->size, tag);
00336 #else
00337         cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00338                               "The list of frame(s) has no frames "
00339                               "with the given tag");
00340 #endif
00341         irplib_framelist_delete(new);
00342         new = NULL;
00343     }
00344 
00345     return new;
00346 
00347 }
00348 
00349 /*----------------------------------------------------------------------------*/
00359 /*----------------------------------------------------------------------------*/
00360 irplib_framelist * irplib_framelist_extract_regexp(const irplib_framelist* self,
00361                                                    const char * regexp,
00362                                                    cpl_boolean invert)
00363 {
00364 
00365     irplib_framelist * new;
00366     int error;
00367     int i, newsize;
00368     const int xor = invert == CPL_FALSE ? 0 : 1;
00369     regex_t re;
00370 
00371 
00372     cpl_ensure(self   != NULL, CPL_ERROR_NULL_INPUT, NULL);
00373     cpl_ensure(regexp != NULL, CPL_ERROR_NULL_INPUT, NULL);
00374 
00375     error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
00376     cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, NULL);
00377 
00378     new = irplib_framelist_new();
00379     newsize = 0;
00380 
00381     for (i = 0; i < self->size; i++) {
00382         const cpl_frame * frame = self->frame[i];
00383         const char * tag = cpl_frame_get_tag(frame);
00384         cpl_frame * copy;
00385 
00386         if (tag == NULL) {
00387             /* The frame is ill-formed */
00388             irplib_framelist_delete(new);
00389             regfree(&re);
00390             cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00391         }
00392 
00393         if ((regexec(&re, tag, (size_t)0, NULL, 0) == REG_NOMATCH ? 1 : 0)
00394             ^ xor) continue;
00395 
00396         copy = cpl_frame_duplicate(frame);
00397 
00398         error = (int)irplib_framelist_set(new, copy, newsize);
00399         assert(error == CPL_ERROR_NONE);
00400 
00401         if (self->propertylist[i] != NULL) new->propertylist[newsize]
00402             = cpl_propertylist_duplicate(self->propertylist[i]);
00403 
00404         newsize++;
00405 
00406     }
00407 
00408     regfree(&re);
00409 
00410     assert( newsize == new->size );
00411 
00412     if (newsize == 0) {
00413 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00414         cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00415                               "The list of %d frame(s) has no frames "
00416                               "that match: %s", self->size, regexp);
00417 #else
00418         cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00419                               "The list of frames has no frames "
00420                               "that match the regular expression");
00421 #endif
00422         irplib_framelist_delete(new);
00423         new = NULL;
00424     }
00425 
00426     return new;
00427 }
00428 
00429 
00430 /*----------------------------------------------------------------------------*/
00437 /*----------------------------------------------------------------------------*/
00438 int irplib_framelist_get_size(const irplib_framelist * self)
00439 {
00440 
00441     cpl_ensure(self != NULL,  CPL_ERROR_NULL_INPUT, -1);
00442 
00443     return self->size;
00444 
00445 }
00446 
00447 /*----------------------------------------------------------------------------*/
00455 /*----------------------------------------------------------------------------*/
00456 cpl_frame * irplib_framelist_get(irplib_framelist * self, int pos)
00457 {
00458     return (cpl_frame *)irplib_framelist_get_const(self, pos);
00459 
00460 }
00461 
00462 
00463 /*----------------------------------------------------------------------------*/
00471 /*----------------------------------------------------------------------------*/
00472 const cpl_frame * irplib_framelist_get_const(const irplib_framelist * self,
00473                                              int pos)
00474 {
00475 
00476     cpl_ensure(self != NULL,      CPL_ERROR_NULL_INPUT,          NULL);
00477     cpl_ensure(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT,       NULL);
00478     cpl_ensure(pos  < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00479 
00480     return self->frame[pos];
00481 
00482 }
00483 
00484 
00485 /*----------------------------------------------------------------------------*/
00494 /*----------------------------------------------------------------------------*/
00495 cpl_error_code irplib_framelist_set_propertylist(irplib_framelist * self,
00496                                                  int pos,
00497                                                  const cpl_propertylist * list)
00498 {
00499 
00500     cpl_ensure_code(self != NULL,      CPL_ERROR_NULL_INPUT);
00501     cpl_ensure_code(list != NULL,      CPL_ERROR_NULL_INPUT);
00502     cpl_ensure_code(pos  >= 0,         CPL_ERROR_ILLEGAL_INPUT);
00503     cpl_ensure_code(pos  < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00504 
00505     cpl_propertylist_delete(self->propertylist[pos]);
00506 
00507     self->propertylist[pos] = cpl_propertylist_duplicate(list);
00508 
00509     cpl_ensure_code(self->propertylist[pos] != NULL, cpl_error_get_code());
00510 
00511     return CPL_ERROR_NONE;
00512 
00513 }
00514 
00515 
00516 /*----------------------------------------------------------------------------*/
00527 /*----------------------------------------------------------------------------*/
00528 cpl_propertylist * irplib_framelist_get_propertylist(irplib_framelist * self,
00529                                                      int pos)
00530 {
00531 
00532     return (cpl_propertylist *)irplib_framelist_get_propertylist_const(self,
00533                                                                        pos);
00534 
00535 }
00536 
00537 
00538 /*----------------------------------------------------------------------------*/
00549 /*----------------------------------------------------------------------------*/
00550 const cpl_propertylist * irplib_framelist_get_propertylist_const(
00551                                                   const irplib_framelist * self,
00552                                                   int pos)
00553 {
00554     cpl_ensure(self != NULL,      CPL_ERROR_NULL_INPUT,          NULL);
00555     cpl_ensure(pos  >= 0,         CPL_ERROR_ILLEGAL_INPUT,       NULL);
00556     cpl_ensure(pos  < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00557 
00558     cpl_ensure(self->propertylist[pos] != NULL,
00559                   CPL_ERROR_DATA_NOT_FOUND, NULL);
00560 
00561     return self->propertylist[pos];
00562 
00563 }
00564 
00565 
00566 /*----------------------------------------------------------------------------*/
00580 /*----------------------------------------------------------------------------*/
00581 cpl_error_code irplib_framelist_load_propertylist(irplib_framelist * self,
00582                                                   int pos, int ind,
00583                                                   const char * regexp,
00584                                                   cpl_boolean invert)
00585 {
00586 
00587     const char * filename;
00588 
00589 
00590     cpl_ensure_code(self   != NULL,    CPL_ERROR_NULL_INPUT);
00591     cpl_ensure_code(regexp != NULL,    CPL_ERROR_NULL_INPUT);
00592     cpl_ensure_code(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT);
00593     cpl_ensure_code(pos <  self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00594 
00595     filename = cpl_frame_get_filename(self->frame[pos]);
00596 
00597     cpl_ensure_code(filename != NULL, cpl_error_get_code());
00598 
00599     cpl_propertylist_delete(self->propertylist[pos]);
00600 
00601     self->propertylist[pos] = cpl_propertylist_load_regexp(filename, ind,
00602                                                            regexp,
00603                                                            invert ? 1 : 0);
00604 
00605     if (self->propertylist[pos] == NULL) {
00606 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00607         return cpl_error_set_message(cpl_func, cpl_error_get_code(), "Could "
00608                                      "not load FITS header from '%s' using "
00609                                      "regexp '%s'", filename, regexp);
00610 #else
00611         return cpl_error_set_message(cpl_func, cpl_error_get_code(),
00612                                      "Could not load FITS header");
00613 #endif
00614     }
00615 
00616     return CPL_ERROR_NONE;
00617 
00618 }
00619 
00620 
00621 /*----------------------------------------------------------------------------*/
00635 /*----------------------------------------------------------------------------*/
00636 cpl_error_code irplib_framelist_load_propertylist_all(irplib_framelist * self,
00637                                                       int ind,
00638                                                       const char * regexp,
00639                                                       cpl_boolean invert)
00640 {
00641 
00642     int nprops = 0;
00643     int nfiles = 0;
00644     int i;
00645 
00646     cpl_ensure_code(self   != NULL,    CPL_ERROR_NULL_INPUT);
00647     cpl_ensure_code(regexp != NULL,    CPL_ERROR_NULL_INPUT);
00648 
00649     for (i=0; i < self->size; i++) {
00650         if (self->propertylist[i] == NULL)
00651             cpl_ensure_code(!irplib_framelist_load_propertylist(self, i,
00652                                                                 ind,
00653                                                                 regexp,
00654                                                                 invert),
00655                                cpl_error_get_code());
00656         /* Counting just for diagnostics - this actually causes
00657            the whole list to be reiterated :-( */
00658         nprops += cpl_propertylist_get_size(self->propertylist[i]);
00659         nfiles++;
00660     }
00661 
00662     cpl_msg_info(cpl_func, "List of %d frames has %d properties", nfiles,
00663                  nprops);
00664 
00665     return CPL_ERROR_NONE;
00666 
00667 }
00668 
00669 
00670 
00671 /*----------------------------------------------------------------------------*/
00679 /*----------------------------------------------------------------------------*/
00680 cpl_error_code irplib_framelist_set_tag_all(irplib_framelist * self,
00681                                             const char * tag)
00682 {
00683 
00684     int i;
00685 
00686     cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00687     cpl_ensure_code(tag  != NULL, CPL_ERROR_NULL_INPUT);
00688 
00689     for (i=0; i < self->size; i++)
00690         cpl_ensure_code(!cpl_frame_set_tag(self->frame[i], tag),
00691                            cpl_error_get_code());
00692 
00693     return CPL_ERROR_NONE;
00694 }
00695 
00696 
00697 /*----------------------------------------------------------------------------*/
00711 /*----------------------------------------------------------------------------*/
00712 cpl_error_code irplib_framelist_set(irplib_framelist * self, cpl_frame * frame,
00713                                     int pos)
00714 {
00715 
00716     cpl_ensure_code(self  != NULL,     CPL_ERROR_NULL_INPUT);
00717     cpl_ensure_code(frame != NULL,     CPL_ERROR_NULL_INPUT);
00718     cpl_ensure_code(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT);
00719 
00720     if (pos == self->size) {
00721 
00722         self->size++;
00723 
00724         irplib_framelist_set_size(self);
00725 
00726     } else {
00727 
00728         cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00729 
00730         cpl_frame_delete(self->frame[pos]);
00731         cpl_propertylist_delete(self->propertylist[pos]);
00732     }
00733 
00734     self->frame[pos] = frame;
00735     self->propertylist[pos] = NULL;
00736 
00737     return CPL_ERROR_NONE;
00738 
00739 }
00740 
00741 /*----------------------------------------------------------------------------*/
00750 /*----------------------------------------------------------------------------*/
00751 cpl_error_code irplib_framelist_erase(irplib_framelist * self, int pos)
00752 {
00753 
00754     int i;
00755 
00756     cpl_ensure_code(self  != NULL,    CPL_ERROR_NULL_INPUT);
00757     cpl_ensure_code(pos >= 0,         CPL_ERROR_ILLEGAL_INPUT);
00758     cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00759 
00760 
00761     /* Delete the specified frame and its propertylist */
00762     cpl_frame_delete(self->frame[pos]);
00763     cpl_propertylist_delete(self->propertylist[pos]);
00764 
00765     /* Move following frames down one position */
00766     for (i = pos+1; i < self->size; i++) {
00767 
00768         self->frame[i-1] = self->frame[i];
00769 
00770         self->propertylist[i-1] = self->propertylist[i];
00771 
00772     }
00773 
00774     self->size--;
00775 
00776     irplib_framelist_set_size(self);
00777 
00778     return CPL_ERROR_NONE;
00779 
00780 }
00781 
00782 
00783 
00784 /*----------------------------------------------------------------------------*/
00800 /*----------------------------------------------------------------------------*/
00801 cpl_frame * irplib_framelist_unset(irplib_framelist * self, int pos,
00802                                    cpl_propertylist ** plist)
00803 
00804 {
00805     cpl_frame * frame;
00806     int i;
00807 
00808 
00809     cpl_ensure(self  != NULL,    CPL_ERROR_NULL_INPUT, NULL);
00810     cpl_ensure(pos >= 0,         CPL_ERROR_ILLEGAL_INPUT, NULL);
00811     cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00812 
00813     /* Get the specified frame and its propertylist */
00814     frame = self->frame[pos];
00815 
00816     if (plist != NULL)
00817         *plist = self->propertylist[pos];
00818     else
00819         cpl_propertylist_delete(self->propertylist[pos]);
00820 
00821 
00822     /* Move following frames down one position */
00823     for (i = pos+1; i < self->size; i++) {
00824 
00825         self->frame[i-1] = self->frame[i];
00826 
00827         self->propertylist[i-1] = self->propertylist[i];
00828 
00829     }
00830 
00831     self->size--;
00832 
00833     irplib_framelist_set_size(self);
00834 
00835     return frame;
00836 
00837 }
00838 
00839 /*----------------------------------------------------------------------------*/
00846 /*----------------------------------------------------------------------------*/
00847 void irplib_framelist_empty(irplib_framelist * self)
00848 {
00849 
00850     if (self != NULL) {
00851 
00852         /* Deallocate all frames and their propertylists */
00853         while (self->size > 0) {
00854             self->size--;
00855             cpl_frame_delete(self->frame[self->size]);
00856             cpl_propertylist_delete(self->propertylist[self->size]);
00857 
00858         }
00859         
00860         /* Deallocate the arrays */
00861         irplib_framelist_set_size(self);
00862 
00863     }
00864 }
00865 
00866 
00867 
00868 /*----------------------------------------------------------------------------*/
00906 /*----------------------------------------------------------------------------*/
00907 cpl_error_code irplib_framelist_contains(const irplib_framelist * self,
00908                                          const char * key, cpl_type type,
00909                                          cpl_boolean is_equal, double fp_tol)
00910 {
00911 
00912     char * value_0;
00913     char * value_i;
00914     cpl_type type_0 = CPL_TYPE_INVALID;
00915     int i;
00916 
00917 
00918     cpl_ensure_code(self  != NULL, CPL_ERROR_NULL_INPUT);
00919     cpl_ensure_code(key   != NULL, CPL_ERROR_NULL_INPUT);
00920     cpl_ensure_code(fp_tol >= 0.0, CPL_ERROR_ILLEGAL_INPUT);
00921 
00922     for (i=0; i < self->size; i++) {
00923         cpl_type type_i;
00924 
00925 
00926         if (self->propertylist[i] == NULL) continue;
00927 
00928         type_i = cpl_propertylist_get_type(self->propertylist[i], key);
00929 
00930         if (type_i == CPL_TYPE_INVALID) {
00931             if (type == CPL_TYPE_INVALID)
00932 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00933                 cpl_error_set_message(cpl_func, cpl_error_get_code(), "FITS "
00934                                       "key '%s' is missing from file %s", key,
00935                                       cpl_frame_get_filename(self->frame[i]));
00936             else
00937                 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00938                                       "FITS key '%s' [%s] is missing from file "
00939                                       "%s", key, cpl_type_get_name(type),
00940                                       cpl_frame_get_filename(self->frame[i]));
00941 #else
00942                 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00943                                       "A FITS key is missing from a file");
00944             else
00945                 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00946                                       "A FITS key is missing from a file");
00947 #endif
00948             return cpl_error_get_code();
00949         }
00950 
00951         if (type != CPL_TYPE_INVALID && type_i != type) {
00952 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00953             return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
00954                                          "FITS key '%s' has type %s instead of "
00955                                          "%s in file %s", key,
00956                                          cpl_type_get_name(type_i),
00957                                          cpl_type_get_name(type),
00958                                          cpl_frame_get_filename(self->frame[i]));
00959 #else
00960             return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
00961                                          "A FITS key had an unexpected type");
00962 #endif
00963 
00964         }
00965 
00966         if (!is_equal) continue;
00967 
00968         if (type_0 == CPL_TYPE_INVALID) {
00969             type_0 = type_i;
00970             continue;
00971         }
00972 
00973         if (type_i != type_0) {
00974             assert( type == CPL_TYPE_INVALID );
00975 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00976             return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
00977                                          "FITS key '%s' has different types "
00978                                          "(%s <=> %s) in files %s and %s", key,
00979                                          cpl_type_get_name(type_0),
00980                                          cpl_type_get_name(type_i),
00981                                          cpl_frame_get_filename(self->frame[0]),
00982                                          cpl_frame_get_filename(self->frame[i]));
00983 #else
00984             return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
00985                                          "A FITS key has different types in "
00986                                          "two files");
00987 #endif
00988         }
00989 
00990         if (irplib_property_equal(self->propertylist[0], self->propertylist[i],
00991                                   key, type_0, fp_tol, &value_0, &value_i))
00992             continue;
00993 
00994         if ((type_0 == CPL_TYPE_FLOAT || type_0 == CPL_TYPE_DOUBLE)
00995             && fp_tol > 0.0) {
00996 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00997             cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "FITS"
00998                                   " key '%s' [%s] has values that differ by "
00999                                   "more than %g (%s <=> %s) in files %s and %s",
01000                                   key, cpl_type_get_name(type_0), fp_tol,
01001                                   value_0, value_i,
01002                                   cpl_frame_get_filename(self->frame[0]),
01003                                   cpl_frame_get_filename(self->frame[i]));
01004 #else
01005             cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "A "
01006                                   "FITS key has values that differ by more "
01007                                   "than the allowed tolerance in two file");
01008 #endif
01009         } else {
01010 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01011             cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
01012                                   "FITS key '%s' [%s] has different values "
01013                                   "(%s <=> %s) in files %s and %s", key,
01014                                   cpl_type_get_name(type_0),
01015                                   value_0, value_i,
01016                                   cpl_frame_get_filename(self->frame[0]),
01017                                   cpl_frame_get_filename(self->frame[i]));
01018 #else
01019             cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "A "
01020                                   "FITS key has different values in two files");
01021 #endif
01022         }
01023         cpl_free(value_0);
01024         cpl_free(value_i);
01025 
01026         return cpl_error_get_code();
01027     }        
01028 
01029     return CPL_ERROR_NONE;
01030 
01031 }
01032 
01033 
01034 /*----------------------------------------------------------------------------*/
01047 /*----------------------------------------------------------------------------*/
01048 cpl_imagelist * irplib_imagelist_load_framelist(const irplib_framelist * self,
01049                                                 cpl_type pixeltype,
01050                                                 int planenum,
01051                                                 int extnum)
01052 {
01053 
01054     cpl_imagelist * list = NULL;
01055     cpl_image     * image = NULL;
01056     int i;
01057 
01058 
01059     cpl_ensure(self != NULL,  CPL_ERROR_NULL_INPUT,          NULL);
01060     cpl_ensure(extnum >= 0,   CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01061     cpl_ensure(planenum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01062 
01063     list = cpl_imagelist_new();
01064 
01065     for (i=0; i < self->size; i++, image = NULL) {
01066         const char * filename = cpl_frame_get_filename(self->frame[i]);
01067         cpl_error_code error;
01068 
01069         if (filename == NULL) break;
01070 
01071         image = cpl_image_load(filename, pixeltype, planenum, extnum);
01072         if (image == NULL) {
01073 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01074             (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
01075                                         "Could not load FITS-image from plane "
01076                                         "%d in extension %d in file %s",
01077                                         planenum, extnum, filename);
01078 #else
01079             (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
01080                                         "Could not load FITS-image");
01081 #endif
01082             break;
01083         }
01084 
01085         error = cpl_imagelist_set(list, image, i);
01086         assert(error == CPL_ERROR_NONE);
01087     }
01088 
01089     cpl_image_delete(image);
01090     
01091     if (cpl_imagelist_get_size(list) != self->size) {
01092         cpl_imagelist_delete(list);
01093         list = NULL;
01094         assert(cpl_error_get_code() != CPL_ERROR_NONE);
01095     }
01096 
01097     return list;
01098 
01099 }
01100 
01101 
01105 /*----------------------------------------------------------------------------*/
01117 /*----------------------------------------------------------------------------*/
01118 static void irplib_framelist_set_size(irplib_framelist * self)
01119 {
01120 
01121 
01122     assert( self != NULL);
01123 
01124     if (self->size == 0) {
01125         /* The list has been emptied */
01126         cpl_free(self->frame);
01127         cpl_free(self->propertylist);
01128         self->frame = NULL;
01129         self->propertylist = NULL;
01130     } else {
01131         /* Update the size of the arrays */
01132 
01133         self->frame = cpl_realloc(self->frame, self->size * sizeof(cpl_frame*));
01134         self->propertylist =
01135             cpl_realloc(self->propertylist,
01136                         self->size * sizeof(cpl_propertylist*));
01137     }
01138 
01139 }
01140 
01141 /*----------------------------------------------------------------------------*/
01165 /*----------------------------------------------------------------------------*/
01166 static cpl_boolean irplib_property_equal(const cpl_propertylist * self,
01167                                          const cpl_propertylist * other,
01168                                          const char * key, cpl_type type,
01169                                          double fp_tol,
01170                                          char ** sstring, char ** ostring)
01171 {
01172 
01173     cpl_boolean equal;
01174 
01175 
01176     assert(self    != NULL);
01177     assert(other   != NULL);
01178     assert(key     != NULL);
01179     assert(sstring != NULL);
01180     assert(ostring != NULL);
01181 
01182     /* FIXME: disable for better performance also with debugging */
01183     assert(cpl_propertylist_get_type(other, key) == type);
01184     assert(fp_tol >= 0.0);
01185 
01186     switch (type) {
01187 
01188     case CPL_TYPE_CHAR: {
01189         const char svalue = cpl_propertylist_get_char(self, key);
01190         const char ovalue = cpl_propertylist_get_char(other, key);
01191 
01192         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01193         if (!equal) {
01194             *sstring = cpl_sprintf("%c", svalue);
01195             *ostring = cpl_sprintf("%c", ovalue);
01196         }
01197         break;
01198     }
01199 
01200     case CPL_TYPE_BOOL: {
01201         const int svalue = cpl_propertylist_get_bool(self, key);
01202         const int ovalue = cpl_propertylist_get_bool(other, key);
01203 
01204         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01205         if (!equal) {
01206             *sstring = cpl_strdup(svalue == 0 ? "F" : "T");
01207             *ostring = cpl_strdup(ovalue == 0 ? "F" : "T");
01208         }
01209         break;
01210     }
01211 
01212     case CPL_TYPE_INT: {
01213         const int svalue = cpl_propertylist_get_int(self, key);
01214         const int ovalue = cpl_propertylist_get_int(other, key);
01215 
01216         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01217         if (!equal) {
01218             *sstring = cpl_sprintf("%d", svalue);
01219             *ostring = cpl_sprintf("%d", ovalue);
01220         }
01221         break;
01222     }
01223 
01224     case CPL_TYPE_LONG: {
01225         const long svalue = cpl_propertylist_get_long(self, key);
01226         const long ovalue = cpl_propertylist_get_long(other, key);
01227 
01228         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01229         if (!equal) {
01230             *sstring = cpl_sprintf("%ld", svalue);
01231             *ostring = cpl_sprintf("%ld", ovalue);
01232         }
01233         break;
01234     }
01235 
01236     case CPL_TYPE_FLOAT: {
01237         const double svalue = (double)cpl_propertylist_get_float(self, key);
01238         const double ovalue = (double)cpl_propertylist_get_float(other, key);
01239 
01240         equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01241         if (!equal) {
01242             *sstring = cpl_sprintf("%f", svalue);
01243             *ostring = cpl_sprintf("%f", ovalue);
01244         }
01245         break;
01246     }
01247 
01248     case CPL_TYPE_DOUBLE: {
01249         const double svalue = cpl_propertylist_get_double(self, key);
01250         const double ovalue = cpl_propertylist_get_double(other, key);
01251 
01252         equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01253         if (!equal) {
01254             *sstring = cpl_sprintf("%g", svalue);
01255             *ostring = cpl_sprintf("%g", ovalue);
01256         }
01257         break;
01258     }
01259     case CPL_TYPE_STRING: {
01260         const char * svalue = cpl_propertylist_get_string(self, key);
01261         const char * ovalue = cpl_propertylist_get_string(other, key);
01262 
01263         equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
01264         if (!equal) {
01265             *sstring = cpl_strdup(svalue);
01266             *ostring = cpl_strdup(ovalue);
01267         }
01268         break;
01269     }
01270     default:
01271         /* Unknown property type */
01272         assert( 0 );
01273 
01274         equal = CPL_FALSE; /* In case of -DNDEBUG */
01275 
01276     }
01277 
01278     if (!equal) {
01279         assert( *sstring != NULL );
01280         assert( *ostring != NULL );
01281     }
01282 
01283     return equal;
01284 
01285 }

Generated on Mon Feb 6 14:42:06 2012 for NACO Pipeline Reference Manual by  doxygen 1.5.8