png_parser
authorPeter Holik <peter@holik.at>
Thu, 3 May 2012 14:16:03 +0000 (00:16 +1000)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 4 May 2012 14:57:54 +0000 (16:57 +0200)
This adds support for png image2pipe streaming

Update to latest git by: Eugene Ware <eugene@noblesamurai.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libavcodec/Makefile
libavcodec/allcodecs.c
libavcodec/png_parser.c [new file with mode: 0644]

index 2a1b15f..891e29f 100644 (file)
@@ -704,6 +704,7 @@ OBJS-$(CONFIG_MPEG4VIDEO_PARSER)       += mpeg4video_parser.o h263.o \
                                           mpegvideo.o error_resilience.o \
                                           mpeg4videodec.o mpeg4video.o \
                                           ituh263dec.o h263dec.o
+OBJS-$(CONFIG_PNG_PARSER)              += png_parser.o
 OBJS-$(CONFIG_MPEGAUDIO_PARSER)        += mpegaudio_parser.o \
                                           mpegaudiodecheader.o mpegaudiodata.o
 OBJS-$(CONFIG_MPEGVIDEO_PARSER)        += mpegvideo_parser.o    \
index c12c783..5390410 100644 (file)
@@ -454,6 +454,7 @@ void avcodec_register_all(void)
     REGISTER_PARSER  (MPEG4VIDEO, mpeg4video);
     REGISTER_PARSER  (MPEGAUDIO, mpegaudio);
     REGISTER_PARSER  (MPEGVIDEO, mpegvideo);
+    REGISTER_PARSER  (PNG, png);
     REGISTER_PARSER  (PNM, pnm);
     REGISTER_PARSER  (RV30, rv30);
     REGISTER_PARSER  (RV40, rv40);
diff --git a/libavcodec/png_parser.c b/libavcodec/png_parser.c
new file mode 100644 (file)
index 0000000..ddd1be8
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * PNG parser
+ * Copyright (c) 2009 Peter Holik
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file libavcodec/png_parser.c
+ * PNG parser
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "parser.h"
+
+#define PNGSIG 0x89504e470d0a1a0a
+#define MNGSIG 0x8a4d4e470d0a1a0a
+
+typedef struct PNGParseContext
+{
+    ParseContext pc;
+    uint32_t index;
+    uint32_t chunk_length;
+    uint32_t remaining_size;
+} PNGParseContext;
+
+static int png_parse(AVCodecParserContext *s, AVCodecContext *avctx,
+                     const uint8_t **poutbuf, int *poutbuf_size,
+                     const uint8_t *buf, int buf_size)
+{
+    PNGParseContext *ppc = s->priv_data;
+    int next = END_NOT_FOUND;
+    int i = 0;
+
+    *poutbuf_size = 0;
+    if (buf_size == 0)
+        return 0;
+
+    if (!ppc->pc.frame_start_found) {
+        uint64_t state64 = ppc->pc.state64;
+        for (; i < buf_size; i++) {
+            state64 = (state64 << 8) | buf[i];
+            if (state64 == PNGSIG || state64 == MNGSIG) {
+                i++;
+                ppc->pc.frame_start_found = 1;
+                break;
+            }
+        }
+        ppc->pc.state64 = state64;
+    } else
+        if (ppc->remaining_size) {
+            i = FFMIN(ppc->remaining_size, buf_size);
+            ppc->remaining_size -= i;
+            if (ppc->remaining_size)
+                goto flush;
+            if (ppc->index == -1) {
+                next = i;
+                goto flush;
+            }
+        }
+
+    for (;ppc->pc.frame_start_found && i < buf_size; i++) {
+        ppc->pc.state = (ppc->pc.state<<8) | buf[i];
+        if (ppc->index == 3) {
+            ppc->chunk_length = AV_RL32(&ppc->pc.state);
+            if (ppc->chunk_length > 0x7fffffff) {
+                ppc->index = ppc->pc.frame_start_found = 0;
+                goto flush;
+            }
+            ppc->chunk_length += 4;
+        } else if (ppc->index == 7) {
+            if (ppc->chunk_length >= buf_size - i)
+                    ppc->remaining_size = ppc->chunk_length - buf_size + i + 1;
+            if (AV_RB32(&ppc->pc.state) == MKTAG('I', 'E', 'N', 'D')) {
+                if (ppc->remaining_size)
+                    ppc->index = -1;
+                else
+                    next = ppc->chunk_length + i + 1;
+                break;
+            } else {
+                ppc->index = 0;
+                if (ppc->remaining_size)
+                    break;
+                else
+                    i += ppc->chunk_length;
+                continue;
+            }
+        }
+        ppc->index++;
+    }
+flush:
+    if (ff_combine_frame(&ppc->pc, next, &buf, &buf_size) < 0)
+        return buf_size;
+
+    ppc->index = ppc->pc.frame_start_found = 0;
+
+    *poutbuf      = buf;
+    *poutbuf_size = buf_size;
+    return next;
+}
+
+AVCodecParser ff_png_parser = {
+    { CODEC_ID_PNG },
+    sizeof(PNGParseContext),
+    NULL,
+    png_parse,
+    ff_parse_close,
+};