FFmpeg  4.0
fitsenc.c
Go to the documentation of this file.
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 
38  const AVFrame *pict, int *got_packet)
39 {
40  AVFrame * const p = (AVFrame *)pict;
41  uint8_t *bytestream, *bytestream_start, *ptr;
42  const uint16_t flip = (1 << 15);
43  uint64_t data_size = 0, padded_data_size = 0;
44  int ret, bitpix, naxis3 = 1, i, j, k, bytes_left;
45  int map[] = {2, 0, 1, 3}; // mapping from GBRA -> RGBA as RGBA is to be stored in FITS file..
46 
47  switch (avctx->pix_fmt) {
48  case AV_PIX_FMT_GRAY8:
50  map[0] = 0; // grayscale images should be directly mapped
51  if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
52  bitpix = 8;
53  } else {
54  bitpix = 16;
55  }
56  break;
57  case AV_PIX_FMT_GBRP:
58  case AV_PIX_FMT_GBRAP:
59  bitpix = 8;
60  if (avctx->pix_fmt == AV_PIX_FMT_GBRP) {
61  naxis3 = 3;
62  } else {
63  naxis3 = 4;
64  }
65  break;
68  bitpix = 16;
69  if (avctx->pix_fmt == AV_PIX_FMT_GBRP16BE) {
70  naxis3 = 3;
71  } else {
72  naxis3 = 4;
73  }
74  break;
75  default:
76  av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
77  return AVERROR(EINVAL);
78  }
79 
80  data_size = (bitpix >> 3) * avctx->height * avctx->width * naxis3;
81  padded_data_size = ((data_size + 2879) / 2880 ) * 2880;
82 
83  if ((ret = ff_alloc_packet2(avctx, pkt, padded_data_size, 0)) < 0)
84  return ret;
85 
86  bytestream_start =
87  bytestream = pkt->data;
88 
89  for (k = 0; k < naxis3; k++) {
90  for (i = 0; i < avctx->height; i++) {
91  ptr = p->data[map[k]] + (avctx->height - i - 1) * p->linesize[map[k]];
92  if (bitpix == 16) {
93  for (j = 0; j < avctx->width; j++) {
94  // subtracting bzero is equivalent to first bit flip
95  bytestream_put_be16(&bytestream, AV_RB16(ptr) ^ flip);
96  ptr += 2;
97  }
98  } else {
99  memcpy(bytestream, ptr, avctx->width);
100  bytestream += avctx->width;
101  }
102  }
103  }
104 
105  bytes_left = padded_data_size - data_size;
106  memset(bytestream, 0, bytes_left);
107  bytestream += bytes_left;
108 
109  pkt->size = bytestream - bytestream_start;
110  pkt->flags |= AV_PKT_FLAG_KEY;
111  *got_packet = 1;
112 
113  return 0;
114 }
115 
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,
128  AV_PIX_FMT_NONE },
129 };
This structure describes decoded (raw) audio or video data.
Definition: frame.h:218
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:164
int size
Definition: avcodec.h:1431
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1727
static AVPacket pkt
AVCodec.
Definition: avcodec.h:3408
planar GBRA 4:4:4:4 64bpp, big-endian
Definition: pixfmt.h:212
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size)
Check AVPacket size and/or allocate data.
Definition: encode.c:32
uint8_t
uint8_t * data
Definition: avcodec.h:1430
planar GBR 4:4:4 48bpp, big-endian
Definition: pixfmt.h:170
#define av_log(a,...)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1462
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AV_RB16
Definition: intreadwrite.h:53
static void flip(AVCodecContext *avctx, AVFrame *frame)
Definition: rawdec.c:136
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
const char * name
Name of the codec implementation.
Definition: avcodec.h:3415
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1436
int width
picture width / height.
Definition: avcodec.h:1690
AVCodec ff_fits_encoder
Definition: fitsenc.c:116
if(ret< 0)
Definition: vf_mcdeint.c:279
static int fits_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
Definition: fitsenc.c:37
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:249
main external API structure.
Definition: avcodec.h:1518
Y , 16bpp, big-endian.
Definition: pixfmt.h:93
const VDPAUPixFmtMap * map
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:232
Y , 8bpp.
Definition: pixfmt.h:70
common internal api header.
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:211
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
This structure stores compressed data.
Definition: avcodec.h:1407