LCOV - code coverage report
Current view: top level - libavcodec - xbmdec.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 55 63 87.3 %
Date: 2017-12-17 16:07:53 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :  * XBM image format
       3             :  *
       4             :  * Copyright (c) 2012 Paul B Mahol
       5             :  *
       6             :  * This file is part of FFmpeg.
       7             :  *
       8             :  * FFmpeg is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public
      10             :  * License as published by the Free Software Foundation; either
      11             :  * version 2.1 of the License, or (at your option) any later version.
      12             :  *
      13             :  * FFmpeg is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public
      19             :  * License along with FFmpeg; if not, write to the Free Software
      20             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      21             :  */
      22             : 
      23             : #include "libavutil/avstring.h"
      24             : 
      25             : #include "avcodec.h"
      26             : #include "internal.h"
      27             : #include "mathops.h"
      28             : 
      29      373944 : static int convert(uint8_t x)
      30             : {
      31      373944 :     if (x >= 'a')
      32          24 :         x -= 87;
      33      373920 :     else if (x >= 'A')
      34      120635 :         x -= 55;
      35             :     else
      36      253285 :         x -= '0';
      37      373944 :     return x;
      38             : }
      39             : 
      40          36 : static int parse_str_int(const uint8_t *p, int len, const uint8_t *key)
      41             : {
      42          36 :     const uint8_t *end = p + len;
      43             : 
      44        1030 :     for(; p<end - strlen(key); p++) {
      45        1030 :         if (!memcmp(p, key, strlen(key)))
      46          36 :             break;
      47             :     }
      48          36 :     p += strlen(key);
      49          36 :     if (p >= end)
      50           0 :         return INT_MIN;
      51             : 
      52          36 :     for(; p<end; p++) {
      53             :         char *eptr;
      54          36 :         int64_t ret = strtol(p, &eptr, 10);
      55          36 :         if ((const uint8_t *)eptr != p)
      56          36 :             return ret;
      57             :     }
      58           0 :     return INT_MIN;
      59             : }
      60             : 
      61          18 : static int xbm_decode_frame(AVCodecContext *avctx, void *data,
      62             :                             int *got_frame, AVPacket *avpkt)
      63             : {
      64          18 :     AVFrame *p = data;
      65             :     int ret, linesize, i, j;
      66          18 :     int width  = 0;
      67          18 :     int height = 0;
      68          18 :     const uint8_t *end, *ptr = avpkt->data;
      69             :     const uint8_t *next;
      70             :     uint8_t *dst;
      71             : 
      72          18 :     avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
      73          18 :     end = avpkt->data + avpkt->size;
      74             : 
      75          18 :     width  = parse_str_int(avpkt->data, avpkt->size, "_width");
      76          18 :     height = parse_str_int(avpkt->data, avpkt->size, "_height");
      77             : 
      78          18 :     if ((ret = ff_set_dimensions(avctx, width, height)) < 0)
      79           0 :         return ret;
      80             : 
      81          18 :     if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
      82           0 :         return ret;
      83             : 
      84             :     // goto start of image data
      85          18 :     next = memchr(ptr, '{', avpkt->size);
      86          18 :     if (!next)
      87           0 :         next = memchr(ptr, '(', avpkt->size);
      88          18 :     if (!next)
      89           0 :         return AVERROR_INVALIDDATA;
      90          18 :     ptr = next + 1;
      91             : 
      92          18 :     linesize = (avctx->width + 7) / 8;
      93        4462 :     for (i = 0; i < avctx->height; i++) {
      94        4444 :         dst = p->data[0] + i * p->linesize[0];
      95      191384 :         for (j = 0; j < linesize; j++) {
      96             :             uint8_t val;
      97             : 
      98      939102 :             while (ptr < end && *ptr != 'x' && *ptr != '$')
      99      565222 :                 ptr++;
     100             : 
     101      186940 :             ptr ++;
     102      186940 :             if (ptr < end && av_isxdigit(*ptr)) {
     103      186940 :                 val = convert(*ptr++);
     104      186940 :                 if (av_isxdigit(*ptr))
     105      186940 :                     val = (val << 4) + convert(*ptr++);
     106      186940 :                 *dst++ = ff_reverse[val];
     107      373880 :                 if (av_isxdigit(*ptr) && j+1 < linesize) {
     108          32 :                     j++;
     109          32 :                     val = convert(*ptr++);
     110          32 :                     if (av_isxdigit(*ptr))
     111          32 :                         val = (val << 4) + convert(*ptr++);
     112          32 :                     *dst++ = ff_reverse[val];
     113             :                 }
     114             :             } else {
     115           0 :                 av_log(avctx, AV_LOG_ERROR,
     116             :                        "Unexpected data at %.8s.\n", ptr);
     117           0 :                 return AVERROR_INVALIDDATA;
     118             :             }
     119             :         }
     120             :     }
     121             : 
     122          18 :     p->key_frame = 1;
     123          18 :     p->pict_type = AV_PICTURE_TYPE_I;
     124             : 
     125          18 :     *got_frame       = 1;
     126             : 
     127          18 :     return avpkt->size;
     128             : }
     129             : 
     130             : AVCodec ff_xbm_decoder = {
     131             :     .name         = "xbm",
     132             :     .long_name    = NULL_IF_CONFIG_SMALL("XBM (X BitMap) image"),
     133             :     .type         = AVMEDIA_TYPE_VIDEO,
     134             :     .id           = AV_CODEC_ID_XBM,
     135             :     .decode       = xbm_decode_frame,
     136             :     .capabilities = AV_CODEC_CAP_DR1,
     137             : };

Generated by: LCOV version 1.13