LCOV - code coverage report
Current view: top level - libavformat - fitsenc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 88 91 96.7 %
Date: 2017-12-12 11:08:38 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :  * FITS muxer
       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             : /**
      23             :  * @file
      24             :  * FITS muxer.
      25             :  */
      26             : 
      27             : #include "internal.h"
      28             : 
      29             : typedef struct FITSContext {
      30             :     int first_image;
      31             : } FITSContext;
      32             : 
      33          11 : static int fits_write_header(AVFormatContext *s)
      34             : {
      35          11 :     FITSContext *fitsctx = s->priv_data;
      36          11 :     fitsctx->first_image = 1;
      37          11 :     return 0;
      38             : }
      39             : 
      40             : /**
      41             :  * Write one header line comprising of keyword and value(int)
      42             :  * @param s AVFormat Context
      43             :  * @param keyword pointer to the char array in which keyword is stored
      44             :  * @param value the value corresponding to the keyword
      45             :  * @param lines_written to keep track of lines written so far
      46             :  * @return 0
      47             :  */
      48        2192 : static int write_keyword_value(AVFormatContext *s, const char *keyword, int value, int *lines_written)
      49             : {
      50             :     int len, ret;
      51             :     uint8_t header[80];
      52             : 
      53        2192 :     len = strlen(keyword);
      54        2192 :     memset(header, ' ', sizeof(header));
      55        2192 :     memcpy(header, keyword, len);
      56             : 
      57        2192 :     header[8] = '=';
      58        2192 :     header[9] = ' ';
      59             : 
      60        2192 :     ret = snprintf(header + 10, 70, "%d", value);
      61        2192 :     memset(&header[ret + 10], ' ', sizeof(header) - (ret + 10));
      62             : 
      63        2192 :     avio_write(s->pb, header, sizeof(header));
      64        2192 :     *lines_written += 1;
      65        2192 :     return 0;
      66             : }
      67             : 
      68         309 : static int write_image_header(AVFormatContext *s)
      69             : {
      70         309 :     AVStream *st = s->streams[0];
      71         309 :     AVCodecParameters *encctx = st->codecpar;
      72         309 :     FITSContext *fitsctx = s->priv_data;
      73             :     uint8_t buffer[80];
      74         309 :     int bitpix, naxis, naxis3 = 1, bzero = 0, rgb = 0, lines_written = 0, lines_left;
      75             : 
      76         309 :     switch (encctx->format) {
      77          51 :         case AV_PIX_FMT_GRAY8:
      78          51 :             bitpix = 8;
      79          51 :             naxis = 2;
      80          51 :             break;
      81          50 :         case AV_PIX_FMT_GRAY16BE:
      82          50 :             bitpix = 16;
      83          50 :             naxis = 2;
      84          50 :             bzero = 32768;
      85          50 :             break;
      86         106 :         case AV_PIX_FMT_GBRP:
      87             :         case AV_PIX_FMT_GBRAP:
      88         106 :             bitpix = 8;
      89         106 :             naxis = 3;
      90         106 :             rgb = 1;
      91         106 :             if (encctx->format == AV_PIX_FMT_GBRP) {
      92          51 :                 naxis3 = 3;
      93             :             } else {
      94          55 :                 naxis3 = 4;
      95             :             }
      96         106 :             break;
      97         102 :         case AV_PIX_FMT_GBRP16BE:
      98             :         case AV_PIX_FMT_GBRAP16BE:
      99         102 :             bitpix = 16;
     100         102 :             naxis = 3;
     101         102 :             rgb = 1;
     102         102 :             if (encctx->format == AV_PIX_FMT_GBRP16BE) {
     103          51 :                 naxis3 = 3;
     104             :             } else {
     105          51 :                 naxis3 = 4;
     106             :             }
     107         102 :             bzero = 32768;
     108         102 :             break;
     109           0 :         default:
     110           0 :             return AVERROR(EINVAL);
     111             :     }
     112             : 
     113         309 :     if (fitsctx->first_image) {
     114          11 :         memcpy(buffer, "SIMPLE  = ", 10);
     115          11 :         memset(buffer + 10, ' ', 70);
     116          11 :         buffer[29] = 'T';
     117          11 :         avio_write(s->pb, buffer, sizeof(buffer));
     118             :     } else {
     119         298 :         memcpy(buffer, "XTENSION= 'IMAGE   '", 20);
     120         298 :         memset(buffer + 20, ' ', 60);
     121         298 :         avio_write(s->pb, buffer, sizeof(buffer));
     122             :     }
     123         309 :     lines_written++;
     124             : 
     125         309 :     write_keyword_value(s, "BITPIX", bitpix, &lines_written);         // no of bits per pixel
     126         309 :     write_keyword_value(s, "NAXIS", naxis, &lines_written);           // no of dimensions of image
     127         309 :     write_keyword_value(s, "NAXIS1", encctx->width, &lines_written);   // first dimension i.e. width
     128         309 :     write_keyword_value(s, "NAXIS2", encctx->height, &lines_written);  // second dimension i.e. height
     129             : 
     130         309 :     if (rgb)
     131         208 :         write_keyword_value(s, "NAXIS3", naxis3, &lines_written);     // third dimension to store RGBA planes
     132             : 
     133         309 :     if (!fitsctx->first_image) {
     134         298 :         write_keyword_value(s, "PCOUNT", 0, &lines_written);
     135         298 :         write_keyword_value(s, "GCOUNT", 1, &lines_written);
     136             :     } else {
     137          11 :         fitsctx->first_image = 0;
     138             :     }
     139             : 
     140             :     /*
     141             :      * Since FITS does not support unsigned 16 bit integers,
     142             :      * BZERO = 32768 is used to store unsigned 16 bit integers as
     143             :      * signed integers so that it can be read properly.
     144             :      */
     145         309 :     if (bitpix == 16)
     146         152 :         write_keyword_value(s, "BZERO", bzero, &lines_written);
     147             : 
     148         309 :     if (rgb) {
     149         208 :         memcpy(buffer, "CTYPE3  = 'RGB     '", 20);
     150         208 :         memset(buffer + 20, ' ', 60);
     151         208 :         avio_write(s->pb, buffer, sizeof(buffer));
     152         208 :         lines_written++;
     153             :     }
     154             : 
     155         309 :     memcpy(buffer, "END", 3);
     156         309 :     memset(buffer + 3, ' ', 77);
     157         309 :     avio_write(s->pb, buffer, sizeof(buffer));
     158         309 :     lines_written++;
     159             : 
     160         309 :     lines_left = ((lines_written + 35) / 36) * 36 - lines_written;
     161         309 :     memset(buffer, ' ', 80);
     162        8724 :     while (lines_left > 0) {
     163        8106 :         avio_write(s->pb, buffer, sizeof(buffer));
     164        8106 :         lines_left--;
     165             :     }
     166         309 :     return 0;
     167             : }
     168             : 
     169         309 : static int fits_write_packet(AVFormatContext *s, AVPacket *pkt)
     170             : {
     171         309 :     int ret = write_image_header(s);
     172         309 :     if (ret < 0)
     173           0 :         return ret;
     174         309 :     avio_write(s->pb, pkt->data, pkt->size);
     175         309 :     return 0;
     176             : }
     177             : 
     178             : AVOutputFormat ff_fits_muxer = {
     179             :     .name         = "fits",
     180             :     .long_name    = NULL_IF_CONFIG_SMALL("Flexible Image Transport System"),
     181             :     .extensions   = "fits",
     182             :     .priv_data_size = sizeof(FITSContext),
     183             :     .audio_codec  = AV_CODEC_ID_NONE,
     184             :     .video_codec  = AV_CODEC_ID_FITS,
     185             :     .write_header = fits_write_header,
     186             :     .write_packet = fits_write_packet,
     187             : };

Generated by: LCOV version 1.13