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