LCOV - code coverage report
Current view: top level - libavcodec - fits.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 101 113 89.4 %
Date: 2017-12-16 21:16:39 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :  * FITS implementation of common functions
       3             :  * Copyright (c) 2017 Paras Chadha
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * License as published by the Free Software Foundation; either
      10             :  * version 2.1 of the License, or (at your option) any later version.
      11             :  *
      12             :  * FFmpeg is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with FFmpeg; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : #include "avcodec.h"
      23             : #include "libavutil/dict.h"
      24             : #include "fits.h"
      25             : 
      26         752 : int avpriv_fits_header_init(FITSHeader *header, FITSHeaderState state)
      27             : {
      28         752 :     header->state = state;
      29         752 :     header->naxis_index = 0;
      30         752 :     header->blank_found = 0;
      31         752 :     header->pcount = 0;
      32         752 :     header->gcount = 1;
      33         752 :     header->groups = 0;
      34         752 :     header->rgb = 0;
      35         752 :     header->image_extension = 0;
      36         752 :     header->bscale = 1.0;
      37         752 :     header->bzero = 0;
      38         752 :     header->data_min_found = 0;
      39         752 :     header->data_max_found = 0;
      40         752 :     return 0;
      41             : }
      42             : 
      43        6145 : static int dict_set_if_not_null(AVDictionary ***metadata, char *keyword, char *value)
      44             : {
      45        6145 :     if (metadata)
      46        3159 :         av_dict_set(*metadata, keyword, value, 0);
      47        6145 :     return 0;
      48             : }
      49             : 
      50             : /**
      51             :  * Extract keyword and value from a header line (80 bytes) and store them in keyword and value strings respectively
      52             :  * @param ptr8 pointer to the data
      53             :  * @param keyword pointer to the char array in which keyword is to be stored
      54             :  * @param value pointer to the char array in which value is to be stored
      55             :  * @return 0 if calculated successfully otherwise AVERROR_INVALIDDATA
      56             :  */
      57        7208 : static int read_keyword_value(const uint8_t *ptr8, char *keyword, char *value)
      58             : {
      59             :     int i;
      60             : 
      61       47686 :     for (i = 0; i < 8 && ptr8[i] != ' '; i++) {
      62       40478 :         keyword[i] = ptr8[i];
      63             :     }
      64        7208 :     keyword[i] = '\0';
      65             : 
      66        7208 :     if (ptr8[8] == '=') {
      67        6323 :         i = 10;
      68       17131 :         while (i < 80 && ptr8[i] == ' ') {
      69        4485 :             i++;
      70             :         }
      71             : 
      72        6323 :         if (i < 80) {
      73        6323 :             *value++ = ptr8[i];
      74        6323 :             i++;
      75        6323 :             if (ptr8[i-1] == '\'') {
      76       12213 :                 for (; i < 80 && ptr8[i] != '\''; i++) {
      77       11114 :                     *value++ = ptr8[i];
      78             :                 }
      79        1099 :                 *value++ = '\'';
      80        5224 :             } else if (ptr8[i-1] == '(') {
      81           0 :                 for (; i < 80 && ptr8[i] != ')'; i++) {
      82           0 :                     *value++ = ptr8[i];
      83             :                 }
      84           0 :                 *value++ = ')';
      85             :             } else {
      86       10947 :                 for (; i < 80 && ptr8[i] != ' ' && ptr8[i] != '/'; i++) {
      87        5723 :                     *value++ = ptr8[i];
      88             :                 }
      89             :             }
      90             :         }
      91             :     }
      92        7208 :     *value = '\0';
      93        7208 :     return 0;
      94             : }
      95             : 
      96             : #define CHECK_KEYWORD(key) \
      97             :     if (strcmp(keyword, key)) { \
      98             :         av_log(avcl, AV_LOG_ERROR, "expected %s keyword, found %s = %s\n", key, keyword, value); \
      99             :         return AVERROR_INVALIDDATA; \
     100             :     }
     101             : 
     102             : #define CHECK_VALUE(key, val) \
     103             :     if (sscanf(value, "%d", &header->val) != 1) { \
     104             :         av_log(avcl, AV_LOG_ERROR, "invalid value of %s keyword, %s = %s\n", key, keyword, value); \
     105             :         return AVERROR_INVALIDDATA; \
     106             :     }
     107             : 
     108        7208 : int avpriv_fits_header_parse_line(void *avcl, FITSHeader *header, const uint8_t line[80], AVDictionary ***metadata)
     109             : {
     110             :     int dim_no, ret;
     111             :     int64_t t;
     112             :     double d;
     113             :     char keyword[10], value[72], c;
     114             : 
     115        7208 :     read_keyword_value(line, keyword, value);
     116        7208 :     switch (header->state) {
     117          22 :     case STATE_SIMPLE:
     118          22 :         CHECK_KEYWORD("SIMPLE");
     119             : 
     120          22 :         if (value[0] == 'F') {
     121           0 :             av_log(avcl, AV_LOG_WARNING, "not a standard FITS file\n");
     122          22 :         } else if (value[0] != 'T') {
     123           0 :             av_log(avcl, AV_LOG_ERROR, "invalid value of SIMPLE keyword, SIMPLE = %c\n", value[0]);
     124           0 :             return AVERROR_INVALIDDATA;
     125             :         }
     126             : 
     127          22 :         header->state = STATE_BITPIX;
     128          22 :         break;
     129         327 :     case STATE_XTENSION:
     130         327 :         CHECK_KEYWORD("XTENSION");
     131             : 
     132         327 :         if (!strcmp(value, "'IMAGE   '")) {
     133         326 :             header->image_extension = 1;
     134             :         }
     135             : 
     136         327 :         header->state = STATE_BITPIX;
     137         327 :         break;
     138         714 :     case STATE_BITPIX:
     139         714 :         CHECK_KEYWORD("BITPIX");
     140         714 :         CHECK_VALUE("BITPIX", bitpix);
     141         714 :         dict_set_if_not_null(metadata, keyword, value);
     142             : 
     143         714 :         header->state = STATE_NAXIS;
     144         714 :         break;
     145         714 :     case STATE_NAXIS:
     146         714 :         CHECK_KEYWORD("NAXIS");
     147         714 :         CHECK_VALUE("NAXIS", naxis);
     148         714 :         dict_set_if_not_null(metadata, keyword, value);
     149             : 
     150         714 :         if (header->naxis) {
     151         714 :             header->state = STATE_NAXIS_N;
     152             :         } else {
     153           0 :             header->state = STATE_REST;
     154             :         }
     155         714 :         break;
     156        1924 :     case STATE_NAXIS_N:
     157        1924 :         ret = sscanf(keyword, "NAXIS%d", &dim_no);
     158        1924 :         if (ret != 1 || dim_no != header->naxis_index + 1) {
     159           0 :             av_log(avcl, AV_LOG_ERROR, "expected NAXIS%d keyword, found %s = %s\n", header->naxis_index + 1, keyword, value);
     160           0 :             return AVERROR_INVALIDDATA;
     161             :         }
     162             : 
     163        1924 :         if (sscanf(value, "%d", &header->naxisn[header->naxis_index]) != 1) {
     164           0 :             av_log(avcl, AV_LOG_ERROR, "invalid value of NAXIS%d keyword, %s = %s\n", header->naxis_index + 1, keyword, value);
     165           0 :             return AVERROR_INVALIDDATA;
     166             :         }
     167             : 
     168        1924 :         dict_set_if_not_null(metadata, keyword, value);
     169        1924 :         header->naxis_index++;
     170        1924 :         if (header->naxis_index == header->naxis) {
     171         714 :             header->state = STATE_REST;
     172             :         }
     173        1924 :         break;
     174        3507 :     case STATE_REST:
     175        3507 :         if (!strcmp(keyword, "BLANK") && sscanf(value, "%"SCNd64"", &t) == 1) {
     176           3 :             header->blank = t;
     177           3 :             header->blank_found = 1;
     178        3504 :         } else if (!strcmp(keyword, "BSCALE") && sscanf(value, "%lf", &d) == 1) {
     179           6 :             header->bscale = d;
     180        3498 :         } else if (!strcmp(keyword, "BZERO") && sscanf(value, "%lf", &d) == 1) {
     181         315 :             header->bzero = d;
     182        3183 :         } else if (!strcmp(keyword, "CTYPE3") && !strncmp(value, "'RGB", 4)) {
     183         496 :             header->rgb = 1;
     184        2687 :         } else if (!strcmp(keyword, "DATAMAX") && sscanf(value, "%lf", &d) == 1) {
     185           3 :             header->data_max_found = 1;
     186           3 :             header->data_max = d;
     187        2684 :         } else if (!strcmp(keyword, "DATAMIN") && sscanf(value, "%lf", &d) == 1) {
     188           3 :             header->data_min_found = 1;
     189           3 :             header->data_min = d;
     190        2681 :         } else if (!strcmp(keyword, "END")) {
     191         714 :             return 1;
     192        1967 :         } else if (!strcmp(keyword, "GROUPS") && sscanf(value, "%c", &c) == 1) {
     193           0 :             header->groups = (c == 'T');
     194        1967 :         } else if (!strcmp(keyword, "GCOUNT") && sscanf(value, "%"SCNd64"", &t) == 1) {
     195         649 :             header->gcount = t;
     196        1318 :         } else if (!strcmp(keyword, "PCOUNT") && sscanf(value, "%"SCNd64"", &t) == 1) {
     197         649 :             header->pcount = t;
     198             :         }
     199        2793 :         dict_set_if_not_null(metadata, keyword, value);
     200        2793 :         break;
     201             :     }
     202        6494 :     return 0;
     203             : }

Generated by: LCOV version 1.13