On 26/03/13 23:21, Nicolas Bertrand wrote:
> Based on 2007 GSOC project and code cleaning (Kamil Nowosad)
> 
> Diego Biurrun modifications :
> - K&R formatting cosmetics
> - Give all files a jpeg2000 prefix
> - Use designated initializers
> - Fix some doxygen comments
> - Switch to jpeg2000 name prefix
> - Wwarning fixes
> - Remove broken and/or silly debug code
> 
> Nicolas Bertrand modifications :
> - Modifications to handle JPEG2000 for digital cinema
> - Corrections on header markers: COD
> - Addition of CPRL progression order
> - Addition of tile-parts mgmt (TLM)
> - Corrections on arithmetic decoder (T1)
> - Corrections on inverse DWT and MCT
> - Robustness corrections on tag tree init
> - Replace of av_malloc by av_malloc_array
> - Adittion of low res parameter (default value=0)
> - Addition of jpeg2000 profiles
> - Replace CODEC_ID by AV_CODEC_ID
> - Convert to refcounted frames
> - Taken into accounts remarks from patch review
> ---
>  Changelog                |    1 +
>  doc/general.texi         |    4 +-
>  libavcodec/Makefile      |    2 +
>  libavcodec/allcodecs.c   |    1 +
>  libavcodec/avcodec.h     |    6 +
>  libavcodec/jpeg2000.c    |  456 +++++++++++++++++
>  libavcodec/jpeg2000.h    |  256 ++++++++++
>  libavcodec/jpeg2000dec.c | 1270 
> ++++++++++++++++++++++++++++++++++++++++++++++
>  libavcodec/jpeg2000dwt.c |  253 +++++++++
>  libavcodec/jpeg2000dwt.h |   62 +++
>  libavcodec/mqc.c         |  112 ++++
>  libavcodec/mqc.h         |   74 +++
>  libavcodec/mqcdec.c      |   93 ++++
>  libavcodec/version.h     |    2 +-
>  14 files changed, 2589 insertions(+), 3 deletions(-)
>  create mode 100644 libavcodec/jpeg2000.c
>  create mode 100644 libavcodec/jpeg2000.h
>  create mode 100644 libavcodec/jpeg2000dec.c
>  create mode 100644 libavcodec/jpeg2000dwt.c
>  create mode 100644 libavcodec/jpeg2000dwt.h
>  create mode 100644 libavcodec/mqc.c
>  create mode 100644 libavcodec/mqc.h
>  create mode 100644 libavcodec/mqcdec.c
> 
> diff --git a/Changelog b/Changelog
> index 15c0873..ce4d07e 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -7,6 +7,7 @@ version 10:
>  - reference-counting for AVFrame and AVPacket data
>  - avconv now fails when input options are used for output file
>    or vice versa
> +- JPEG 2000 decoder
>  
>  
>  version 9:
> diff --git a/doc/general.texi b/doc/general.texi
> index 2345ef7..ee87e9f 100644
> --- a/doc/general.texi
> +++ b/doc/general.texi
> @@ -373,8 +373,8 @@ following image formats are supported:
>      @tab Digital Picture Exchange
>  @item JPEG         @tab X @tab X
>      @tab Progressive JPEG is not supported.
> -@item JPEG 2000    @tab E @tab E
> -    @tab decoding supported through external library libopenjpeg
> +@item JPEG 2000    @tab E @tab X
> +    @tab encoding supported through external library libopenjpeg
>  @item JPEG-LS      @tab X @tab X
>  @item LJPEG        @tab X @tab
>      @tab Lossless JPEG
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index addf5a5..68d84d0 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -206,6 +206,8 @@ OBJS-$(CONFIG_INDEO4_DECODER)          += indeo4.o 
> ivi_common.o ivi_dsp.o
>  OBJS-$(CONFIG_INDEO5_DECODER)          += indeo5.o ivi_common.o ivi_dsp.o
>  OBJS-$(CONFIG_INTERPLAY_DPCM_DECODER)  += dpcm.o
>  OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.o
> +OBJS-$(CONFIG_JPEG2000_DECODER)        += jpeg2000dec.o jpeg2000.o      \
> +                                          jpeg2000dwt.o mqcdec.o mqc.o
>  OBJS-$(CONFIG_JPEGLS_DECODER)          += jpeglsdec.o jpegls.o \
>                                            mjpegdec.o mjpeg.o
>  OBJS-$(CONFIG_JPEGLS_ENCODER)          += jpeglsenc.o jpegls.o
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index 8bfa603..45fea3a 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -160,6 +160,7 @@ void avcodec_register_all(void)
>      REGISTER_DECODER(INDEO4,            indeo4);
>      REGISTER_DECODER(INDEO5,            indeo5);
>      REGISTER_DECODER(INTERPLAY_VIDEO,   interplay_video);
> +    REGISTER_DECODER(JPEG2000,          jpeg2000);
>      REGISTER_ENCDEC (JPEGLS,            jpegls);
>      REGISTER_DECODER(JV,                jv);
>      REGISTER_DECODER(KGV1,              kgv1);
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index f7d6553..484f217 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -2561,6 +2561,12 @@ typedef struct AVCodecContext {
>  #define FF_PROFILE_MPEG4_SIMPLE_STUDIO             14
>  #define FF_PROFILE_MPEG4_ADVANCED_SIMPLE           15
>  
> +#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0   0
> +#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1   1
> +#define FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION  2
> +#define FF_PROFILE_JPEG2000_DCINEMA_2K              3
> +#define FF_PROFILE_JPEG2000_DCINEMA_4K              4
> +
>      /**
>       * level
>       * - encoding: Set by user.
> diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c
> new file mode 100644
> index 0000000..12e943a
> --- /dev/null
> +++ b/libavcodec/jpeg2000.c
> @@ -0,0 +1,456 @@
> +/*
> + * JPEG 2000 encoder and decoder common functions
> + * Copyright (c) 2007 Kamil Nowosad
> + * Copyright (c) 2013 Nicolas Bertrand <[email protected]>
> + *
> + * This file is part of Libav.
> + *
> + * Libav is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * Libav is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
> USA
> + */
> +
> +/**
> + * @file
> + * JPEG 2000 image encoder and decoder common functions
> + */
> +
> +
> +#include "libavutil/common.h"
> +#include "libavutil/mem.h"
> +#include "avcodec.h"
> +#include "jpeg2000.h"
> +
> +#define SHL(a, n) ((n) >= 0 ? (a) << (n) : (a) >> -(n))
> +
> +/* tag tree routines */
> +
> +/* allocate the memory for tag tree */
> +static int32_t tag_tree_size(uint16_t w, uint16_t h)
> +{
> +    uint32_t res = 0;
> +    while (w > 1 || h > 1) {
> +        res += w * h;
> +        if (res + 1 >= INT32_MAX)
> +            return -1;
> +        w    = (w + 1) >> 1;
> +        h    = (h + 1) >> 1;
> +    }
> +    return (int32_t)(res + 1);
> +}

Are we sure there isn't a simpler way to code it? why int32_t ?

> +
> +static Jpeg2000TgtNode *ff_jpeg2000_tag_tree_init(int w, int h)
> +{
> +    int pw = w, ph = h;
> +    Jpeg2000TgtNode *res, *t, *t2;
> +    int32_t tt_size;
> +    
> +    tt_size = tag_tree_size(w, h);
> +    if (tt_size == -1)
> +        return NULL;
> +
> +    t = res = av_mallocz_array(tt_size, sizeof(*t));
> +    if (res == NULL)
> +        return NULL;
> +
> +    while (w > 1 || h > 1) {
> +        int i, j;
> +        pw = w;
> +        ph = h;
> +
> +        w  = (w + 1) >> 1;
> +        h  = (h + 1) >> 1;
> +        t2 = t + pw * ph;
> +
> +        for (i = 0; i < ph; i++)
> +            for (j = 0; j < pw; j++)
> +                t[i * pw + j].parent = &t2[(i >> 1) * w + (j >> 1)];
> +
> +        t = t2;
> +    }
> +    t[0].parent = NULL;
> +    return res;
> +}
> +
> +uint8_t ff_jpeg2000_nbctxno_lut[256][4];
> +
> +static int getnbctxno(int flag, int bandno)
> +{
> +    int h, v, d;
> +
> +    h = ((flag & JPEG2000_T1_SIG_E)  ? 1 : 0) +
> +        ((flag & JPEG2000_T1_SIG_W)  ? 1 : 0);
> +    v = ((flag & JPEG2000_T1_SIG_N)  ? 1 : 0) +
> +        ((flag & JPEG2000_T1_SIG_S)  ? 1 : 0);
> +    d = ((flag & JPEG2000_T1_SIG_NE) ? 1 : 0) +
> +        ((flag & JPEG2000_T1_SIG_NW) ? 1 : 0) +
> +        ((flag & JPEG2000_T1_SIG_SE) ? 1 : 0) +
> +        ((flag & JPEG2000_T1_SIG_SW) ? 1 : 0);
> +    if (bandno < 3) {
> +        if (bandno == 1)
> +            FFSWAP(int, h, v);
> +        if (h == 2)
> +            return 8;
> +        if (h == 1) {
> +            if (v >= 1)
> +                return 7;
> +            if (d >= 1)
> +                return 6;
> +            return 5;
> +        }
> +        if (v == 2)
> +            return 4;
> +        if (v == 1)
> +            return 3;
> +        if (d >= 2)
> +            return 2;
> +        if (d == 1)
> +            return 1;
> +        return 0;
> +    } else {
> +        if (d >= 3)
> +            return 8;
> +        if (d == 2) {
> +            if (h + v >= 1)
> +                return 7;
> +            return 6;
> +        }
> +        if (d == 1) {
> +            if (h + v >= 2)
> +                return 5;
> +            if (h + v == 1)
> +                return 4;
> +            return 3;
> +        }
> +        if (h + v >= 2)
> +            return 2;
> +        if (h + v == 1)
> +            return 1;
> +        return 0;
> +    }
> +    return 0;
> +}
> +
> +uint8_t ff_jpeg2000_sgnctxno_lut[16][16], ff_jpeg2000_xorbit_lut[16][16];
> +
> +static int getsgnctxno(int flag, uint8_t *xorbit)
> +{
> +    int vcontrib, hcontrib;
> +    static const int contribtab[3][3] = {{ 0, -1,  1 }, {-1, -1,  0 }, { 1,  
> 0,  1 }};
> +    static const int  ctxlbltab[3][3] = {{13, 12, 11 }, {10,  9, 10 }, {11, 
> 12, 13 }};
> +    static const int  xorbittab[3][3] = {{ 1,  1,  1 }, { 1,  0,  0 }, { 0,  
> 0,  0 }};
> +
> +    hcontrib = contribtab[flag & JPEG2000_T1_SIG_E ? flag & 
> JPEG2000_T1_SGN_E ? 1 : 2 : 0]
> +               [flag & JPEG2000_T1_SIG_W ? flag & JPEG2000_T1_SGN_W ? 1 : 2 
> : 0] + 1;
> +    vcontrib = contribtab[flag & JPEG2000_T1_SIG_S ? flag & 
> JPEG2000_T1_SGN_S ? 1 : 2 : 0]
> +               [flag & JPEG2000_T1_SIG_N ? flag & JPEG2000_T1_SGN_N ? 1 : 2 
> : 0] + 1;
> +    *xorbit = xorbittab[hcontrib][vcontrib];
> +    return ctxlbltab[hcontrib][vcontrib];
> +}

A switch table might be simpler?

> +
> +void ff_jpeg2000_init_tier1_luts(void)
> +{
> +    int i, j;
> +    for (i = 0; i < 256; i++)
> +        for (j = 0; j < 4; j++)
> +            ff_jpeg2000_nbctxno_lut[i][j] = getnbctxno(i, j);
> +    for (i = 0; i < 16; i++)
> +        for (j = 0; j < 16; j++)
> +            ff_jpeg2000_sgnctxno_lut[i][j] = getsgnctxno(i + (j << 8),
> +                                                         
> &ff_jpeg2000_xorbit_lut[i][j]);
> +}
> +
> +void ff_jpeg2000_set_significant(Jpeg2000T1Context *t1, int x, int y,
> +                                 int negative)
> +{
> +    x++;
> +    y++;
> +    t1->flags[y][x] |= JPEG2000_T1_SIG;
> +    if (negative) {
> +        t1->flags[y][x + 1] |= JPEG2000_T1_SIG_W | JPEG2000_T1_SGN_W;
> +        t1->flags[y][x - 1] |= JPEG2000_T1_SIG_E | JPEG2000_T1_SGN_E;
> +        t1->flags[y + 1][x] |= JPEG2000_T1_SIG_N | JPEG2000_T1_SGN_N;
> +        t1->flags[y - 1][x] |= JPEG2000_T1_SIG_S | JPEG2000_T1_SGN_S;
> +    } else {
> +        t1->flags[y][x + 1] |= JPEG2000_T1_SIG_W;
> +        t1->flags[y][x - 1] |= JPEG2000_T1_SIG_E;
> +        t1->flags[y + 1][x] |= JPEG2000_T1_SIG_N;
> +        t1->flags[y - 1][x] |= JPEG2000_T1_SIG_S;
> +    }
> +    t1->flags[y + 1][x + 1] |= JPEG2000_T1_SIG_NW;
> +    t1->flags[y + 1][x - 1] |= JPEG2000_T1_SIG_NE;
> +    t1->flags[y - 1][x + 1] |= JPEG2000_T1_SIG_SW;
> +    t1->flags[y - 1][x - 1] |= JPEG2000_T1_SIG_SE;
> +}
> +
> +int ff_jpeg2000_init_component(Jpeg2000Component *comp,
> +                               Jpeg2000CodingStyle *codsty,
> +                               Jpeg2000QuantStyle *qntsty,

It is a nit, but wouldn't be better having a jp2k namespace instead of
jpeg2000 ?

lu
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to