Hi!

Attached patch allows reading the aspect ratio from jpeg2000 files.
Kakadu allows to produce samples, the "aspect" is defined as the 
horizontal and vertical resolution as in tiff.

Please comment, Carl Eugen
From 9955a76ea9abd6ad0c79b4e3d7fe74d4cf292aa6 Mon Sep 17 00:00:00 2001
From: Carl Eugen Hoyos <ceho...@ag.or.at>
Date: Tue, 2 May 2017 16:01:02 +0200
Subject: [PATCH] lavc/jpeg2000dec: Read the resolution box from jp2 files.

---
 libavcodec/jpeg2000dec.c |   37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
index e9f5f51..3e1cc00 100644
--- a/libavcodec/jpeg2000dec.c
+++ b/libavcodec/jpeg2000dec.c
@@ -26,6 +26,7 @@
  */
 
 #include <inttypes.h>
+#include <math.h>
 
 #include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
@@ -106,6 +107,7 @@ typedef struct Jpeg2000DecoderContext {
     int             tile_width, tile_height;
     unsigned        numXtiles, numYtiles;
     int             maxtilelen;
+    AVRational      resolution;
 
     Jpeg2000CodingStyle codsty[4];
     Jpeg2000QuantStyle  qntsty[4];
@@ -2043,6 +2045,34 @@ static int jp2_find_codestream(Jpeg2000DecoderContext *s)
                         if (cn < 4 && asoc < 4)
                             s->cdef[cn] = asoc;
                     }
+                } else if (atom2 == MKBETAG('r','e','s',' ') && atom2_size >= 
18) {
+                    int64_t vnum, vden, hnum, hden, vexp, hexp;
+                    uint32_t resx;
+                    bytestream2_skip(&s->g, 4);
+                    resx = bytestream2_get_be32u(&s->g);
+                    if (resx != MKBETAG('r','e','s','c') && resx != 
MKBETAG('r','e','s','d')) {
+                        bytestream2_seek(&s->g, atom2_end, SEEK_SET);
+                        continue;
+                    }
+                    vnum = bytestream2_get_be16u(&s->g);
+                    vden = bytestream2_get_be16u(&s->g);
+                    hnum = bytestream2_get_be16u(&s->g);
+                    hden = bytestream2_get_be16u(&s->g);
+                    vexp = bytestream2_get_byteu(&s->g);
+                    hexp = bytestream2_get_byteu(&s->g);
+                    if (vexp > hexp) {
+                        vexp -= hexp;
+                        hexp = 0;
+                    } else {
+                        hexp -= vexp;
+                        vexp = 0;
+                    }
+                    if (   INT64_MAX / (hnum * vden) > pow(10, hexp)
+                        && INT64_MAX / (vnum * hden) > pow(10, vexp))
+                        av_reduce(&s->resolution.num, &s->resolution.den,
+                                  hnum * vden * pow(10, hexp),
+                                  vnum * hden * pow(10, vexp),
+                                  INT32_MAX);
                 }
                 bytestream2_seek(&s->g, atom2_end, SEEK_SET);
             } while (atom_end - atom2_end >= 8);
@@ -2125,6 +2155,13 @@ static int jpeg2000_decode_frame(AVCodecContext *avctx, 
void *data,
 
     if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
         memcpy(picture->data[1], s->palette, 256 * sizeof(uint32_t));
+    if (   s->resolution.num && s->resolution.den
+        && INT64_MAX / avctx->width  > s->resolution.den
+        && INT64_MAX / avctx->height > s->resolution.num)
+        av_reduce(&avctx->sample_aspect_ratio.num, 
&avctx->sample_aspect_ratio.den,
+                  (int64_t)avctx->width  * s->resolution.den,
+                  (int64_t)avctx->height * s->resolution.num,
+                  INT32_MAX);
 
     return bytestream2_tell(&s->g);
 
-- 
1.7.10.4

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to