From e9e7e685166e024466df8f9f10de12e74b327c82 Mon Sep 17 00:00:00 2001
From: Kirill Gavrilov <kirill@sview.ru>
Date: Wed, 29 Jan 2014 21:22:24 +0400
Subject: mjpegdec: parse JPS extension and save relevant stereo3d information

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
---
 libavcodec/mjpegdec.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/mjpegdec.h |  3 +++
 2 files changed, 52 insertions(+)

(limited to 'libavcodec')

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 6a74226713..0c30f89602 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -1554,6 +1554,45 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
         goto out;
     }
 
+    /* JPS extension by VRex */
+    if (s->start_code == APP3 && id == AV_RB32("_JPS") && len >= 10) {
+        int flags, layout, type;
+        if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+            av_log(s->avctx, AV_LOG_INFO, "_JPSJPS_\n");
+
+        skip_bits(&s->gb, 32); len -= 4;  /* JPS_ */
+        skip_bits(&s->gb, 16); len -= 2;  /* block length */
+        skip_bits(&s->gb, 8);             /* reserved */
+        flags  = get_bits(&s->gb, 8);
+        layout = get_bits(&s->gb, 8);
+        type   = get_bits(&s->gb, 8);
+        len -= 4;
+
+        s->stereo3d = av_stereo3d_alloc();
+        if (!s->stereo3d) {
+            goto out;
+        }
+        if (type == 0) {
+            s->stereo3d->type = AV_STEREO3D_2D;
+        } else if (type == 1) {
+            switch (layout) {
+            case 0x01:
+                s->stereo3d->type = AV_STEREO3D_LINES;
+                break;
+            case 0x02:
+                s->stereo3d->type = AV_STEREO3D_SIDEBYSIDE;
+                break;
+            case 0x03:
+                s->stereo3d->type = AV_STEREO3D_TOPBOTTOM;
+                break;
+            }
+            if (!(flags & 0x04)) {
+                s->stereo3d->flags = AV_STEREO3D_FLAG_INVERT;
+            }
+        }
+        goto out;
+    }
+
     /* EXIF metadata */
     if (s->start_code == APP1 && id == AV_RB32("Exif") && len >= 2) {
         GetByteContext gbytes;
@@ -1787,6 +1826,7 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     int ret = 0;
 
     av_dict_free(&s->exif_metadata);
+    av_freep(&s->stereo3d);
 
     buf_ptr = buf;
     buf_end = buf + buf_size;
@@ -2017,6 +2057,15 @@ the_end:
         }
     }
 
+    if (s->stereo3d) {
+        AVStereo3D *stereo = av_stereo3d_create_side_data(data);
+        if (stereo) {
+            stereo->type  = s->stereo3d->type;
+            stereo->flags = s->stereo3d->flags;
+        }
+        av_freep(&s->stereo3d);
+    }
+
     av_dict_copy(avpriv_frame_get_metadatap(data), s->exif_metadata, 0);
     av_dict_free(&s->exif_metadata);
 
diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h
index 79a95f551c..1ec241b1e6 100644
--- a/libavcodec/mjpegdec.h
+++ b/libavcodec/mjpegdec.h
@@ -31,6 +31,7 @@
 
 #include "libavutil/log.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/stereo3d.h"
 
 #include "avcodec.h"
 #include "get_bits.h"
@@ -122,6 +123,8 @@ typedef struct MJpegDecodeContext {
     int extern_huff;
     AVDictionary *exif_metadata;
 
+    AVStereo3D *stereo3d; ///!< stereoscopic information (cached, since it is read before frame allocation)
+
     const AVPixFmtDescriptor *pix_desc;
 } MJpegDecodeContext;
 
-- 
cgit v1.2.3