[FFmpeg-devel] [PATCH]lavc/jpeg2000dec: Read resolution box from jp2 files

Carl Eugen Hoyos cehoyos at ag.or.at
Tue May 2 17:14:58 EEST 2017


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
-------------- next part --------------
From 9955a76ea9abd6ad0c79b4e3d7fe74d4cf292aa6 Mon Sep 17 00:00:00 2001
From: Carl Eugen Hoyos <cehoyos at 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



More information about the ffmpeg-devel mailing list