LCOV - code coverage report
Current view: top level - libavcodec - png_parser.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 47 52 90.4 %
Date: 2017-12-15 11:05:35 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*
       2             :  * PNG parser
       3             :  * Copyright (c) 2009 Peter Holik
       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             :  * PNG parser
      25             :  */
      26             : 
      27             : #include "parser.h"
      28             : #include "png.h"
      29             : 
      30             : typedef struct PNGParseContext {
      31             :     ParseContext pc;
      32             :     uint32_t chunk_pos;           ///< position inside current chunk
      33             :     uint32_t chunk_length;        ///< length of the current chunk
      34             :     uint32_t remaining_size;      ///< remaining size of the current chunk
      35             : } PNGParseContext;
      36             : 
      37         578 : static int png_parse(AVCodecParserContext *s, AVCodecContext *avctx,
      38             :                      const uint8_t **poutbuf, int *poutbuf_size,
      39             :                      const uint8_t *buf, int buf_size)
      40             : {
      41         578 :     PNGParseContext *ppc = s->priv_data;
      42         578 :     int next = END_NOT_FOUND;
      43         578 :     int i = 0;
      44             : 
      45         578 :     s->pict_type = AV_PICTURE_TYPE_NONE;
      46             : 
      47         578 :     *poutbuf_size = 0;
      48             : 
      49         578 :     if (!ppc->pc.frame_start_found) {
      50         287 :         uint64_t state64 = ppc->pc.state64;
      51        2058 :         for (; i < buf_size; i++) {
      52        2024 :             state64 = (state64 << 8) | buf[i];
      53        2024 :             if (state64 == PNGSIG || state64 == MNGSIG) {
      54         253 :                 i++;
      55         253 :                 ppc->pc.frame_start_found = 1;
      56         253 :                 break;
      57             :             }
      58             :         }
      59         287 :         ppc->pc.state64 = state64;
      60         291 :     } else if (ppc->remaining_size) {
      61         291 :         i = FFMIN(ppc->remaining_size, buf_size);
      62         291 :         ppc->remaining_size -= i;
      63         291 :         if (ppc->remaining_size)
      64         150 :             goto flush;
      65         141 :         if (ppc->chunk_pos == -1) {
      66           0 :             next = i;
      67           0 :             goto flush;
      68             :         }
      69             :     }
      70             : 
      71      160546 :     for (; ppc->pc.frame_start_found && i < buf_size; i++) {
      72       80256 :         ppc->pc.state = (ppc->pc.state << 8) | buf[i];
      73       80256 :         if (ppc->chunk_pos == 3) {
      74       10032 :             ppc->chunk_length = ppc->pc.state;
      75       10032 :             if (ppc->chunk_length > 0x7fffffff) {
      76           0 :                 ppc->chunk_pos = ppc->pc.frame_start_found = 0;
      77           0 :                 goto flush;
      78             :             }
      79       10032 :             ppc->chunk_length += 4;
      80       70224 :         } else if (ppc->chunk_pos == 7) {
      81       10032 :             if (ppc->chunk_length >= buf_size - i)
      82         142 :                 ppc->remaining_size = ppc->chunk_length - buf_size + i + 1;
      83       10032 :             if (ppc->pc.state == MKBETAG('I', 'E', 'N', 'D')) {
      84         252 :                 if (ppc->remaining_size)
      85           0 :                     ppc->chunk_pos = -1;
      86             :                 else
      87         252 :                     next = ppc->chunk_length + i + 1;
      88         252 :                 break;
      89             :             } else {
      90        9780 :                 ppc->chunk_pos = 0;
      91        9780 :                 if (ppc->remaining_size)
      92         142 :                     break;
      93             :                 else
      94        9638 :                     i += ppc->chunk_length;
      95        9638 :                 continue;
      96             :             }
      97             :         }
      98       70224 :         ppc->chunk_pos++;
      99             :     }
     100             : 
     101          34 : flush:
     102         578 :     if (ff_combine_frame(&ppc->pc, next, &buf, &buf_size) < 0)
     103         291 :         return buf_size;
     104             : 
     105         287 :     ppc->chunk_pos = ppc->pc.frame_start_found = 0;
     106             : 
     107         287 :     *poutbuf      = buf;
     108         287 :     *poutbuf_size = buf_size;
     109         287 :     return next;
     110             : }
     111             : 
     112             : AVCodecParser ff_png_parser = {
     113             :     .codec_ids      = { AV_CODEC_ID_PNG },
     114             :     .priv_data_size = sizeof(PNGParseContext),
     115             :     .parser_parse   = png_parse,
     116             :     .parser_close   = ff_parse_close,
     117             : };

Generated by: LCOV version 1.13