LCOV - code coverage report
Current view: top level - libavcodec - vcr1.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 49 54 90.7 %
Date: 2017-12-10 21:22:29 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :  * ATI VCR1 codec
       3             :  * Copyright (c) 2003 Michael Niedermayer
       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             :  * ATI VCR1 codec
      25             :  */
      26             : 
      27             : #include "avcodec.h"
      28             : #include "internal.h"
      29             : #include "libavutil/avassert.h"
      30             : #include "libavutil/internal.h"
      31             : 
      32             : typedef struct VCR1Context {
      33             :     int delta[16];
      34             :     int offset[4];
      35             : } VCR1Context;
      36             : 
      37           2 : static av_cold int vcr1_decode_init(AVCodecContext *avctx)
      38             : {
      39           2 :     avctx->pix_fmt = AV_PIX_FMT_YUV410P;
      40             : 
      41           2 :     if (avctx->width % 8 || avctx->height%4) {
      42           0 :         avpriv_request_sample(avctx, "odd dimensions (%d x %d) support", avctx->width, avctx->height);
      43           0 :         return AVERROR_INVALIDDATA;
      44             :     }
      45             : 
      46           2 :     return 0;
      47             : }
      48             : 
      49         128 : static int vcr1_decode_frame(AVCodecContext *avctx, void *data,
      50             :                              int *got_frame, AVPacket *avpkt)
      51             : {
      52         128 :     VCR1Context *const a      = avctx->priv_data;
      53         128 :     AVFrame *const p          = data;
      54         128 :     const uint8_t *bytestream = avpkt->data;
      55         128 :     const uint8_t *bytestream_end = bytestream + avpkt->size;
      56             :     int i, x, y, ret;
      57             : 
      58         128 :     if(avpkt->size < 32 + avctx->height + avctx->width*avctx->height*5/8){
      59           0 :         av_log(avctx, AV_LOG_ERROR, "Insufficient input data. %d < %d\n", avpkt->size ,  32 + avctx->height + avctx->width*avctx->height*5/8);
      60           0 :         return AVERROR(EINVAL);
      61             :     }
      62             : 
      63         128 :     if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
      64           0 :         return ret;
      65         128 :     p->pict_type = AV_PICTURE_TYPE_I;
      66         128 :     p->key_frame = 1;
      67             : 
      68        2176 :     for (i = 0; i < 16; i++) {
      69        2048 :         a->delta[i] = *bytestream++;
      70        2048 :         bytestream++;
      71             :     }
      72             : 
      73       18560 :     for (y = 0; y < avctx->height; y++) {
      74             :         int offset;
      75       18432 :         uint8_t *luma = &p->data[0][y * p->linesize[0]];
      76             : 
      77       18432 :         if ((y & 3) == 0) {
      78        4608 :             uint8_t *cb = &p->data[1][(y >> 2) * p->linesize[1]];
      79        4608 :             uint8_t *cr = &p->data[2][(y >> 2) * p->linesize[2]];
      80             : 
      81        4608 :             av_assert0 (bytestream_end - bytestream >= 4 + avctx->width);
      82             : 
      83       23040 :             for (i = 0; i < 4; i++)
      84       18432 :                 a->offset[i] = *bytestream++;
      85             : 
      86        4608 :             offset = a->offset[0] - a->delta[bytestream[2] & 0xF];
      87      207360 :             for (x = 0; x < avctx->width; x += 4) {
      88      202752 :                 luma[0]     = offset += a->delta[bytestream[2] & 0xF];
      89      202752 :                 luma[1]     = offset += a->delta[bytestream[2] >>  4];
      90      202752 :                 luma[2]     = offset += a->delta[bytestream[0] & 0xF];
      91      202752 :                 luma[3]     = offset += a->delta[bytestream[0] >>  4];
      92      202752 :                 luma       += 4;
      93             : 
      94      202752 :                 *cb++       = bytestream[3];
      95      202752 :                 *cr++       = bytestream[1];
      96             : 
      97      202752 :                 bytestream += 4;
      98             :             }
      99             :         } else {
     100       13824 :             av_assert0 (bytestream_end - bytestream >= avctx->width / 2);
     101             : 
     102       13824 :             offset = a->offset[y & 3] - a->delta[bytestream[2] & 0xF];
     103             : 
     104      317952 :             for (x = 0; x < avctx->width; x += 8) {
     105      304128 :                 luma[0]     = offset += a->delta[bytestream[2] & 0xF];
     106      304128 :                 luma[1]     = offset += a->delta[bytestream[2] >>  4];
     107      304128 :                 luma[2]     = offset += a->delta[bytestream[3] & 0xF];
     108      304128 :                 luma[3]     = offset += a->delta[bytestream[3] >>  4];
     109      304128 :                 luma[4]     = offset += a->delta[bytestream[0] & 0xF];
     110      304128 :                 luma[5]     = offset += a->delta[bytestream[0] >>  4];
     111      304128 :                 luma[6]     = offset += a->delta[bytestream[1] & 0xF];
     112      304128 :                 luma[7]     = offset += a->delta[bytestream[1] >>  4];
     113      304128 :                 luma       += 8;
     114      304128 :                 bytestream += 4;
     115             :             }
     116             :         }
     117             :     }
     118             : 
     119         128 :     *got_frame = 1;
     120             : 
     121         128 :     return bytestream - avpkt->data;
     122             : }
     123             : 
     124             : AVCodec ff_vcr1_decoder = {
     125             :     .name           = "vcr1",
     126             :     .long_name      = NULL_IF_CONFIG_SMALL("ATI VCR1"),
     127             :     .type           = AVMEDIA_TYPE_VIDEO,
     128             :     .id             = AV_CODEC_ID_VCR1,
     129             :     .priv_data_size = sizeof(VCR1Context),
     130             :     .init           = vcr1_decode_init,
     131             :     .decode         = vcr1_decode_frame,
     132             :     .capabilities   = AV_CODEC_CAP_DR1,
     133             : };

Generated by: LCOV version 1.13