LCOV - code coverage report
Current view: top level - libavcodec - sgirledec.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 39 45 86.7 %
Date: 2017-12-16 13:57:32 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Silicon Graphics RLE 8-bit video decoder
       3             :  * Copyright (c) 2012 Peter Ross
       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             :  * Silicon Graphics RLE 8-bit video decoder
      25             :  * @note Data is packed in rbg323 with rle, contained in mv or mov.
      26             :  * The algorithm and pixfmt are subtly different from SGI images.
      27             :  */
      28             : 
      29             : #include "libavutil/common.h"
      30             : 
      31             : #include "avcodec.h"
      32             : #include "internal.h"
      33             : 
      34           2 : static av_cold int sgirle_decode_init(AVCodecContext *avctx)
      35             : {
      36           2 :     avctx->pix_fmt = AV_PIX_FMT_BGR8;
      37           2 :     return 0;
      38             : }
      39             : 
      40             : /**
      41             :  * Convert SGI RBG323 pixel into AV_PIX_FMT_BGR8
      42             :  * SGI RGB data is packed as 8bpp, (msb)3R 2B 3G(lsb)
      43             :  */
      44             : #define RBG323_TO_BGR8(x) ((((x) << 3) & 0xC0) |                                \
      45             :                            (((x) << 3) & 0x38) |                                \
      46             :                            (((x) >> 5) & 7))
      47             : static av_always_inline
      48       89431 : void rbg323_to_bgr8(uint8_t *dst, const uint8_t *src, int size)
      49             : {
      50             :     int i;
      51     1674217 :     for (i = 0; i < size; i++)
      52     1584786 :         dst[i] = RBG323_TO_BGR8(src[i]);
      53       89431 : }
      54             : 
      55             : /**
      56             :  * @param[out] dst Destination buffer
      57             :  * @param[in] src  Source buffer
      58             :  * @param src_size Source buffer size (bytes)
      59             :  * @param width    Width of destination buffer (pixels)
      60             :  * @param height   Height of destination buffer (pixels)
      61             :  * @param linesize Line size of destination buffer (bytes)
      62             :  *
      63             :  * @return <0 on error
      64             :  */
      65          31 : static int decode_sgirle8(AVCodecContext *avctx, uint8_t *dst,
      66             :                           const uint8_t *src, int src_size,
      67             :                           int width, int height, ptrdiff_t linesize)
      68             : {
      69          31 :     const uint8_t *src_end = src + src_size;
      70          31 :     int x = 0, y = 0;
      71             : 
      72             : #define INC_XY(n)                                                             \
      73             :     x += n;                                                                   \
      74             :     if (x >= width) {                                                         \
      75             :         y++;                                                                  \
      76             :         if (y >= height)                                                      \
      77             :             return 0;                                                         \
      78             :         x = 0;                                                                \
      79             :     }
      80             : 
      81      346458 :     while (src_end - src >= 2) {
      82      346427 :         uint8_t v = *src++;
      83      346427 :         if (v > 0 && v < 0xC0) {
      84             :             do {
      85      268566 :                 int length = FFMIN(v, width - x);
      86      268566 :                 if (length <= 0)
      87           0 :                     break;
      88      268566 :                 memset(dst + y * linesize + x, RBG323_TO_BGR8(*src), length);
      89      268566 :                 INC_XY(length);
      90      268535 :                 v -= length;
      91      268535 :             } while (v > 0);
      92      256965 :             src++;
      93       89431 :         } else if (v >= 0xC1) {
      94       89431 :             v -= 0xC0;
      95             :             do {
      96       89431 :                 int length = FFMIN3(v, width - x, src_end - src);
      97       89431 :                 if (src_end - src < length || length <= 0)
      98             :                     break;
      99       89431 :                 rbg323_to_bgr8(dst + y * linesize + x, src, length);
     100       89431 :                 INC_XY(length);
     101       89431 :                 src += length;
     102       89431 :                 v   -= length;
     103       89431 :             } while (v > 0);
     104             :         } else {
     105           0 :             avpriv_request_sample(avctx, "opcode %d", v);
     106           0 :             return AVERROR_PATCHWELCOME;
     107             :         }
     108             :     }
     109           0 :     return 0;
     110             : }
     111             : 
     112          31 : static int sgirle_decode_frame(AVCodecContext *avctx, void *data,
     113             :                                int *got_frame, AVPacket *avpkt)
     114             : {
     115          31 :     AVFrame *frame = data;
     116             :     int ret;
     117             : 
     118          31 :     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
     119           0 :         return ret;
     120             : 
     121          31 :     ret = decode_sgirle8(avctx, frame->data[0], avpkt->data, avpkt->size,
     122          31 :                          avctx->width, avctx->height, frame->linesize[0]);
     123          31 :     if (ret < 0)
     124           0 :         return ret;
     125             : 
     126          31 :     frame->pict_type = AV_PICTURE_TYPE_I;
     127          31 :     frame->key_frame = 1;
     128             : 
     129          31 :     *got_frame = 1;
     130             : 
     131          31 :     return avpkt->size;
     132             : }
     133             : 
     134             : AVCodec ff_sgirle_decoder = {
     135             :     .name           = "sgirle",
     136             :     .long_name      = NULL_IF_CONFIG_SMALL("Silicon Graphics RLE 8-bit video"),
     137             :     .type           = AVMEDIA_TYPE_VIDEO,
     138             :     .id             = AV_CODEC_ID_SGIRLE,
     139             :     .init           = sgirle_decode_init,
     140             :     .decode         = sgirle_decode_frame,
     141             :     .capabilities   = AV_CODEC_CAP_DR1,
     142             : };

Generated by: LCOV version 1.13