diff mbox

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

Message ID CAB0OVGq4hgcBrCdZQJQE0C+NU5gnUWZ9J9HEr10y4iqvpBUKCA@mail.gmail.com
State Accepted
Headers show

Commit Message

Carl Eugen Hoyos May 2, 2017, 2:29 p.m. UTC
2017-05-02 16:21 GMT+02:00 Nicolas George <george@nsup.org>:
> Le tridi 13 floréal, an CCXXV, Carl Eugen Hoyos a écrit :
>> 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.
>
> Did you test what happens with this patch if you try to read two frames
> with the same context (for example with the image2 demuxer), the first
> frame has a non-square-pixels resolution defined and the second has no
> resolution indication at all?
>
> The correct result would be to have a sample aspect ratio on the first
> frame and not on the second.
>
> But with this code, since the first resolution is stored in the context
> and never cleared, it looks like it will be kept for the remaining
> images.

New, fixed patch attached.
(There also was another bug.)

Thank you, Carl Eugen

Comments

Carl Eugen Hoyos July 18, 2017, 10:06 a.m. UTC | #1
2017-05-02 16:29 GMT+02:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:

> New, fixed patch attached.

Patch applied.

Carl Eugen
diff mbox

Patch

From 027d46030354c99ce496d299ff3c95e739ecdda2 Mon Sep 17 00:00:00 2001
From: Carl Eugen Hoyos <cehoyos@ag.or.at>
Date: Tue, 2 May 2017 16:27:47 +0200
Subject: [PATCH] lavc/jpeg2000dec: Read the sample aspect ratio from the jp2
 resolution box.

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

diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
index e9f5f51..17ca257 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      sar;
 
     Jpeg2000CodingStyle codsty[4];
     Jpeg2000QuantStyle  qntsty[4];
@@ -1982,6 +1984,7 @@  static int jp2_find_codestream(Jpeg2000DecoderContext *s)
                 atom2_end  = bytestream2_tell(&s->g) + atom2_size - 8;
                 if (atom2_size < 8 || atom2_end > atom_end || atom2_end < atom2_size)
                     break;
+                atom2_size -= 8;
                 if (atom2 == JP2_CODESTREAM) {
                     return 1;
                 } else if (atom2 == MKBETAG('c','o','l','r') && atom2_size >= 7) {
@@ -2043,6 +2046,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->sar.den, &s->sar.num,
+                                  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 +2156,9 @@  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->sar.num && s->sar.den)
+        avctx->sample_aspect_ratio = s->sar;
+    s->sar.num = s->sar.den = 0;
 
     return bytestream2_tell(&s->g);
 
-- 
1.7.10.4