LCOV - code coverage report
Current view: top level - libavcodec - dpx.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 155 250 62.0 %
Date: 2017-12-15 18:13:28 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :  * DPX (.dpx) image decoder
       3             :  * Copyright (c) 2009 Jimmy Christensen
       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 "libavutil/intreadwrite.h"
      23             : #include "libavutil/intfloat.h"
      24             : #include "libavutil/imgutils.h"
      25             : #include "bytestream.h"
      26             : #include "avcodec.h"
      27             : #include "internal.h"
      28             : 
      29     4257974 : static unsigned int read16(const uint8_t **ptr, int is_big)
      30             : {
      31             :     unsigned int temp;
      32     4257974 :     if (is_big) {
      33           4 :         temp = AV_RB16(*ptr);
      34             :     } else {
      35     4257970 :         temp = AV_RL16(*ptr);
      36             :     }
      37     4257974 :     *ptr += 2;
      38     4257974 :     return temp;
      39             : }
      40             : 
      41     2839076 : static unsigned int read32(const uint8_t **ptr, int is_big)
      42             : {
      43             :     unsigned int temp;
      44     2839076 :     if (is_big) {
      45          14 :         temp = AV_RB32(*ptr);
      46             :     } else {
      47     2839062 :         temp = AV_RL32(*ptr);
      48             :     }
      49     2839076 :     *ptr += 4;
      50     2839076 :     return temp;
      51             : }
      52             : 
      53     8515584 : static uint16_t read10in32(const uint8_t **ptr, uint32_t * lbuf,
      54             :                                   int * n_datum, int is_big)
      55             : {
      56     8515584 :     if (*n_datum)
      57     5677056 :         (*n_datum)--;
      58             :     else {
      59     2838528 :         *lbuf = read32(ptr, is_big);
      60     2838528 :         *n_datum = 2;
      61             :     }
      62             : 
      63     8515584 :     *lbuf = (*lbuf << 10) | (*lbuf >> 22);
      64             : 
      65     8515584 :     return *lbuf & 0x3FF;
      66             : }
      67             : 
      68          91 : static int decode_frame(AVCodecContext *avctx,
      69             :                         void *data,
      70             :                         int *got_frame,
      71             :                         AVPacket *avpkt)
      72             : {
      73          91 :     const uint8_t *buf = avpkt->data;
      74          91 :     int buf_size       = avpkt->size;
      75          91 :     AVFrame *const p = data;
      76             :     uint8_t *ptr[AV_NUM_DATA_POINTERS];
      77             : 
      78             :     unsigned int offset;
      79             :     int magic_num, endian;
      80             :     int x, y, stride, i, ret;
      81             :     int w, h, bits_per_color, descriptor, elements, packing;
      82          91 :     int encoding, need_align = 0;
      83             : 
      84          91 :     unsigned int rgbBuffer = 0;
      85          91 :     int n_datum = 0;
      86             : 
      87          91 :     if (avpkt->size <= 1634) {
      88           0 :         av_log(avctx, AV_LOG_ERROR, "Packet too small for DPX header\n");
      89           0 :         return AVERROR_INVALIDDATA;
      90             :     }
      91             : 
      92          91 :     magic_num = AV_RB32(buf);
      93          91 :     buf += 4;
      94             : 
      95             :     /* Check if the files "magic number" is "SDPX" which means it uses
      96             :      * big-endian or XPDS which is for little-endian files */
      97          91 :     if (magic_num == AV_RL32("SDPX")) {
      98          89 :         endian = 0;
      99           2 :     } else if (magic_num == AV_RB32("SDPX")) {
     100           2 :         endian = 1;
     101             :     } else {
     102           0 :         av_log(avctx, AV_LOG_ERROR, "DPX marker not found\n");
     103           0 :         return AVERROR_INVALIDDATA;
     104             :     }
     105             : 
     106          91 :     offset = read32(&buf, endian);
     107          91 :     if (avpkt->size <= offset) {
     108           0 :         av_log(avctx, AV_LOG_ERROR, "Invalid data start offset\n");
     109           0 :         return AVERROR_INVALIDDATA;
     110             :     }
     111             : 
     112             :     // Check encryption
     113          91 :     buf = avpkt->data + 660;
     114          91 :     ret = read32(&buf, endian);
     115          91 :     if (ret != 0xFFFFFFFF) {
     116           0 :         avpriv_report_missing_feature(avctx, "Encryption");
     117           0 :         av_log(avctx, AV_LOG_WARNING, "The image is encrypted and may "
     118             :                "not properly decode.\n");
     119             :     }
     120             : 
     121             :     // Need to end in 0x304 offset from start of file
     122          91 :     buf = avpkt->data + 0x304;
     123          91 :     w = read32(&buf, endian);
     124          91 :     h = read32(&buf, endian);
     125             : 
     126          91 :     if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
     127           0 :         return ret;
     128             : 
     129             :     // Need to end in 0x320 to read the descriptor
     130          91 :     buf += 20;
     131          91 :     descriptor = buf[0];
     132             : 
     133             :     // Need to end in 0x323 to read the bits per color
     134          91 :     buf += 3;
     135          91 :     avctx->bits_per_raw_sample =
     136          91 :     bits_per_color = buf[0];
     137          91 :     buf++;
     138          91 :     packing = read16(&buf, endian);
     139          91 :     encoding = read16(&buf, endian);
     140             : 
     141          91 :     if (packing > 1) {
     142           0 :         avpriv_report_missing_feature(avctx, "Packing %d", packing);
     143           0 :         return AVERROR_PATCHWELCOME;
     144             :     }
     145          91 :     if (encoding) {
     146           0 :         avpriv_report_missing_feature(avctx, "Encoding %d", encoding);
     147           0 :         return AVERROR_PATCHWELCOME;
     148             :     }
     149             : 
     150          91 :     buf += 820;
     151          91 :     avctx->sample_aspect_ratio.num = read32(&buf, endian);
     152          91 :     avctx->sample_aspect_ratio.den = read32(&buf, endian);
     153          91 :     if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0)
     154           0 :         av_reduce(&avctx->sample_aspect_ratio.num, &avctx->sample_aspect_ratio.den,
     155           0 :                    avctx->sample_aspect_ratio.num,  avctx->sample_aspect_ratio.den,
     156             :                   0x10000);
     157             :     else
     158          91 :         avctx->sample_aspect_ratio = (AVRational){ 0, 1 };
     159             : 
     160          91 :     if (offset >= 1724 + 4) {
     161           2 :         buf = avpkt->data + 1724;
     162           2 :         i = read32(&buf, endian);
     163           2 :         if(i) {
     164           0 :             AVRational q = av_d2q(av_int2float(i), 4096);
     165           0 :             if (q.num > 0 && q.den > 0)
     166           0 :                 avctx->framerate = q;
     167             :         }
     168             :     }
     169             : 
     170          91 :     switch (descriptor) {
     171           0 :     case 6:  // Y
     172           0 :         elements = 1;
     173           0 :         break;
     174          14 :     case 52: // ABGR
     175             :     case 51: // RGBA
     176             :     case 103: // UYVA4444
     177          14 :         elements = 4;
     178          14 :         break;
     179          77 :     case 50: // RGB
     180             :     case 102: // UYV444
     181          77 :         elements = 3;
     182          77 :         break;
     183           0 :     case 100: // UYVY422
     184           0 :         elements = 2;
     185           0 :         break;
     186           0 :     default:
     187           0 :         avpriv_report_missing_feature(avctx, "Descriptor %d", descriptor);
     188           0 :         return AVERROR_PATCHWELCOME;
     189             :     }
     190             : 
     191          91 :     switch (bits_per_color) {
     192          19 :     case 8:
     193          19 :         stride = avctx->width * elements;
     194          19 :         break;
     195          28 :     case 10:
     196          28 :         if (!packing) {
     197           0 :             av_log(avctx, AV_LOG_ERROR, "Packing to 32bit required\n");
     198           0 :             return -1;
     199             :         }
     200          28 :         stride = (avctx->width * elements + 2) / 3 * 4;
     201          28 :         break;
     202          14 :     case 12:
     203          14 :         if (!packing) {
     204           0 :             av_log(avctx, AV_LOG_ERROR, "Packing to 16bit required\n");
     205           0 :             return -1;
     206             :         }
     207          14 :         stride = 2 * avctx->width * elements;
     208          14 :         break;
     209          30 :     case 16:
     210          30 :         stride = 2 * avctx->width * elements;
     211          30 :         break;
     212           0 :     case 1:
     213             :     case 32:
     214             :     case 64:
     215           0 :         avpriv_report_missing_feature(avctx, "Depth %d", bits_per_color);
     216           0 :         return AVERROR_PATCHWELCOME;
     217           0 :     default:
     218           0 :         return AVERROR_INVALIDDATA;
     219             :     }
     220             : 
     221             :     // Table 3c: Runs will always break at scan line boundaries. Packing
     222             :     // will always break to the next 32-bit word at scan-line boundaries.
     223             :     // Unfortunately, the encoder produced invalid files, so attempt
     224             :     // to detect it
     225          91 :     need_align = FFALIGN(stride, 4);
     226          91 :     if (need_align*avctx->height + (int64_t)offset > avpkt->size) {
     227             :         // Alignment seems unappliable, try without
     228           0 :         if (stride*avctx->height + (int64_t)offset > avpkt->size) {
     229           0 :             av_log(avctx, AV_LOG_ERROR, "Overread buffer. Invalid header?\n");
     230           0 :             return AVERROR_INVALIDDATA;
     231             :         } else {
     232           0 :             av_log(avctx, AV_LOG_INFO, "Decoding DPX without scanline "
     233             :                    "alignment.\n");
     234           0 :             need_align = 0;
     235             :         }
     236             :     } else {
     237          91 :         need_align -= stride;
     238          91 :         stride = FFALIGN(stride, 4);
     239             :     }
     240             : 
     241          91 :     switch (1000 * descriptor + 10 * bits_per_color + endian) {
     242           0 :     case 6081:
     243             :     case 6080:
     244           0 :         avctx->pix_fmt = AV_PIX_FMT_GRAY8;
     245           0 :         break;
     246           0 :     case 6121:
     247             :     case 6120:
     248           0 :         avctx->pix_fmt = AV_PIX_FMT_GRAY12;
     249           0 :         break;
     250          19 :     case 50081:
     251             :     case 50080:
     252          19 :         avctx->pix_fmt = AV_PIX_FMT_RGB24;
     253          19 :         break;
     254           0 :     case 52081:
     255             :     case 52080:
     256           0 :         avctx->pix_fmt = AV_PIX_FMT_ABGR;
     257           0 :         break;
     258           0 :     case 51081:
     259             :     case 51080:
     260           0 :         avctx->pix_fmt = AV_PIX_FMT_RGBA;
     261           0 :         break;
     262          28 :     case 50100:
     263             :     case 50101:
     264          28 :         avctx->pix_fmt = AV_PIX_FMT_GBRP10;
     265          28 :         break;
     266           0 :     case 51100:
     267             :     case 51101:
     268           0 :         avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
     269           0 :         break;
     270          14 :     case 50120:
     271             :     case 50121:
     272          14 :         avctx->pix_fmt = AV_PIX_FMT_GBRP12;
     273          14 :         break;
     274           0 :     case 51120:
     275             :     case 51121:
     276           0 :         avctx->pix_fmt = AV_PIX_FMT_GBRAP12;
     277           0 :         break;
     278           0 :     case 6161:
     279           0 :         avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
     280           0 :         break;
     281           0 :     case 6160:
     282           0 :         avctx->pix_fmt = AV_PIX_FMT_GRAY16LE;
     283           0 :         break;
     284           2 :     case 50161:
     285           2 :         avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
     286           2 :         break;
     287          14 :     case 50160:
     288          14 :         avctx->pix_fmt = AV_PIX_FMT_RGB48LE;
     289          14 :         break;
     290           0 :     case 51161:
     291           0 :         avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
     292           0 :         break;
     293          14 :     case 51160:
     294          14 :         avctx->pix_fmt = AV_PIX_FMT_RGBA64LE;
     295          14 :         break;
     296           0 :     case 100081:
     297           0 :         avctx->pix_fmt = AV_PIX_FMT_UYVY422;
     298           0 :         break;
     299           0 :     case 102081:
     300           0 :         avctx->pix_fmt = AV_PIX_FMT_YUV444P;
     301           0 :         break;
     302           0 :     case 103081:
     303           0 :         avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
     304           0 :         break;
     305           0 :     default:
     306           0 :         av_log(avctx, AV_LOG_ERROR, "Unsupported format\n");
     307           0 :         return AVERROR_PATCHWELCOME;
     308             :     }
     309             : 
     310          91 :     ff_set_sar(avctx, avctx->sample_aspect_ratio);
     311             : 
     312          91 :     if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
     313           0 :         return ret;
     314             : 
     315             :     // Move pointer to offset from start of file
     316          91 :     buf =  avpkt->data + offset;
     317             : 
     318         819 :     for (i=0; i<AV_NUM_DATA_POINTERS; i++)
     319         728 :         ptr[i] = p->data[i];
     320             : 
     321          91 :     switch (bits_per_color) {
     322          28 :     case 10:
     323        8092 :         for (x = 0; x < avctx->height; x++) {
     324       32256 :             uint16_t *dst[4] = {(uint16_t*)ptr[0],
     325        8064 :                                 (uint16_t*)ptr[1],
     326        8064 :                                 (uint16_t*)ptr[2],
     327        8064 :                                 (uint16_t*)ptr[3]};
     328     2846592 :             for (y = 0; y < avctx->width; y++) {
     329     2838528 :                 *dst[2]++ = read10in32(&buf, &rgbBuffer,
     330             :                                        &n_datum, endian);
     331     2838528 :                 *dst[0]++ = read10in32(&buf, &rgbBuffer,
     332             :                                        &n_datum, endian);
     333     2838528 :                 *dst[1]++ = read10in32(&buf, &rgbBuffer,
     334             :                                        &n_datum, endian);
     335     2838528 :                 if (elements == 4)
     336           0 :                     *dst[3]++ =
     337           0 :                     read10in32(&buf, &rgbBuffer,
     338             :                                &n_datum, endian);
     339             :             }
     340        8064 :             n_datum = 0;
     341       32256 :             for (i = 0; i < elements; i++)
     342       24192 :                 ptr[i] += p->linesize[i];
     343             :         }
     344          28 :         break;
     345          14 :     case 12:
     346        4046 :         for (x = 0; x < avctx->height; x++) {
     347       16128 :             uint16_t *dst[4] = {(uint16_t*)ptr[0],
     348        4032 :                                 (uint16_t*)ptr[1],
     349        4032 :                                 (uint16_t*)ptr[2],
     350        4032 :                                 (uint16_t*)ptr[3]};
     351     1423296 :             for (y = 0; y < avctx->width; y++) {
     352     1419264 :                 if (elements >= 3)
     353     1419264 :                     *dst[2]++ = read16(&buf, endian) >> 4;
     354     1419264 :                 *dst[0] = read16(&buf, endian) >> 4;
     355     1419264 :                 dst[0]++;
     356     1419264 :                 if (elements >= 2)
     357     1419264 :                     *dst[1]++ = read16(&buf, endian) >> 4;
     358     1419264 :                 if (elements == 4)
     359           0 :                     *dst[3]++ = read16(&buf, endian) >> 4;
     360             :             }
     361       16128 :             for (i = 0; i < elements; i++)
     362       12096 :                 ptr[i] += p->linesize[i];
     363             :             // Jump to next aligned position
     364        4032 :             buf += need_align;
     365             :         }
     366          14 :         break;
     367          30 :     case 16:
     368          30 :         elements *= 2;
     369          49 :     case 8:
     370          49 :         if (   avctx->pix_fmt == AV_PIX_FMT_YUVA444P
     371          49 :             || avctx->pix_fmt == AV_PIX_FMT_YUV444P) {
     372           0 :             for (x = 0; x < avctx->height; x++) {
     373           0 :                 ptr[0] = p->data[0] + x * p->linesize[0];
     374           0 :                 ptr[1] = p->data[1] + x * p->linesize[1];
     375           0 :                 ptr[2] = p->data[2] + x * p->linesize[2];
     376           0 :                 ptr[3] = p->data[3] + x * p->linesize[3];
     377           0 :                 for (y = 0; y < avctx->width; y++) {
     378           0 :                     *ptr[1]++ = *buf++;
     379           0 :                     *ptr[0]++ = *buf++;
     380           0 :                     *ptr[2]++ = *buf++;
     381           0 :                     if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P)
     382           0 :                         *ptr[3]++ = *buf++;
     383             :                 }
     384             :             }
     385             :         } else {
     386          98 :         av_image_copy_plane(ptr[0], p->linesize[0],
     387             :                             buf, stride,
     388          49 :                             elements * avctx->width, avctx->height);
     389             :         }
     390          49 :         break;
     391             :     }
     392             : 
     393          91 :     *got_frame = 1;
     394             : 
     395          91 :     return buf_size;
     396             : }
     397             : 
     398             : AVCodec ff_dpx_decoder = {
     399             :     .name           = "dpx",
     400             :     .long_name      = NULL_IF_CONFIG_SMALL("DPX (Digital Picture Exchange) image"),
     401             :     .type           = AVMEDIA_TYPE_VIDEO,
     402             :     .id             = AV_CODEC_ID_DPX,
     403             :     .decode         = decode_frame,
     404             :     .capabilities   = AV_CODEC_CAP_DR1,
     405             : };

Generated by: LCOV version 1.13