Ticket #1272: patchpngparser.2.diff

File patchpngparser.2.diff, 5.0 KB (added by Carl Eugen Hoyos, 14 years ago)
  • libavcodec/Makefile

    diff --git a/libavcodec/Makefile b/libavcodec/Makefile
    index 28d4a1c..6fc29f8 100644
    a b OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o h263.o \  
    703703                                          mpegvideo.o error_resilience.o \
    704704                                          mpeg4videodec.o mpeg4video.o \
    705705                                          ituh263dec.o h263dec.o
     706OBJS-$(CONFIG_PNG_PARSER)              += png_parser.o
    706707OBJS-$(CONFIG_MPEGAUDIO_PARSER)        += mpegaudio_parser.o \
    707708                                          mpegaudiodecheader.o mpegaudiodata.o
    708709OBJS-$(CONFIG_MPEGVIDEO_PARSER)        += mpegvideo_parser.o    \
  • libavcodec/allcodecs.c

    diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
    index d31d29a..4ebb90c 100644
    a b void avcodec_register_all(void)  
    453453    REGISTER_PARSER  (MPEG4VIDEO, mpeg4video);
    454454    REGISTER_PARSER  (MPEGAUDIO, mpegaudio);
    455455    REGISTER_PARSER  (MPEGVIDEO, mpegvideo);
     456    REGISTER_PARSER  (PNG, png);
    456457    REGISTER_PARSER  (PNM, pnm);
    457458    REGISTER_PARSER  (RV30, rv30);
    458459    REGISTER_PARSER  (RV40, rv40);
  • libavcodec/png_parser.c

    diff --git a/libavcodec/png_parser.c b/libavcodec/png_parser.c
    index e69de29..ddd1be8 100644
    a b  
     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 libavcodec/png_parser.c
     24 * PNG parser
     25 */
     26
     27#include "libavutil/intreadwrite.h"
     28#include "parser.h"
     29
     30#define PNGSIG 0x89504e470d0a1a0a
     31#define MNGSIG 0x8a4d4e470d0a1a0a
     32
     33typedef struct PNGParseContext
     34{
     35    ParseContext pc;
     36    uint32_t index;
     37    uint32_t chunk_length;
     38    uint32_t remaining_size;
     39} PNGParseContext;
     40
     41static int png_parse(AVCodecParserContext *s, AVCodecContext *avctx,
     42                     const uint8_t **poutbuf, int *poutbuf_size,
     43                     const uint8_t *buf, int buf_size)
     44{
     45    PNGParseContext *ppc = s->priv_data;
     46    int next = END_NOT_FOUND;
     47    int i = 0;
     48
     49    *poutbuf_size = 0;
     50    if (buf_size == 0)
     51        return 0;
     52
     53    if (!ppc->pc.frame_start_found) {
     54        uint64_t state64 = ppc->pc.state64;
     55        for (; i < buf_size; i++) {
     56            state64 = (state64 << 8) | buf[i];
     57            if (state64 == PNGSIG || state64 == MNGSIG) {
     58                i++;
     59                ppc->pc.frame_start_found = 1;
     60                break;
     61            }
     62        }
     63        ppc->pc.state64 = state64;
     64    } else
     65        if (ppc->remaining_size) {
     66            i = FFMIN(ppc->remaining_size, buf_size);
     67            ppc->remaining_size -= i;
     68            if (ppc->remaining_size)
     69                goto flush;
     70            if (ppc->index == -1) {
     71                next = i;
     72                goto flush;
     73            }
     74        }
     75
     76    for (;ppc->pc.frame_start_found && i < buf_size; i++) {
     77        ppc->pc.state = (ppc->pc.state<<8) | buf[i];
     78        if (ppc->index == 3) {
     79            ppc->chunk_length = AV_RL32(&ppc->pc.state);
     80            if (ppc->chunk_length > 0x7fffffff) {
     81                ppc->index = ppc->pc.frame_start_found = 0;
     82                goto flush;
     83            }
     84            ppc->chunk_length += 4;
     85        } else if (ppc->index == 7) {
     86            if (ppc->chunk_length >= buf_size - i)
     87                    ppc->remaining_size = ppc->chunk_length - buf_size + i + 1;
     88            if (AV_RB32(&ppc->pc.state) == MKTAG('I', 'E', 'N', 'D')) {
     89                if (ppc->remaining_size)
     90                    ppc->index = -1;
     91                else
     92                    next = ppc->chunk_length + i + 1;
     93                break;
     94            } else {
     95                ppc->index = 0;
     96                if (ppc->remaining_size)
     97                    break;
     98                else
     99                    i += ppc->chunk_length;
     100                continue;
     101            }
     102        }
     103        ppc->index++;
     104    }
     105flush:
     106    if (ff_combine_frame(&ppc->pc, next, &buf, &buf_size) < 0)
     107        return buf_size;
     108
     109    ppc->index = ppc->pc.frame_start_found = 0;
     110
     111    *poutbuf      = buf;
     112    *poutbuf_size = buf_size;
     113    return next;
     114}
     115
     116AVCodecParser ff_png_parser = {
     117    { CODEC_ID_PNG },
     118    sizeof(PNGParseContext),
     119    NULL,
     120    png_parse,
     121    ff_parse_close,
     122};