irplib_framelist.c

00001 /* $Id: irplib_framelist.c,v 1.30 2013/02/27 16:05:13 jtaylor 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: jtaylor $
00023  * $Date: 2013/02/27 16:05:13 $
00024  * $Revision: 1.30 $
00025  * $Name: HEAD $
00026  */
00027 
00028 
00029 #ifdef HAVE_CONFIG_H
00030 #include <config.h>
00031 #endif
00032 
00033 
00034 /*-----------------------------------------------------------------------------
00035                                  Includes
00036  -----------------------------------------------------------------------------*/
00037 
00038 #include "irplib_framelist.h"
00039 #include "irplib_utils.h"
00040 #include <cpl.h>
00041 
00042 #include <stdio.h>
00043 #include <string.h>
00044 #include <sys/types.h>
00045 #include <regex.h>
00046 #include <math.h>
00047 #include <assert.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     IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
00459     return (cpl_frame *)irplib_framelist_get_const(self, pos);
00460     IRPLIB_DIAG_PRAGMA_POP;
00461 }
00462 
00463 
00464 /*----------------------------------------------------------------------------*/
00472 /*----------------------------------------------------------------------------*/
00473 const cpl_frame * irplib_framelist_get_const(const irplib_framelist * self,
00474                                              int pos)
00475 {
00476 
00477     cpl_ensure(self != NULL,      CPL_ERROR_NULL_INPUT,          NULL);
00478     cpl_ensure(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT,       NULL);
00479     cpl_ensure(pos  < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00480 
00481     return self->frame[pos];
00482 
00483 }
00484 
00485 
00486 /*----------------------------------------------------------------------------*/
00495 /*----------------------------------------------------------------------------*/
00496 cpl_error_code irplib_framelist_set_propertylist(irplib_framelist * self,
00497                                                  int pos,
00498                                                  const cpl_propertylist * list)
00499 {
00500 
00501     cpl_ensure_code(self != NULL,      CPL_ERROR_NULL_INPUT);
00502     cpl_ensure_code(list != NULL,      CPL_ERROR_NULL_INPUT);
00503     cpl_ensure_code(pos  >= 0,         CPL_ERROR_ILLEGAL_INPUT);
00504     cpl_ensure_code(pos  < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00505 
00506     cpl_propertylist_delete(self->propertylist[pos]);
00507 
00508     self->propertylist[pos] = cpl_propertylist_duplicate(list);
00509 
00510     cpl_ensure_code(self->propertylist[pos] != NULL, cpl_error_get_code());
00511 
00512     return CPL_ERROR_NONE;
00513 
00514 }
00515 
00516 
00517 /*----------------------------------------------------------------------------*/
00528 /*----------------------------------------------------------------------------*/
00529 cpl_propertylist * irplib_framelist_get_propertylist(irplib_framelist * self,
00530                                                      int pos)
00531 {
00532 
00533     IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
00534     return (cpl_propertylist *)irplib_framelist_get_propertylist_const(self,
00535                                                                        pos);
00536     IRPLIB_DIAG_PRAGMA_POP;
00537 }
00538 
00539 
00540 /*----------------------------------------------------------------------------*/
00551 /*----------------------------------------------------------------------------*/
00552 const cpl_propertylist * irplib_framelist_get_propertylist_const(
00553                                                   const irplib_framelist * self,
00554                                                   int pos)
00555 {
00556     cpl_ensure(self != NULL,      CPL_ERROR_NULL_INPUT,          NULL);
00557     cpl_ensure(pos  >= 0,         CPL_ERROR_ILLEGAL_INPUT,       NULL);
00558     cpl_ensure(pos  < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00559 
00560     cpl_ensure(self->propertylist[pos] != NULL,
00561                   CPL_ERROR_DATA_NOT_FOUND, NULL);
00562 
00563     return self->propertylist[pos];
00564 
00565 }
00566 
00567 
00568 /*----------------------------------------------------------------------------*/
00582 /*----------------------------------------------------------------------------*/
00583 cpl_error_code irplib_framelist_load_propertylist(irplib_framelist * self,
00584                                                   int pos, int ind,
00585                                                   const char * regexp,
00586                                                   cpl_boolean invert)
00587 {
00588 
00589     const char * filename;
00590 
00591 
00592     cpl_ensure_code(self   != NULL,    CPL_ERROR_NULL_INPUT);
00593     cpl_ensure_code(regexp != NULL,    CPL_ERROR_NULL_INPUT);
00594     cpl_ensure_code(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT);
00595     cpl_ensure_code(pos <  self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00596 
00597     filename = cpl_frame_get_filename(self->frame[pos]);
00598 
00599     cpl_ensure_code(filename != NULL, cpl_error_get_code());
00600 
00601     cpl_propertylist_delete(self->propertylist[pos]);
00602 
00603     self->propertylist[pos] = cpl_propertylist_load_regexp(filename, ind,
00604                                                            regexp,
00605                                                            invert ? 1 : 0);
00606 
00607     if (self->propertylist[pos] == NULL) {
00608 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00609         return cpl_error_set_message(cpl_func, cpl_error_get_code(), "Could "
00610                                      "not load FITS header from '%s' using "
00611                                      "regexp '%s'", filename, regexp);
00612 #else
00613         return cpl_error_set_message(cpl_func, cpl_error_get_code(),
00614                                      "Could not load FITS header");
00615 #endif
00616     }
00617 
00618     return CPL_ERROR_NONE;
00619 
00620 }
00621 
00622 
00623 /*----------------------------------------------------------------------------*/
00637 /*----------------------------------------------------------------------------*/
00638 cpl_error_code irplib_framelist_load_propertylist_all(irplib_framelist * self,
00639                                                       int ind,
00640                                                       const char * regexp,
00641                                                       cpl_boolean invert)
00642 {
00643 
00644     int nprops = 0;
00645     int nfiles = 0;
00646     int i;
00647 
00648     cpl_ensure_code(self   != NULL,    CPL_ERROR_NULL_INPUT);
00649     cpl_ensure_code(regexp != NULL,    CPL_ERROR_NULL_INPUT);
00650 
00651     for (i=0; i < self->size; i++) {
00652         if (self->propertylist[i] == NULL)
00653             cpl_ensure_code(!irplib_framelist_load_propertylist(self, i,
00654                                                                 ind,
00655                                                                 regexp,
00656                                                                 invert),
00657                                cpl_error_get_code());
00658         /* Counting just for diagnostics - this actually causes
00659            the whole list to be reiterated :-( */
00660         nprops += cpl_propertylist_get_size(self->propertylist[i]);
00661         nfiles++;
00662     }
00663 
00664     cpl_msg_info(cpl_func, "List of %d frames has %d properties", nfiles,
00665                  nprops);
00666 
00667     return CPL_ERROR_NONE;
00668 
00669 }
00670 
00671 
00672 
00673 /*----------------------------------------------------------------------------*/
00681 /*----------------------------------------------------------------------------*/
00682 cpl_error_code irplib_framelist_set_tag_all(irplib_framelist * self,
00683                                             const char * tag)
00684 {
00685 
00686     int i;
00687 
00688     cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00689     cpl_ensure_code(tag  != NULL, CPL_ERROR_NULL_INPUT);
00690 
00691     for (i=0; i < self->size; i++)
00692         cpl_ensure_code(!cpl_frame_set_tag(self->frame[i], tag),
00693                            cpl_error_get_code());
00694 
00695     return CPL_ERROR_NONE;
00696 }
00697 
00698 
00699 /*----------------------------------------------------------------------------*/
00713 /*----------------------------------------------------------------------------*/
00714 cpl_error_code irplib_framelist_set(irplib_framelist * self, cpl_frame * frame,
00715                                     int pos)
00716 {
00717 
00718     cpl_ensure_code(self  != NULL,     CPL_ERROR_NULL_INPUT);
00719     cpl_ensure_code(frame != NULL,     CPL_ERROR_NULL_INPUT);
00720     cpl_ensure_code(pos >= 0,          CPL_ERROR_ILLEGAL_INPUT);
00721 
00722     if (pos == self->size) {
00723 
00724         self->size++;
00725 
00726         irplib_framelist_set_size(self);
00727 
00728     } else {
00729 
00730         cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00731 
00732         cpl_frame_delete(self->frame[pos]);
00733         cpl_propertylist_delete(self->propertylist[pos]);
00734     }
00735 
00736     self->frame[pos] = frame;
00737     self->propertylist[pos] = NULL;
00738 
00739     return CPL_ERROR_NONE;
00740 
00741 }
00742 
00743 /*----------------------------------------------------------------------------*/
00752 /*----------------------------------------------------------------------------*/
00753 cpl_error_code irplib_framelist_erase(irplib_framelist * self, int pos)
00754 {
00755 
00756     int i;
00757 
00758     cpl_ensure_code(self  != NULL,    CPL_ERROR_NULL_INPUT);
00759     cpl_ensure_code(pos >= 0,         CPL_ERROR_ILLEGAL_INPUT);
00760     cpl_ensure_code(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00761 
00762 
00763     /* Delete the specified frame and its propertylist */
00764     cpl_frame_delete(self->frame[pos]);
00765     cpl_propertylist_delete(self->propertylist[pos]);
00766 
00767     /* Move following frames down one position */
00768     for (i = pos+1; i < self->size; i++) {
00769 
00770         self->frame[i-1] = self->frame[i];
00771 
00772         self->propertylist[i-1] = self->propertylist[i];
00773 
00774     }
00775 
00776     self->size--;
00777 
00778     irplib_framelist_set_size(self);
00779 
00780     return CPL_ERROR_NONE;
00781 
00782 }
00783 
00784 
00785 
00786 /*----------------------------------------------------------------------------*/
00802 /*----------------------------------------------------------------------------*/
00803 cpl_frame * irplib_framelist_unset(irplib_framelist * self, int pos,
00804                                    cpl_propertylist ** plist)
00805 
00806 {
00807     cpl_frame * frame;
00808     int i;
00809 
00810 
00811     cpl_ensure(self  != NULL,    CPL_ERROR_NULL_INPUT, NULL);
00812     cpl_ensure(pos >= 0,         CPL_ERROR_ILLEGAL_INPUT, NULL);
00813     cpl_ensure(pos < self->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
00814 
00815     /* Get the specified frame and its propertylist */
00816     frame = self->frame[pos];
00817 
00818     if (plist != NULL)
00819         *plist = self->propertylist[pos];
00820     else
00821         cpl_propertylist_delete(self->propertylist[pos]);
00822 
00823 
00824     /* Move following frames down one position */
00825     for (i = pos+1; i < self->size; i++) {
00826 
00827         self->frame[i-1] = self->frame[i];
00828 
00829         self->propertylist[i-1] = self->propertylist[i];
00830 
00831     }
00832 
00833     self->size--;
00834 
00835     irplib_framelist_set_size(self);
00836 
00837     return frame;
00838 
00839 }
00840 
00841 /*----------------------------------------------------------------------------*/
00848 /*----------------------------------------------------------------------------*/
00849 void irplib_framelist_empty(irplib_framelist * self)
00850 {
00851 
00852     if (self != NULL) {
00853 
00854         /* Deallocate all frames and their propertylists */
00855         while (self->size > 0) {
00856             self->size--;
00857             cpl_frame_delete(self->frame[self->size]);
00858             cpl_propertylist_delete(self->propertylist[self->size]);
00859 
00860         }
00861         
00862         /* Deallocate the arrays */
00863         irplib_framelist_set_size(self);
00864 
00865     }
00866 }
00867 
00868 
00869 
00870 /*----------------------------------------------------------------------------*/
00908 /*----------------------------------------------------------------------------*/
00909 cpl_error_code irplib_framelist_contains(const irplib_framelist * self,
00910                                          const char * key, cpl_type type,
00911                                          cpl_boolean is_equal, double fp_tol)
00912 {
00913 
00914     char * value_0;
00915     char * value_i;
00916     cpl_type type_0 = CPL_TYPE_INVALID;
00917     int i, ifirst = -1;  /* First non-NULL propertylist */
00918 
00919 
00920     cpl_ensure_code(self  != NULL, CPL_ERROR_NULL_INPUT);
00921     cpl_ensure_code(key   != NULL, CPL_ERROR_NULL_INPUT);
00922     cpl_ensure_code(fp_tol >= 0.0, CPL_ERROR_ILLEGAL_INPUT);
00923 
00924     for (i=0; i < self->size; i++) {
00925         cpl_type type_i;
00926 
00927 
00928         if (self->propertylist[i] == NULL) continue;
00929         if (ifirst < 0) ifirst = i;
00930 
00931         type_i = cpl_propertylist_get_type(self->propertylist[i], key);
00932 
00933         if (type_i == CPL_TYPE_INVALID) {
00934             if (type == CPL_TYPE_INVALID)
00935 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00936                 cpl_error_set_message(cpl_func, cpl_error_get_code(), "FITS "
00937                                       "key '%s' is missing from file %s", key,
00938                                       cpl_frame_get_filename(self->frame[i]));
00939             else
00940                 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00941                                       "FITS key '%s' [%s] is missing from file "
00942                                       "%s", key, cpl_type_get_name(type),
00943                                       cpl_frame_get_filename(self->frame[i]));
00944 #else
00945                 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00946                                       "A FITS key is missing from a file");
00947             else
00948                 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00949                                       "A FITS key is missing from a file");
00950 #endif
00951             return cpl_error_get_code();
00952         }
00953 
00954         if (type != CPL_TYPE_INVALID && type_i != type) {
00955 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00956             return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
00957                                          "FITS key '%s' has type %s instead of "
00958                                          "%s in file %s", key,
00959                                          cpl_type_get_name(type_i),
00960                                          cpl_type_get_name(type),
00961                                          cpl_frame_get_filename(self->frame[i]));
00962 #else
00963             return cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
00964                                          "A FITS key had an unexpected type");
00965 #endif
00966 
00967         }
00968 
00969         if (!is_equal) continue;
00970 
00971         if (type_0 == CPL_TYPE_INVALID) {
00972             type_0 = type_i;
00973             continue;
00974         }
00975 
00976         if (type_i != type_0) {
00977             assert( type == CPL_TYPE_INVALID );
00978 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00979             return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
00980                                          "FITS key '%s' has different types "
00981                                          "(%s <=> %s) in files %s and %s", key,
00982                                          cpl_type_get_name(type_0),
00983                                          cpl_type_get_name(type_i),
00984                                          cpl_frame_get_filename(self->frame[0]),
00985                                          cpl_frame_get_filename(self->frame[i]));
00986 #else
00987             return cpl_error_set_message(cpl_func, CPL_ERROR_TYPE_MISMATCH,
00988                                          "A FITS key has different types in "
00989                                          "two files");
00990 #endif
00991         }
00992 
00993         if (irplib_property_equal(self->propertylist[ifirst],
00994                                   self->propertylist[i],
00995                                   key, type_0, fp_tol, &value_0, &value_i))
00996             continue;
00997 
00998         if ((type_0 == CPL_TYPE_FLOAT || type_0 == CPL_TYPE_DOUBLE)
00999             && fp_tol > 0.0) {
01000 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01001             cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "FITS"
01002                                   " key '%s' [%s] has values that differ by "
01003                                   "more than %g (%s <=> %s) in files %s and %s",
01004                                   key, cpl_type_get_name(type_0), fp_tol,
01005                                   value_0, value_i,
01006                                   cpl_frame_get_filename(self->frame[0]),
01007                                   cpl_frame_get_filename(self->frame[i]));
01008 #else
01009             cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "A "
01010                                   "FITS key has values that differ by more "
01011                                   "than the allowed tolerance in two file");
01012 #endif
01013         } else {
01014 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01015             cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
01016                                   "FITS key '%s' [%s] has different values "
01017                                   "(%s <=> %s) in files %s and %s", key,
01018                                   cpl_type_get_name(type_0),
01019                                   value_0, value_i,
01020                                   cpl_frame_get_filename(self->frame[0]),
01021                                   cpl_frame_get_filename(self->frame[i]));
01022 #else
01023             cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "A "
01024                                   "FITS key has different values in two files");
01025 #endif
01026         }
01027         cpl_free(value_0);
01028         cpl_free(value_i);
01029 
01030         return cpl_error_get_code();
01031     }        
01032 
01033     return CPL_ERROR_NONE;
01034 
01035 }
01036 
01037 
01038 /*----------------------------------------------------------------------------*/
01051 /*----------------------------------------------------------------------------*/
01052 cpl_imagelist * irplib_imagelist_load_framelist(const irplib_framelist * self,
01053                                                 cpl_type pixeltype,
01054                                                 int planenum,
01055                                                 int extnum)
01056 {
01057 
01058     cpl_imagelist * list = NULL;
01059     cpl_image     * image = NULL;
01060     int i;
01061 
01062 
01063     cpl_ensure(self != NULL,  CPL_ERROR_NULL_INPUT,          NULL);
01064     cpl_ensure(extnum >= 0,   CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01065     cpl_ensure(planenum >= 0, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
01066 
01067     list = cpl_imagelist_new();
01068 
01069     for (i=0; i < self->size; i++, image = NULL) {
01070         const char * filename = cpl_frame_get_filename(self->frame[i]);
01071         cpl_error_code error;
01072 
01073         if (filename == NULL) break;
01074 
01075         image = cpl_image_load(filename, pixeltype, planenum, extnum);
01076         if (image == NULL) {
01077 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
01078             (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
01079                                         "Could not load FITS-image from plane "
01080                                         "%d in extension %d in file %s",
01081                                         planenum, extnum, filename);
01082 #else
01083             (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
01084                                         "Could not load FITS-image");
01085 #endif
01086             break;
01087         }
01088 
01089         error = cpl_imagelist_set(list, image, i);
01090         assert(error == CPL_ERROR_NONE);
01091     }
01092 
01093     cpl_image_delete(image);
01094     
01095     if (cpl_imagelist_get_size(list) != self->size) {
01096         cpl_imagelist_delete(list);
01097         list = NULL;
01098         assert(cpl_error_get_code() != CPL_ERROR_NONE);
01099     }
01100 
01101     return list;
01102 
01103 }
01104 
01105 
01109 /*----------------------------------------------------------------------------*/
01121 /*----------------------------------------------------------------------------*/
01122 static void irplib_framelist_set_size(irplib_framelist * self)
01123 {
01124 
01125 
01126     assert( self != NULL);
01127 
01128     if (self->size == 0) {
01129         /* The list has been emptied */
01130         cpl_free(self->frame);
01131         cpl_free(self->propertylist);
01132         self->frame = NULL;
01133         self->propertylist = NULL;
01134     } else {
01135         /* Update the size of the arrays */
01136 
01137         self->frame = cpl_realloc(self->frame, self->size * sizeof(cpl_frame*));
01138         self->propertylist =
01139             cpl_realloc(self->propertylist,
01140                         self->size * sizeof(cpl_propertylist*));
01141     }
01142 
01143 }
01144 
01145 /*----------------------------------------------------------------------------*/
01169 /*----------------------------------------------------------------------------*/
01170 static cpl_boolean irplib_property_equal(const cpl_propertylist * self,
01171                                          const cpl_propertylist * other,
01172                                          const char * key, cpl_type type,
01173                                          double fp_tol,
01174                                          char ** sstring, char ** ostring)
01175 {
01176 
01177     cpl_boolean equal;
01178 
01179 
01180     assert(self    != NULL);
01181     assert(other   != NULL);
01182     assert(key     != NULL);
01183     assert(sstring != NULL);
01184     assert(ostring != NULL);
01185 
01186     /* FIXME: disable for better performance also with debugging */
01187     assert(cpl_propertylist_get_type(other, key) == type);
01188     assert(fp_tol >= 0.0);
01189 
01190     if (self == other) return CPL_TRUE;
01191 
01192     switch (type) {
01193 
01194     case CPL_TYPE_CHAR: {
01195         const char svalue = cpl_propertylist_get_char(self, key);
01196         const char ovalue = cpl_propertylist_get_char(other, key);
01197 
01198         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01199         if (!equal) {
01200             *sstring = cpl_sprintf("%c", svalue);
01201             *ostring = cpl_sprintf("%c", ovalue);
01202         }
01203         break;
01204     }
01205 
01206     case CPL_TYPE_BOOL: {
01207         const int svalue = cpl_propertylist_get_bool(self, key);
01208         const int ovalue = cpl_propertylist_get_bool(other, key);
01209 
01210         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01211         if (!equal) {
01212             *sstring = cpl_strdup(svalue == 0 ? "F" : "T");
01213             *ostring = cpl_strdup(ovalue == 0 ? "F" : "T");
01214         }
01215         break;
01216     }
01217 
01218     case CPL_TYPE_INT: {
01219         const int svalue = cpl_propertylist_get_int(self, key);
01220         const int ovalue = cpl_propertylist_get_int(other, key);
01221 
01222         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01223         if (!equal) {
01224             *sstring = cpl_sprintf("%d", svalue);
01225             *ostring = cpl_sprintf("%d", ovalue);
01226         }
01227         break;
01228     }
01229 
01230     case CPL_TYPE_LONG: {
01231         const long svalue = cpl_propertylist_get_long(self, key);
01232         const long ovalue = cpl_propertylist_get_long(other, key);
01233 
01234         equal = svalue == ovalue ? CPL_TRUE : CPL_FALSE;
01235         if (!equal) {
01236             *sstring = cpl_sprintf("%ld", svalue);
01237             *ostring = cpl_sprintf("%ld", ovalue);
01238         }
01239         break;
01240     }
01241 
01242     case CPL_TYPE_FLOAT: {
01243         const double svalue = (double)cpl_propertylist_get_float(self, key);
01244         const double ovalue = (double)cpl_propertylist_get_float(other, key);
01245 
01246         equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01247         if (!equal) {
01248             *sstring = cpl_sprintf("%f", svalue);
01249             *ostring = cpl_sprintf("%f", ovalue);
01250         }
01251         break;
01252     }
01253 
01254     case CPL_TYPE_DOUBLE: {
01255         const double svalue = cpl_propertylist_get_double(self, key);
01256         const double ovalue = cpl_propertylist_get_double(other, key);
01257 
01258         equal = (fabs(svalue - ovalue) <= fp_tol) ? CPL_TRUE : CPL_FALSE;
01259         if (!equal) {
01260             *sstring = cpl_sprintf("%g", svalue);
01261             *ostring = cpl_sprintf("%g", ovalue);
01262         }
01263         break;
01264     }
01265     case CPL_TYPE_STRING: {
01266         const char * svalue = cpl_propertylist_get_string(self, key);
01267         const char * ovalue = cpl_propertylist_get_string(other, key);
01268 
01269         equal = strcmp(svalue, ovalue) == 0 ? CPL_TRUE : CPL_FALSE;
01270         if (!equal) {
01271             *sstring = cpl_strdup(svalue);
01272             *ostring = cpl_strdup(ovalue);
01273         }
01274         break;
01275     }
01276     default:
01277         /* Unknown property type */
01278         assert( 0 );
01279 
01280         equal = CPL_FALSE; /* In case of -DNDEBUG */
01281 
01282     }
01283 
01284     if (!equal) {
01285         assert( *sstring != NULL );
01286         assert( *ostring != NULL );
01287     }
01288 
01289     return equal;
01290 
01291 }

Generated on 3 Mar 2013 for SINFONI Pipeline Reference Manual by  doxygen 1.6.1