[FFmpeg-devel] [PATCH] Add FITS Decoder
Paras Chadha
paraschadha18 at gmail.com
Fri Jun 9 20:16:02 EEST 2017
On Fri, Jun 9, 2017 at 4:19 PM, Michael Niedermayer <michael at niedermayer.cc>
wrote:
> On Thu, Jun 08, 2017 at 10:34:15PM +0530, Paras Chadha wrote:
> > It supports all 2-d images alongwith bzero, bscale and blank keywords.
> > RGBA images are supported as NAXIS3 = 3 or 4 i.e. Planes in RGBA order.
> Also CTYPE = 'RGB ' should be present.
> > It currently does not support XTENSION keyword.
> >
> > Signed-off-by: Paras Chadha <paraschadha18 at gmail.com>
> > ---
> > Changelog | 1 +
> > doc/general.texi | 2 +
> > libavcodec/Makefile | 1 +
> > libavcodec/allcodecs.c | 1 +
> > libavcodec/avcodec.h | 1 +
> > libavcodec/codec_desc.c | 8 +
> > libavcodec/fitsdec.c | 527 ++++++++++++++++++++++++++++++
> +++++++++++++++++
> > libavcodec/version.h | 4 +-
> > libavformat/Makefile | 1 +
> > libavformat/allformats.c | 1 +
> > libavformat/img2.c | 1 +
> > libavformat/img2dec.c | 10 +
> > 12 files changed, 556 insertions(+), 2 deletions(-)
> > create mode 100644 libavcodec/fitsdec.c
> [...]
> > +/**
> > + * function reads the fits header and stores the values in fits_header
> pointed by header
> > + * @param avctx - AVCodec context
> > + * @param ptr - pointer to pointer to the data
> > + * @param header - pointer to the fits_header
> > + * @param end - pointer to end of packet
> > + * @return 1, if calculated successfully, otherwise AVERROR_INVALIDDATA
> > + */
> > +static int fits_read_header(AVCodecContext *avctx, const uint8_t
> **ptr, fits_header * header, const uint8_t * end)
> > +{
> > + const uint8_t *ptr8 = *ptr;
> > + int lines_read = 0, i, dim_no, t, data_min_found = 0,
> data_max_found = 0, ret;
> > + uint64_t size=1;
> > + char str_val[80];
> > + double d;
> > +
> > + header->blank = 0;
> > + header->bscale = 1.0;
> > + header->bzero = 0;
> > + header->rgb = 0;
> > +
> > + if (end - ptr8 < 80)
> > + return AVERROR_INVALIDDATA;
> > +
> > + if (sscanf(ptr8, "SIMPLE = %c", &header->simple) != 1) {
> > + av_log(avctx, AV_LOG_ERROR, "missing SIMPLE keyword\n");
> > + return AVERROR_INVALIDDATA;
> > + }
> > +
> > + if (header->simple == 'F')
> > + av_log(avctx, AV_LOG_WARNING, "not a standard FITS file\n");
> > + else if (header->simple != 'T') {
> > + av_log(avctx, AV_LOG_ERROR, "invalid SIMPLE value, SIMPLE =
> %c\n", header->simple);
> > + return AVERROR_INVALIDDATA;
> > + }
> > +
> > + ptr8 += 80;
> > + lines_read++;
> > +
> > + if (end - ptr8 < 80)
> > + return AVERROR_INVALIDDATA;
> > +
> > + if (sscanf(ptr8, "BITPIX = %d", &header->bitpix) != 1) {
> > + av_log(avctx, AV_LOG_ERROR, "missing BITPIX keyword\n");
> > + return AVERROR_INVALIDDATA;
> > + }
> > +
> > + size = abs(header->bitpix) / 8;
> > + ptr8 += 80;
> > + lines_read++;
> > +
> > + if (end - ptr8 < 80)
> > + return AVERROR_INVALIDDATA;
> > +
> > + if (sscanf(ptr8, "NAXIS = %d", &header->naxis) != 1) {
> > + av_log(avctx, AV_LOG_ERROR, "missing NAXIS keyword\n");
> > + return AVERROR_INVALIDDATA;
> > + }
> > +
> > + if (header->naxis == 0) {
> > + av_log(avctx, AV_LOG_ERROR, "No image data found, NAXIS =
> %d\n", header->naxis);
> > + return AVERROR_INVALIDDATA;
> > + }
> > +
> > + if (header->naxis != 2 && header->naxis != 3) {
> > + av_log(avctx, AV_LOG_ERROR, "unsupported number of dimensions,
> NAXIS = %d\n", header->naxis);
> > + return AVERROR_INVALIDDATA;
> > + }
> > +
> > + ptr8 += 80;
> > + lines_read++;
> > +
> > + for (i = 0; i < header->naxis; i++) {
> > + if (end - ptr8 < 80)
> > + return AVERROR_INVALIDDATA;
> > +
> > + if (sscanf(ptr8, "NAXIS%d = %d", &dim_no, &header->naxisn[i])
> != 2 || dim_no != i+1) {
> > + av_log(avctx, AV_LOG_ERROR, "missing NAXIS%d keyword\n",
> i+1);
> > + return AVERROR_INVALIDDATA;
> > + }
> > +
> > + size *= header->naxisn[i];
> > + ptr8 += 80;
> > + lines_read++;
> > + }
> > +
> > + if (end - ptr8 < 80)
> > + return AVERROR_INVALIDDATA;
> > +
> > + while (strncmp(ptr8, "END", 3)) {
> > + if (sscanf(ptr8, "BLANK = %d", &t) == 1)
> > + header->blank = t;
> > + else if (sscanf(ptr8, "BSCALE = %lf", &d) == 1)
> > + header->bscale = d;
> > + else if (sscanf(ptr8, "BZERO = %lf", &d) == 1)
> > + header->bzero = d;
> > + else if (sscanf(ptr8, "DATAMAX = %lf", &d) == 1) {
> > + data_max_found = 1;
> > + header->data_max = d;
> > + }
> > + else if (sscanf(ptr8, "DATAMIN = %lf", &d) == 1) {
> > + data_min_found = 1;
> > + header->data_min = d;
> > + }
>
> > + else if (sscanf(ptr8, "CTYPE3 = '%s '", str_val) == 1) {
>
> what prevents a buffer overflow here ?
>
Yes you are right. I have provided an alternative code in latest patch
which prevents buffer overflow.
>
> [...]
> > +
> > +static int fits_decode_frame(AVCodecContext *avctx, void *data, int
> *got_frame, AVPacket *avpkt)
> > +{
> > + AVFrame *p=data;
> > + const uint8_t *ptr8 = avpkt->data, *end;
> > + int16_t t16;
> > + int32_t t32;
> > + int64_t t64;
> > + float tflt;
> > + double tdbl;
> > + int ret, i, j;
> > + uint8_t *dst8;
> > + uint16_t *dst16;
> > + uint32_t *dst32;
> > + uint64_t *dst64, size, r, g, b, a, t;
> > + fits_header header;
> > +
> > + end = ptr8 + avpkt->size;
>
> > + if ((ret = fits_read_header(avctx, &ptr8, &header, end) < 0))
>
> wrongly placed ()
>
Fixed
>
>
> [...]
> --
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> Take away the freedom of one citizen and you will be jailed, take away
> the freedom of all citizens and you will be congratulated by your peers
> in Parliament.
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>
More information about the ffmpeg-devel
mailing list