LCOV - code coverage report
Current view: top level - libavcodec - pnmdec.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 104 182 57.1 %
Date: 2017-12-15 18:13:28 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :  * PNM image format
       3             :  * Copyright (c) 2002, 2003 Fabrice Bellard
       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 "avcodec.h"
      23             : #include "internal.h"
      24             : #include "put_bits.h"
      25             : #include "pnm.h"
      26             : 
      27     5992816 : static void samplecpy(uint8_t *dst, const uint8_t *src, int n, int maxval)
      28             : {
      29     5992816 :     if (maxval <= 255) {
      30     5984752 :         memcpy(dst, src, n);
      31             :     } else {
      32             :         int i;
      33     5685120 :         for (i=0; i<n/2; i++) {
      34     5677056 :             ((uint16_t *)dst)[i] = AV_RB16(src+2*i);
      35             :         }
      36             :     }
      37     5992816 : }
      38             : 
      39       10536 : static int pnm_decode_frame(AVCodecContext *avctx, void *data,
      40             :                             int *got_frame, AVPacket *avpkt)
      41             : {
      42       10536 :     const uint8_t *buf   = avpkt->data;
      43       10536 :     int buf_size         = avpkt->size;
      44       10536 :     PNMContext * const s = avctx->priv_data;
      45       10536 :     AVFrame * const p    = data;
      46       10536 :     int i, j, k, n, linesize, h, upgrade = 0, is_mono = 0;
      47             :     unsigned char *ptr;
      48             :     int components, sample_len, ret;
      49             : 
      50       10536 :     s->bytestream_start =
      51       10536 :     s->bytestream       = (uint8_t *)buf;
      52       10536 :     s->bytestream_end   = (uint8_t *)buf + buf_size;
      53             : 
      54       10536 :     if ((ret = ff_pnm_decode_header(avctx, s)) < 0)
      55           0 :         return ret;
      56             : 
      57       10536 :     if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
      58           0 :         return ret;
      59       10536 :     p->pict_type = AV_PICTURE_TYPE_I;
      60       10536 :     p->key_frame = 1;
      61       10536 :     avctx->bits_per_raw_sample = av_log2(s->maxval) + 1;
      62             : 
      63       10536 :     switch (avctx->pix_fmt) {
      64           0 :     default:
      65           0 :         return AVERROR(EINVAL);
      66           0 :     case AV_PIX_FMT_RGBA64:
      67           0 :         n = avctx->width * 8;
      68           0 :         components=4;
      69           0 :         sample_len=16;
      70           0 :         if (s->maxval < 65535)
      71           0 :             upgrade = 2;
      72           0 :         goto do_read;
      73          14 :     case AV_PIX_FMT_RGB48:
      74          14 :         n = avctx->width * 6;
      75          14 :         components=3;
      76          14 :         sample_len=16;
      77          14 :         if (s->maxval < 65535)
      78           0 :             upgrade = 2;
      79          14 :         goto do_read;
      80          14 :     case AV_PIX_FMT_RGBA:
      81          14 :         n = avctx->width * 4;
      82          14 :         components=4;
      83          14 :         sample_len=8;
      84          14 :         goto do_read;
      85          55 :     case AV_PIX_FMT_RGB24:
      86          55 :         n = avctx->width * 3;
      87          55 :         components=3;
      88          55 :         sample_len=8;
      89          55 :         if (s->maxval < 255)
      90           0 :             upgrade = 1;
      91          55 :         goto do_read;
      92         173 :     case AV_PIX_FMT_GRAY8:
      93         173 :         n = avctx->width;
      94         173 :         components=1;
      95         173 :         sample_len=8;
      96         173 :         if (s->maxval < 255)
      97           0 :             upgrade = 1;
      98         173 :         goto do_read;
      99           0 :     case AV_PIX_FMT_GRAY8A:
     100           0 :         n = avctx->width * 2;
     101           0 :         components=2;
     102           0 :         sample_len=8;
     103           0 :         goto do_read;
     104          14 :     case AV_PIX_FMT_GRAY16:
     105          14 :         n = avctx->width * 2;
     106          14 :         components=1;
     107          14 :         sample_len=16;
     108          14 :         if (s->maxval < 65535)
     109           0 :             upgrade = 2;
     110          14 :         goto do_read;
     111           0 :     case AV_PIX_FMT_YA16:
     112           0 :         n =  avctx->width * 4;
     113           0 :         components=2;
     114           0 :         sample_len=16;
     115           0 :         if (s->maxval < 65535)
     116           0 :             upgrade = 2;
     117           0 :         goto do_read;
     118          39 :     case AV_PIX_FMT_MONOWHITE:
     119             :     case AV_PIX_FMT_MONOBLACK:
     120          39 :         n = (avctx->width + 7) >> 3;
     121          39 :         components=1;
     122          39 :         sample_len=1;
     123          39 :         is_mono = 1;
     124         309 :     do_read:
     125         309 :         ptr      = p->data[0];
     126         309 :         linesize = p->linesize[0];
     127         309 :         if (n * avctx->height > s->bytestream_end - s->bytestream)
     128           0 :             return AVERROR_INVALIDDATA;
     129         323 :         if(s->type < 4 || (is_mono && s->type==7)){
     130        8092 :             for (i=0; i<avctx->height; i++) {
     131             :                 PutBitContext pb;
     132        4032 :                 init_put_bits(&pb, ptr, linesize);
     133     1423296 :                 for(j=0; j<avctx->width * components; j++){
     134     1419264 :                     unsigned int c=0;
     135     1419264 :                     int v=0;
     136     1419264 :                     if(s->type < 4)
     137           0 :                     while(s->bytestream < s->bytestream_end && (*s->bytestream < '0' || *s->bytestream > '9' ))
     138           0 :                         s->bytestream++;
     139     1419264 :                     if(s->bytestream >= s->bytestream_end)
     140           0 :                         return AVERROR_INVALIDDATA;
     141     1419264 :                     if (is_mono) {
     142             :                         /* read a single digit */
     143     1419264 :                         v = (*s->bytestream++)&1;
     144             :                     } else {
     145             :                         /* read a sequence of digits */
     146           0 :                         for (k = 0; k < 5 && c <= 9; k += 1) {
     147           0 :                             v = 10*v + c;
     148           0 :                             c = (*s->bytestream++) - '0';
     149             :                         }
     150           0 :                         if (v > s->maxval) {
     151           0 :                             av_log(avctx, AV_LOG_ERROR, "value %d larger than maxval %d\n", v, s->maxval);
     152           0 :                             return AVERROR_INVALIDDATA;
     153             :                         }
     154             :                     }
     155     1419264 :                     if (sample_len == 16) {
     156           0 :                         ((uint16_t*)ptr)[j] = (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval;
     157             :                     } else
     158     1419264 :                         put_bits(&pb, sample_len, (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval);
     159             :                 }
     160        4032 :                 if (sample_len != 16)
     161        4032 :                     flush_put_bits(&pb);
     162        4032 :                 ptr+= linesize;
     163             :             }
     164             :         }else{
     165      102359 :         for (i = 0; i < avctx->height; i++) {
     166      102064 :             if (!upgrade)
     167      102064 :                 samplecpy(ptr, s->bytestream, n, s->maxval);
     168           0 :             else if (upgrade == 1) {
     169           0 :                 unsigned int j, f = (255 * 128 + s->maxval / 2) / s->maxval;
     170           0 :                 for (j = 0; j < n; j++)
     171           0 :                     ptr[j] = (s->bytestream[j] * f + 64) >> 7;
     172           0 :             } else if (upgrade == 2) {
     173           0 :                 unsigned int j, v, f = (65535 * 32768 + s->maxval / 2) / s->maxval;
     174           0 :                 for (j = 0; j < n / 2; j++) {
     175           0 :                     v = av_be2ne16(((uint16_t *)s->bytestream)[j]);
     176           0 :                     ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15;
     177             :                 }
     178             :             }
     179      102064 :             s->bytestream += n;
     180      102064 :             ptr           += linesize;
     181             :         }
     182             :         }
     183         309 :         break;
     184       10227 :     case AV_PIX_FMT_YUV420P:
     185             :     case AV_PIX_FMT_YUV420P9:
     186             :     case AV_PIX_FMT_YUV420P10:
     187             :         {
     188             :             unsigned char *ptr1, *ptr2;
     189             : 
     190       10227 :             n        = avctx->width;
     191       10227 :             ptr      = p->data[0];
     192       10227 :             linesize = p->linesize[0];
     193       10227 :             if (s->maxval >= 256)
     194           0 :                 n *= 2;
     195       10227 :             if (n * avctx->height * 3 / 2 > s->bytestream_end - s->bytestream)
     196           0 :                 return AVERROR_INVALIDDATA;
     197     2955603 :             for (i = 0; i < avctx->height; i++) {
     198     2945376 :                 samplecpy(ptr, s->bytestream, n, s->maxval);
     199     2945376 :                 s->bytestream += n;
     200     2945376 :                 ptr           += linesize;
     201             :             }
     202       10227 :             ptr1 = p->data[1];
     203       10227 :             ptr2 = p->data[2];
     204       10227 :             n >>= 1;
     205       10227 :             h = avctx->height >> 1;
     206     1482915 :             for (i = 0; i < h; i++) {
     207     1472688 :                 samplecpy(ptr1, s->bytestream, n, s->maxval);
     208     1472688 :                 s->bytestream += n;
     209     1472688 :                 samplecpy(ptr2, s->bytestream, n, s->maxval);
     210     1472688 :                 s->bytestream += n;
     211     1472688 :                 ptr1 += p->linesize[1];
     212     1472688 :                 ptr2 += p->linesize[2];
     213             :             }
     214             :         }
     215       10227 :         break;
     216           0 :     case AV_PIX_FMT_YUV420P16:
     217             :         {
     218             :             uint16_t *ptr1, *ptr2;
     219           0 :             const int f = (65535 * 32768 + s->maxval / 2) / s->maxval;
     220             :             unsigned int j, v;
     221             : 
     222           0 :             n        = avctx->width * 2;
     223           0 :             ptr      = p->data[0];
     224           0 :             linesize = p->linesize[0];
     225           0 :             if (n * avctx->height * 3 / 2 > s->bytestream_end - s->bytestream)
     226           0 :                 return AVERROR_INVALIDDATA;
     227           0 :             for (i = 0; i < avctx->height; i++) {
     228           0 :                 for (j = 0; j < n / 2; j++) {
     229           0 :                     v = av_be2ne16(((uint16_t *)s->bytestream)[j]);
     230           0 :                     ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15;
     231             :                 }
     232           0 :                 s->bytestream += n;
     233           0 :                 ptr           += linesize;
     234             :             }
     235           0 :             ptr1 = (uint16_t*)p->data[1];
     236           0 :             ptr2 = (uint16_t*)p->data[2];
     237           0 :             n >>= 1;
     238           0 :             h = avctx->height >> 1;
     239           0 :             for (i = 0; i < h; i++) {
     240           0 :                 for (j = 0; j < n / 2; j++) {
     241           0 :                     v = av_be2ne16(((uint16_t *)s->bytestream)[j]);
     242           0 :                     ptr1[j] = (v * f + 16384) >> 15;
     243             :                 }
     244           0 :                 s->bytestream += n;
     245             : 
     246           0 :                 for (j = 0; j < n / 2; j++) {
     247           0 :                     v = av_be2ne16(((uint16_t *)s->bytestream)[j]);
     248           0 :                     ptr2[j] = (v * f + 16384) >> 15;
     249             :                 }
     250           0 :                 s->bytestream += n;
     251             : 
     252           0 :                 ptr1 += p->linesize[1] / 2;
     253           0 :                 ptr2 += p->linesize[2] / 2;
     254             :             }
     255             :         }
     256           0 :         break;
     257             :     }
     258       10536 :     *got_frame = 1;
     259             : 
     260       10536 :     return s->bytestream - s->bytestream_start;
     261             : }
     262             : 
     263             : 
     264             : #if CONFIG_PGM_DECODER
     265             : AVCodec ff_pgm_decoder = {
     266             :     .name           = "pgm",
     267             :     .long_name      = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"),
     268             :     .type           = AVMEDIA_TYPE_VIDEO,
     269             :     .id             = AV_CODEC_ID_PGM,
     270             :     .priv_data_size = sizeof(PNMContext),
     271             :     .decode         = pnm_decode_frame,
     272             :     .capabilities   = AV_CODEC_CAP_DR1,
     273             : };
     274             : #endif
     275             : 
     276             : #if CONFIG_PGMYUV_DECODER
     277             : AVCodec ff_pgmyuv_decoder = {
     278             :     .name           = "pgmyuv",
     279             :     .long_name      = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"),
     280             :     .type           = AVMEDIA_TYPE_VIDEO,
     281             :     .id             = AV_CODEC_ID_PGMYUV,
     282             :     .priv_data_size = sizeof(PNMContext),
     283             :     .decode         = pnm_decode_frame,
     284             :     .capabilities   = AV_CODEC_CAP_DR1,
     285             : };
     286             : #endif
     287             : 
     288             : #if CONFIG_PPM_DECODER
     289             : AVCodec ff_ppm_decoder = {
     290             :     .name           = "ppm",
     291             :     .long_name      = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"),
     292             :     .type           = AVMEDIA_TYPE_VIDEO,
     293             :     .id             = AV_CODEC_ID_PPM,
     294             :     .priv_data_size = sizeof(PNMContext),
     295             :     .decode         = pnm_decode_frame,
     296             :     .capabilities   = AV_CODEC_CAP_DR1,
     297             : };
     298             : #endif
     299             : 
     300             : #if CONFIG_PBM_DECODER
     301             : AVCodec ff_pbm_decoder = {
     302             :     .name           = "pbm",
     303             :     .long_name      = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"),
     304             :     .type           = AVMEDIA_TYPE_VIDEO,
     305             :     .id             = AV_CODEC_ID_PBM,
     306             :     .priv_data_size = sizeof(PNMContext),
     307             :     .decode         = pnm_decode_frame,
     308             :     .capabilities   = AV_CODEC_CAP_DR1,
     309             : };
     310             : #endif
     311             : 
     312             : #if CONFIG_PAM_DECODER
     313             : AVCodec ff_pam_decoder = {
     314             :     .name           = "pam",
     315             :     .long_name      = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),
     316             :     .type           = AVMEDIA_TYPE_VIDEO,
     317             :     .id             = AV_CODEC_ID_PAM,
     318             :     .priv_data_size = sizeof(PNMContext),
     319             :     .decode         = pnm_decode_frame,
     320             :     .capabilities   = AV_CODEC_CAP_DR1,
     321             : };
     322             : #endif

Generated by: LCOV version 1.13