diff mbox series

[FFmpeg-devel,2/5] libavcodec/jpeg2000dec.c: Modify image dimensions

Message ID 20200621184208.27665-2-gautamramk@gmail.com
State Accepted
Commit 2760de16bc91449b617e3c8dd0d1db1866ba72a8
Headers show
Series [FFmpeg-devel,1/5] libavcodec/jpeg2000.c: Precinct size check removed | expand

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Gautam Ramakrishnan June 21, 2020, 6:42 p.m. UTC
From: Gautam Ramakrishnan <gautamramk@gmail.com>

Reduce image size of the image if all components have
a non zero sample separation. This is to replicate the
output of opj_decompress.
---
 libavcodec/jpeg2000dec.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

Comments

Michael Niedermayer June 22, 2020, 9:32 p.m. UTC | #1
On Mon, Jun 22, 2020 at 12:12:05AM +0530, gautamramk@gmail.com wrote:
> From: Gautam Ramakrishnan <gautamramk@gmail.com>
> 
> Reduce image size of the image if all components have
> a non zero sample separation. This is to replicate the
> output of opj_decompress.
> ---
>  libavcodec/jpeg2000dec.c | 19 ++++++++++++++-----
>  1 file changed, 14 insertions(+), 5 deletions(-)
> 
> diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
> index ab36009a2d..05e85f4317 100644
> --- a/libavcodec/jpeg2000dec.c
> +++ b/libavcodec/jpeg2000dec.c
> @@ -269,6 +269,8 @@ static int get_siz(Jpeg2000DecoderContext *s)
>      const enum AVPixelFormat *possible_fmts = NULL;
>      int possible_fmts_nb = 0;
>      int ret;
> +    int o_dimx, o_dimy; //original image dimensions.
> +    int dimx, dimy;
>  
>      if (bytestream2_get_bytes_left(&s->g) < 36) {
>          av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for SIZ\n");
> @@ -371,11 +373,18 @@ static int get_siz(Jpeg2000DecoderContext *s)
>      }
>  
>      /* compute image size with reduction factor */
> -    ret = ff_set_dimensions(s->avctx,
> -            ff_jpeg2000_ceildivpow2(s->width  - s->image_offset_x,
> -                                               s->reduction_factor),
> -            ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y,
> -                                               s->reduction_factor));
> +    o_dimx = ff_jpeg2000_ceildivpow2(s->width  - s->image_offset_x,
> +                                               s->reduction_factor);
> +    o_dimy = ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y,
> +                                               s->reduction_factor);
> +    dimx = ff_jpeg2000_ceildiv(o_dimx, s->cdx[0]);
> +    dimy = ff_jpeg2000_ceildiv(o_dimy, s->cdy[0]);
> +    for (i = 1; i < s->ncomponents; i++) {
> +        dimx = FFMAX(dimx, ff_jpeg2000_ceildiv(o_dimx, s->cdx[i]));
> +        dimy = FFMAX(dimy, ff_jpeg2000_ceildiv(o_dimy, s->cdy[i]));
> +    }
> +
> +    ret = ff_set_dimensions(s->avctx, dimx, dimy);
>      if (ret < 0)
>          return ret;

I think the resolution, the pixel format and any odd-format-handling
code probably need to be adjusted together.
Changing just the dimension code to select a higher resolution when
chroma or alpha planes are of higher resolution then luma. Will
probably not work if there is neither a pixel format selected that
represents that nor code to compensate for this (as mjpeg does)
but i might be missing something

is there some testcase this fixes or improves ?

thx

[...]
Carl Eugen Hoyos June 22, 2020, 9:33 p.m. UTC | #2
Am Mo., 22. Juni 2020 um 23:32 Uhr schrieb Michael Niedermayer
<michael@niedermayer.cc>:
>
> On Mon, Jun 22, 2020 at 12:12:05AM +0530, gautamramk@gmail.com wrote:
> > From: Gautam Ramakrishnan <gautamramk@gmail.com>
> >
> > Reduce image size of the image if all components have
> > a non zero sample separation. This is to replicate the
> > output of opj_decompress.
> > ---
> >  libavcodec/jpeg2000dec.c | 19 ++++++++++++++-----
> >  1 file changed, 14 insertions(+), 5 deletions(-)
> >
> > diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
> > index ab36009a2d..05e85f4317 100644
> > --- a/libavcodec/jpeg2000dec.c
> > +++ b/libavcodec/jpeg2000dec.c
> > @@ -269,6 +269,8 @@ static int get_siz(Jpeg2000DecoderContext *s)
> >      const enum AVPixelFormat *possible_fmts = NULL;
> >      int possible_fmts_nb = 0;
> >      int ret;
> > +    int o_dimx, o_dimy; //original image dimensions.
> > +    int dimx, dimy;
> >
> >      if (bytestream2_get_bytes_left(&s->g) < 36) {
> >          av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for SIZ\n");
> > @@ -371,11 +373,18 @@ static int get_siz(Jpeg2000DecoderContext *s)
> >      }
> >
> >      /* compute image size with reduction factor */
> > -    ret = ff_set_dimensions(s->avctx,
> > -            ff_jpeg2000_ceildivpow2(s->width  - s->image_offset_x,
> > -                                               s->reduction_factor),
> > -            ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y,
> > -                                               s->reduction_factor));
> > +    o_dimx = ff_jpeg2000_ceildivpow2(s->width  - s->image_offset_x,
> > +                                               s->reduction_factor);
> > +    o_dimy = ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y,
> > +                                               s->reduction_factor);
> > +    dimx = ff_jpeg2000_ceildiv(o_dimx, s->cdx[0]);
> > +    dimy = ff_jpeg2000_ceildiv(o_dimy, s->cdy[0]);
> > +    for (i = 1; i < s->ncomponents; i++) {
> > +        dimx = FFMAX(dimx, ff_jpeg2000_ceildiv(o_dimx, s->cdx[i]));
> > +        dimy = FFMAX(dimy, ff_jpeg2000_ceildiv(o_dimy, s->cdy[i]));
> > +    }
> > +
> > +    ret = ff_set_dimensions(s->avctx, dimx, dimy);
> >      if (ret < 0)
> >          return ret;
>
> I think the resolution, the pixel format and any odd-format-handling
> code probably need to be adjusted together.
> Changing just the dimension code to select a higher resolution when
> chroma or alpha planes are of higher resolution then luma. Will
> probably not work if there is neither a pixel format selected that
> represents that nor code to compensate for this (as mjpeg does)
> but i might be missing something
>
> is there some testcase this fixes or improves ?

At least p1_01.j2k which has one component.

Carl Eugen
Michael Niedermayer June 27, 2020, 10:42 a.m. UTC | #3
On Mon, Jun 22, 2020 at 11:33:38PM +0200, Carl Eugen Hoyos wrote:
> Am Mo., 22. Juni 2020 um 23:32 Uhr schrieb Michael Niedermayer
> <michael@niedermayer.cc>:
> >
> > On Mon, Jun 22, 2020 at 12:12:05AM +0530, gautamramk@gmail.com wrote:
> > > From: Gautam Ramakrishnan <gautamramk@gmail.com>
> > >
> > > Reduce image size of the image if all components have
> > > a non zero sample separation. This is to replicate the
> > > output of opj_decompress.
> > > ---
> > >  libavcodec/jpeg2000dec.c | 19 ++++++++++++++-----
> > >  1 file changed, 14 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
> > > index ab36009a2d..05e85f4317 100644
> > > --- a/libavcodec/jpeg2000dec.c
> > > +++ b/libavcodec/jpeg2000dec.c
> > > @@ -269,6 +269,8 @@ static int get_siz(Jpeg2000DecoderContext *s)
> > >      const enum AVPixelFormat *possible_fmts = NULL;
> > >      int possible_fmts_nb = 0;
> > >      int ret;
> > > +    int o_dimx, o_dimy; //original image dimensions.
> > > +    int dimx, dimy;
> > >
> > >      if (bytestream2_get_bytes_left(&s->g) < 36) {
> > >          av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for SIZ\n");
> > > @@ -371,11 +373,18 @@ static int get_siz(Jpeg2000DecoderContext *s)
> > >      }
> > >
> > >      /* compute image size with reduction factor */
> > > -    ret = ff_set_dimensions(s->avctx,
> > > -            ff_jpeg2000_ceildivpow2(s->width  - s->image_offset_x,
> > > -                                               s->reduction_factor),
> > > -            ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y,
> > > -                                               s->reduction_factor));
> > > +    o_dimx = ff_jpeg2000_ceildivpow2(s->width  - s->image_offset_x,
> > > +                                               s->reduction_factor);
> > > +    o_dimy = ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y,
> > > +                                               s->reduction_factor);
> > > +    dimx = ff_jpeg2000_ceildiv(o_dimx, s->cdx[0]);
> > > +    dimy = ff_jpeg2000_ceildiv(o_dimy, s->cdy[0]);
> > > +    for (i = 1; i < s->ncomponents; i++) {
> > > +        dimx = FFMAX(dimx, ff_jpeg2000_ceildiv(o_dimx, s->cdx[i]));
> > > +        dimy = FFMAX(dimy, ff_jpeg2000_ceildiv(o_dimy, s->cdy[i]));
> > > +    }
> > > +
> > > +    ret = ff_set_dimensions(s->avctx, dimx, dimy);
> > >      if (ret < 0)
> > >          return ret;
> >
> > I think the resolution, the pixel format and any odd-format-handling
> > code probably need to be adjusted together.
> > Changing just the dimension code to select a higher resolution when
> > chroma or alpha planes are of higher resolution then luma. Will
> > probably not work if there is neither a pixel format selected that
> > represents that nor code to compensate for this (as mjpeg does)
> > but i might be missing something
> >
> > is there some testcase this fixes or improves ?
> 
> At least p1_01.j2k which has one component.

Ok, will apply
ive also tested the patchset over night with afl

Thanks


[...]
diff mbox series

Patch

diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
index ab36009a2d..05e85f4317 100644
--- a/libavcodec/jpeg2000dec.c
+++ b/libavcodec/jpeg2000dec.c
@@ -269,6 +269,8 @@  static int get_siz(Jpeg2000DecoderContext *s)
     const enum AVPixelFormat *possible_fmts = NULL;
     int possible_fmts_nb = 0;
     int ret;
+    int o_dimx, o_dimy; //original image dimensions.
+    int dimx, dimy;
 
     if (bytestream2_get_bytes_left(&s->g) < 36) {
         av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for SIZ\n");
@@ -371,11 +373,18 @@  static int get_siz(Jpeg2000DecoderContext *s)
     }
 
     /* compute image size with reduction factor */
-    ret = ff_set_dimensions(s->avctx,
-            ff_jpeg2000_ceildivpow2(s->width  - s->image_offset_x,
-                                               s->reduction_factor),
-            ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y,
-                                               s->reduction_factor));
+    o_dimx = ff_jpeg2000_ceildivpow2(s->width  - s->image_offset_x,
+                                               s->reduction_factor);
+    o_dimy = ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y,
+                                               s->reduction_factor);
+    dimx = ff_jpeg2000_ceildiv(o_dimx, s->cdx[0]);
+    dimy = ff_jpeg2000_ceildiv(o_dimy, s->cdy[0]);
+    for (i = 1; i < s->ncomponents; i++) {
+        dimx = FFMAX(dimx, ff_jpeg2000_ceildiv(o_dimx, s->cdx[i]));
+        dimy = FFMAX(dimy, ff_jpeg2000_ceildiv(o_dimy, s->cdy[i]));
+    }
+
+    ret = ff_set_dimensions(s->avctx, dimx, dimy);
     if (ret < 0)
         return ret;