LCOV - code coverage report
Current view: top level - libavcodec - fitsenc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 46 50 92.0 %
Date: 2017-12-16 01:21:47 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*
       2             :  * FITS image encoder
       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 image encoder
      25             :  *
      26             :  * Specification: https://fits.gsfc.nasa.gov/fits_standard.html Version 3.0
      27             :  *
      28             :  * RGBA images are encoded as planes in RGBA order. So, NAXIS3 is 3 or 4 for them.
      29             :  * Also CTYPE3 = 'RGB ' is added to the header to distinguish them from 3d images.
      30             :  */
      31             : 
      32             : #include "libavutil/intreadwrite.h"
      33             : #include "avcodec.h"
      34             : #include "bytestream.h"
      35             : #include "internal.h"
      36             : 
      37         339 : static int fits_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
      38             :                             const AVFrame *pict, int *got_packet)
      39             : {
      40         339 :     AVFrame * const p = (AVFrame *)pict;
      41             :     uint8_t *bytestream, *bytestream_start, *ptr;
      42         339 :     const uint16_t flip = (1 << 15);
      43         339 :     uint64_t data_size = 0, padded_data_size = 0;
      44         339 :     int ret, bitpix, naxis3 = 1, i, j, k, bytes_left;
      45         339 :     int map[] = {2, 0, 1, 3}; // mapping from GBRA -> RGBA as RGBA is to be stored in FITS file..
      46             : 
      47         339 :     switch (avctx->pix_fmt) {
      48         111 :     case AV_PIX_FMT_GRAY8:
      49             :     case AV_PIX_FMT_GRAY16BE:
      50         111 :         map[0] = 0; // grayscale images should be directly mapped
      51         111 :         if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
      52          56 :             bitpix = 8;
      53             :         } else {
      54          55 :             bitpix = 16;
      55             :         }
      56         111 :         break;
      57         116 :     case AV_PIX_FMT_GBRP:
      58             :     case AV_PIX_FMT_GBRAP:
      59         116 :         bitpix = 8;
      60         116 :         if (avctx->pix_fmt == AV_PIX_FMT_GBRP) {
      61          56 :             naxis3 = 3;
      62             :         } else {
      63          60 :             naxis3 = 4;
      64             :         }
      65         116 :         break;
      66         112 :     case AV_PIX_FMT_GBRP16BE:
      67             :     case AV_PIX_FMT_GBRAP16BE:
      68         112 :         bitpix = 16;
      69         112 :         if (avctx->pix_fmt == AV_PIX_FMT_GBRP16BE) {
      70          56 :             naxis3 = 3;
      71             :         } else {
      72          56 :             naxis3 = 4;
      73             :         }
      74         112 :         break;
      75           0 :     default:
      76           0 :         av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
      77           0 :         return AVERROR(EINVAL);
      78             :     }
      79             : 
      80         339 :     data_size = (bitpix >> 3) * avctx->height * avctx->width * naxis3;
      81         339 :     padded_data_size = ((data_size + 2879) / 2880 ) * 2880;
      82             : 
      83         339 :     if ((ret = ff_alloc_packet2(avctx, pkt, padded_data_size, 0)) < 0)
      84           0 :         return ret;
      85             : 
      86         339 :     bytestream_start =
      87         339 :     bytestream       = pkt->data;
      88             : 
      89        1250 :     for (k = 0; k < naxis3; k++) {
      90      236319 :         for (i = 0; i < avctx->height; i++) {
      91      235408 :             ptr = p->data[map[k]] + (avctx->height - i - 1) * p->linesize[map[k]];
      92      235408 :             if (bitpix == 16) {
      93    40886304 :                 for (j = 0; j < avctx->width; j++) {
      94             :                     // subtracting bzero is equivalent to first bit flip
      95    40768768 :                     bytestream_put_be16(&bytestream, AV_RB16(ptr) ^ flip);
      96    40768768 :                     ptr += 2;
      97             :                 }
      98             :             } else {
      99      117872 :                 memcpy(bytestream, ptr, avctx->width);
     100      117872 :                 bytestream += avctx->width;
     101             :             }
     102             :         }
     103             :     }
     104             : 
     105         339 :     bytes_left = padded_data_size - data_size;
     106         339 :     memset(bytestream, 0, bytes_left);
     107         339 :     bytestream += bytes_left;
     108             : 
     109         339 :     pkt->size   = bytestream - bytestream_start;
     110         339 :     pkt->flags |= AV_PKT_FLAG_KEY;
     111         339 :     *got_packet = 1;
     112             : 
     113         339 :     return 0;
     114             : }
     115             : 
     116             : AVCodec ff_fits_encoder = {
     117             :     .name           = "fits",
     118             :     .long_name      = NULL_IF_CONFIG_SMALL("Flexible Image Transport System"),
     119             :     .type           = AVMEDIA_TYPE_VIDEO,
     120             :     .id             = AV_CODEC_ID_FITS,
     121             :     .encode2        = fits_encode_frame,
     122             :     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_GBRAP16BE,
     123             :                                                      AV_PIX_FMT_GBRP16BE,
     124             :                                                      AV_PIX_FMT_GBRP,
     125             :                                                      AV_PIX_FMT_GBRAP,
     126             :                                                      AV_PIX_FMT_GRAY16BE,
     127             :                                                      AV_PIX_FMT_GRAY8,
     128             :                                                      AV_PIX_FMT_NONE },
     129             : };

Generated by: LCOV version 1.13