libavcodec/jpeg2000dec.c
c81a7063
 /*
  * JPEG 2000 image decoder
  * Copyright (c) 2007 Kamil Nowosad
  * Copyright (c) 2013 Nicolas Bertrand <nicoinattendu@gmail.com>
  *
e2e9bee2
  * This file is part of FFmpeg.
c81a7063
  *
e2e9bee2
  * FFmpeg is free software; you can redistribute it and/or
c81a7063
  * 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.
  *
e2e9bee2
  * FFmpeg is distributed in the hope that it will be useful,
c81a7063
  * 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
e2e9bee2
  * License along with FFmpeg; if not, write to the Free Software
c81a7063
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
  * @file
  * JPEG 2000 image decoder
  */
 
cc8163e1
 #include <inttypes.h>
 
fe4d5fe9
 #include "libavutil/attributes.h"
bbf43c70
 #include "libavutil/avassert.h"
c81a7063
 #include "libavutil/common.h"
 #include "libavutil/opt.h"
b39a6bbe
 #include "libavutil/pixdesc.h"
c81a7063
 #include "avcodec.h"
 #include "bytestream.h"
 #include "internal.h"
2e2d2466
 #include "thread.h"
c81a7063
 #include "jpeg2000.h"
 
 #define JP2_SIG_TYPE    0x6A502020
 #define JP2_SIG_VALUE   0x0D0A870A
 #define JP2_CODESTREAM  0x6A703263
b39a6bbe
 #define JP2_HEADER      0x6A703268
c81a7063
 
 #define HAD_COC 0x01
 #define HAD_QCC 0x02
 
 typedef struct Jpeg2000TilePart {
     uint8_t tile_index;                 // Tile index who refers the tile-part
9d56ccf5
     const uint8_t *tp_end;
0b426316
     GetByteContext tpg;                 // bit stream in tile-part
c81a7063
 } Jpeg2000TilePart;
 
 /* RMK: For JPEG2000 DCINEMA 3 tile-parts in a tile
  * one per component, so tile_part elements have a size of 3 */
 typedef struct Jpeg2000Tile {
     Jpeg2000Component   *comp;
     uint8_t             properties[4];
     Jpeg2000CodingStyle codsty[4];
     Jpeg2000QuantStyle  qntsty[4];
c51654fb
     Jpeg2000TilePart    tile_part[4];
9d56ccf5
     uint16_t tp_idx;                    // Tile-part index
c81a7063
 } Jpeg2000Tile;
 
 typedef struct Jpeg2000DecoderContext {
     AVClass         *class;
     AVCodecContext  *avctx;
de90bd6c
     GetByteContext  g;
c81a7063
 
     int             width, height;
     int             image_offset_x, image_offset_y;
     int             tile_offset_x, tile_offset_y;
     uint8_t         cbps[4];    // bits per sample in particular components
     uint8_t         sgnd[4];    // if a component is signed
     uint8_t         properties[4];
     int             cdx[4], cdy[4];
     int             precision;
     int             ncomponents;
b39a6bbe
     int             colour_space;
     uint32_t        palette[256];
     int8_t          pal8;
99de97ca
     int             cdef[4];
c81a7063
     int             tile_width, tile_height;
278a923c
     unsigned        numXtiles, numYtiles;
c81a7063
     int             maxtilelen;
 
     Jpeg2000CodingStyle codsty[4];
     Jpeg2000QuantStyle  qntsty[4];
 
     int             bit_index;
 
5dbbb762
     int             curtileno;
 
c81a7063
     Jpeg2000Tile    *tile;
 
     /*options parameters*/
5dbbb762
     int             reduction_factor;
c81a7063
 } Jpeg2000DecoderContext;
 
 /* get_bits functions for JPEG2000 packet bitstream
  * It is a get_bit function with a bit-stuffing routine. If the value of the
  * byte is 0xFF, the next byte includes an extra zero bit stuffed into the MSB.
  * cf. ISO-15444-1:2002 / B.10.1 Bit-stuffing routine */
 static int get_bits(Jpeg2000DecoderContext *s, int n)
 {
     int res = 0;
0b426316
 
c81a7063
     while (--n >= 0) {
         res <<= 1;
         if (s->bit_index == 0) {
0b426316
             s->bit_index = 7 + (bytestream2_get_byte(&s->g) != 0xFFu);
c81a7063
         }
         s->bit_index--;
0b426316
         res |= (bytestream2_peek_byte(&s->g) >> s->bit_index) & 1;
c81a7063
     }
     return res;
 }
 
 static void jpeg2000_flush(Jpeg2000DecoderContext *s)
 {
0b426316
     if (bytestream2_get_byte(&s->g) == 0xff)
         bytestream2_skip(&s->g, 1);
c81a7063
     s->bit_index = 8;
 }
 
 /* decode the value stored in node */
 static int tag_tree_decode(Jpeg2000DecoderContext *s, Jpeg2000TgtNode *node,
                            int threshold)
 {
     Jpeg2000TgtNode *stack[30];
     int sp = -1, curval = 0;
 
9d56ccf5
     if (!node)
09d5929f
         return AVERROR_INVALIDDATA;
9d56ccf5
 
c81a7063
     while (node && !node->vis) {
         stack[++sp] = node;
         node        = node->parent;
     }
 
     if (node)
         curval = node->val;
     else
         curval = stack[sp]->val;
 
     while (curval < threshold && sp >= 0) {
         if (curval < stack[sp]->val)
             curval = stack[sp]->val;
         while (curval < threshold) {
             int ret;
             if ((ret = get_bits(s, 1)) > 0) {
                 stack[sp]->vis++;
                 break;
             } else if (!ret)
                 curval++;
             else
                 return ret;
         }
         stack[sp]->val = curval;
         sp--;
     }
     return curval;
 }
 
b39a6bbe
 static int pix_fmt_match(enum AVPixelFormat pix_fmt, int components,
                          int bpc, uint32_t log2_chroma_wh, int pal8)
 {
     int match = 1;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
 
     if (desc->nb_components != components) {
         return 0;
     }
 
     switch (components) {
     case 4:
         match = match && desc->comp[3].depth_minus1 + 1 >= bpc &&
                          (log2_chroma_wh >> 14 & 3) == 0 &&
                          (log2_chroma_wh >> 12 & 3) == 0;
     case 3:
         match = match && desc->comp[2].depth_minus1 + 1 >= bpc &&
                          (log2_chroma_wh >> 10 & 3) == desc->log2_chroma_w &&
                          (log2_chroma_wh >>  8 & 3) == desc->log2_chroma_h;
     case 2:
         match = match && desc->comp[1].depth_minus1 + 1 >= bpc &&
                          (log2_chroma_wh >>  6 & 3) == desc->log2_chroma_w &&
                          (log2_chroma_wh >>  4 & 3) == desc->log2_chroma_h;
 
     case 1:
         match = match && desc->comp[0].depth_minus1 + 1 >= bpc &&
                          (log2_chroma_wh >>  2 & 3) == 0 &&
                          (log2_chroma_wh       & 3) == 0 &&
                          (desc->flags & AV_PIX_FMT_FLAG_PAL) == pal8 * AV_PIX_FMT_FLAG_PAL;
     }
     return match;
 }
 
 // pix_fmts with lower bpp have to be listed before
 // similar pix_fmts with higher bpp.
 #define RGB_PIXEL_FORMATS   AV_PIX_FMT_PAL8,AV_PIX_FMT_RGB24,AV_PIX_FMT_RGBA,AV_PIX_FMT_RGB48,AV_PIX_FMT_RGBA64
 #define GRAY_PIXEL_FORMATS  AV_PIX_FMT_GRAY8,AV_PIX_FMT_GRAY8A,AV_PIX_FMT_GRAY16
 #define YUV_PIXEL_FORMATS   AV_PIX_FMT_YUV410P,AV_PIX_FMT_YUV411P,AV_PIX_FMT_YUVA420P, \
                             AV_PIX_FMT_YUV420P,AV_PIX_FMT_YUV422P,AV_PIX_FMT_YUVA422P, \
                             AV_PIX_FMT_YUV440P,AV_PIX_FMT_YUV444P,AV_PIX_FMT_YUVA444P, \
                             AV_PIX_FMT_YUV420P9,AV_PIX_FMT_YUV422P9,AV_PIX_FMT_YUV444P9, \
                             AV_PIX_FMT_YUVA420P9,AV_PIX_FMT_YUVA422P9,AV_PIX_FMT_YUVA444P9, \
                             AV_PIX_FMT_YUV420P10,AV_PIX_FMT_YUV422P10,AV_PIX_FMT_YUV444P10, \
                             AV_PIX_FMT_YUVA420P10,AV_PIX_FMT_YUVA422P10,AV_PIX_FMT_YUVA444P10, \
                             AV_PIX_FMT_YUV420P12,AV_PIX_FMT_YUV422P12,AV_PIX_FMT_YUV444P12, \
                             AV_PIX_FMT_YUV420P14,AV_PIX_FMT_YUV422P14,AV_PIX_FMT_YUV444P14, \
                             AV_PIX_FMT_YUV420P16,AV_PIX_FMT_YUV422P16,AV_PIX_FMT_YUV444P16, \
                             AV_PIX_FMT_YUVA420P16,AV_PIX_FMT_YUVA422P16,AV_PIX_FMT_YUVA444P16
 #define XYZ_PIXEL_FORMATS   AV_PIX_FMT_XYZ12
 
 static const enum AVPixelFormat rgb_pix_fmts[]  = {RGB_PIXEL_FORMATS};
 static const enum AVPixelFormat gray_pix_fmts[] = {GRAY_PIXEL_FORMATS};
 static const enum AVPixelFormat yuv_pix_fmts[]  = {YUV_PIXEL_FORMATS};
 static const enum AVPixelFormat xyz_pix_fmts[]  = {XYZ_PIXEL_FORMATS};
 static const enum AVPixelFormat all_pix_fmts[]  = {RGB_PIXEL_FORMATS,
                                                    GRAY_PIXEL_FORMATS,
                                                    YUV_PIXEL_FORMATS,
                                                    XYZ_PIXEL_FORMATS};
 
c81a7063
 /* marker segments */
 /* get sizes and offsets of image, tiles; number of components */
 static int get_siz(Jpeg2000DecoderContext *s)
 {
     int i;
129edcb5
     int ncomponents;
b39a6bbe
     uint32_t log2_chroma_wh = 0;
     const enum AVPixelFormat *possible_fmts = NULL;
     int possible_fmts_nb = 0;
c81a7063
 
0b426316
     if (bytestream2_get_bytes_left(&s->g) < 36)
26f6acc6
         return AVERROR_INVALIDDATA;
c81a7063
 
0b426316
     s->avctx->profile = bytestream2_get_be16u(&s->g); // Rsiz
     s->width          = bytestream2_get_be32u(&s->g); // Width
     s->height         = bytestream2_get_be32u(&s->g); // Height
     s->image_offset_x = bytestream2_get_be32u(&s->g); // X0Siz
     s->image_offset_y = bytestream2_get_be32u(&s->g); // Y0Siz
     s->tile_width     = bytestream2_get_be32u(&s->g); // XTSiz
     s->tile_height    = bytestream2_get_be32u(&s->g); // YTSiz
     s->tile_offset_x  = bytestream2_get_be32u(&s->g); // XT0Siz
     s->tile_offset_y  = bytestream2_get_be32u(&s->g); // YT0Siz
129edcb5
     ncomponents       = bytestream2_get_be16u(&s->g); // CSiz
c81a7063
 
780669ef
     if (s->image_offset_x || s->image_offset_y) {
         avpriv_request_sample(s->avctx, "Support for image offsets");
         return AVERROR_PATCHWELCOME;
     }
 
278a923c
     if (ncomponents <= 0) {
         av_log(s->avctx, AV_LOG_ERROR, "Invalid number of components: %d\n",
                s->ncomponents);
26f6acc6
         return AVERROR_INVALIDDATA;
069ede29
     }
278a923c
 
f0358dc1
     if (ncomponents > 4) {
278a923c
         avpriv_request_sample(s->avctx, "Support for %d components",
                               s->ncomponents);
         return AVERROR_PATCHWELCOME;
     }
 
129edcb5
     s->ncomponents = ncomponents;
 
f0358dc1
     if (s->tile_width <= 0 || s->tile_height <= 0) {
278a923c
         av_log(s->avctx, AV_LOG_ERROR, "Invalid tile dimension %dx%d.\n",
                s->tile_width, s->tile_height);
5efadcb8
         return AVERROR_INVALIDDATA;
278a923c
     }
069ede29
 
0b426316
     if (bytestream2_get_bytes_left(&s->g) < 3 * s->ncomponents)
5efadcb8
         return AVERROR_INVALIDDATA;
c81a7063
 
     for (i = 0; i < s->ncomponents; i++) { // Ssiz_i XRsiz_i, YRsiz_i
1a3598aa
         uint8_t x    = bytestream2_get_byteu(&s->g);
c81a7063
         s->cbps[i]   = (x & 0x7f) + 1;
         s->precision = FFMAX(s->cbps[i], s->precision);
9d56ccf5
         s->sgnd[i]   = !!(x & 0x80);
0b426316
         s->cdx[i]    = bytestream2_get_byteu(&s->g);
         s->cdy[i]    = bytestream2_get_byteu(&s->g);
8bb11c3c
         if (   !s->cdx[i] || s->cdx[i] == 3 || s->cdx[i] > 4
             || !s->cdy[i] || s->cdy[i] == 3 || s->cdy[i] > 4) {
04427182
             av_log(s->avctx, AV_LOG_ERROR, "Invalid sample separation %d/%d\n", s->cdx[i], s->cdy[i]);
5cd57e87
             return AVERROR_INVALIDDATA;
         }
b39a6bbe
         log2_chroma_wh |= s->cdy[i] >> 1 << i * 4 | s->cdx[i] >> 1 << i * 4 + 2;
c81a7063
     }
 
     s->numXtiles = ff_jpeg2000_ceildiv(s->width  - s->tile_offset_x, s->tile_width);
     s->numYtiles = ff_jpeg2000_ceildiv(s->height - s->tile_offset_y, s->tile_height);
 
f0358dc1
     if (s->numXtiles * (uint64_t)s->numYtiles > INT_MAX/sizeof(*s->tile)) {
         s->numXtiles = s->numYtiles = 0;
53f04424
         return AVERROR(EINVAL);
f0358dc1
     }
53f04424
 
278a923c
     s->tile = av_mallocz_array(s->numXtiles * s->numYtiles, sizeof(*s->tile));
     if (!s->tile) {
         s->numXtiles = s->numYtiles = 0;
c81a7063
         return AVERROR(ENOMEM);
278a923c
     }
c81a7063
 
     for (i = 0; i < s->numXtiles * s->numYtiles; i++) {
         Jpeg2000Tile *tile = s->tile + i;
 
         tile->comp = av_mallocz(s->ncomponents * sizeof(*tile->comp));
         if (!tile->comp)
             return AVERROR(ENOMEM);
     }
 
     /* compute image size with reduction factor */
     s->avctx->width  = ff_jpeg2000_ceildivpow2(s->width  - s->image_offset_x,
                                                s->reduction_factor);
     s->avctx->height = ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y,
                                                s->reduction_factor);
 
b39a6bbe
     if (s->avctx->profile == FF_PROFILE_JPEG2000_DCINEMA_2K ||
         s->avctx->profile == FF_PROFILE_JPEG2000_DCINEMA_4K) {
         possible_fmts = xyz_pix_fmts;
         possible_fmts_nb = FF_ARRAY_ELEMS(xyz_pix_fmts);
     } else {
         switch (s->colour_space) {
         case 16:
             possible_fmts = rgb_pix_fmts;
             possible_fmts_nb = FF_ARRAY_ELEMS(rgb_pix_fmts);
             break;
         case 17:
             possible_fmts = gray_pix_fmts;
             possible_fmts_nb = FF_ARRAY_ELEMS(gray_pix_fmts);
             break;
         case 18:
             possible_fmts = yuv_pix_fmts;
             possible_fmts_nb = FF_ARRAY_ELEMS(yuv_pix_fmts);
c81a7063
             break;
310f9dd6
         default:
b39a6bbe
             possible_fmts = all_pix_fmts;
             possible_fmts_nb = FF_ARRAY_ELEMS(all_pix_fmts);
c81a7063
             break;
         }
b39a6bbe
     }
     for (i = 0; i < possible_fmts_nb; ++i) {
         if (pix_fmt_match(possible_fmts[i], ncomponents, s->precision, log2_chroma_wh, s->pal8)) {
             s->avctx->pix_fmt = possible_fmts[i];
             break;
         }
     }
8001e9f7
     if (i == possible_fmts_nb) {
b39a6bbe
         av_log(s->avctx, AV_LOG_ERROR,
                "Unknown pix_fmt, profile: %d, colour_space: %d, "
                "components: %d, precision: %d, "
                "cdx[1]: %d, cdy[1]: %d, cdx[2]: %d, cdy[2]: %d\n",
                s->avctx->profile, s->colour_space, ncomponents, s->precision,
                ncomponents > 2 ? s->cdx[1] : 0,
                ncomponents > 2 ? s->cdy[1] : 0,
                ncomponents > 2 ? s->cdx[2] : 0,
                ncomponents > 2 ? s->cdy[2] : 0);
8001e9f7
         return AVERROR_PATCHWELCOME;
c81a7063
     }
f99f7f40
     s->avctx->bits_per_raw_sample = s->precision;
c81a7063
     return 0;
 }
 
 /* get common part for COD and COC segments */
 static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c)
 {
     uint8_t byte;
 
0b426316
     if (bytestream2_get_bytes_left(&s->g) < 5)
26f6acc6
         return AVERROR_INVALIDDATA;
1a3598aa
 
5650e331
     /*  nreslevels = number of resolution levels
                    = number of decomposition level +1 */
37a970bb
     c->nreslevels = bytestream2_get_byteu(&s->g) + 1;
bd89b2b2
     if (c->nreslevels >= JPEG2000_MAX_RESLEVELS) {
         av_log(s->avctx, AV_LOG_ERROR, "nreslevels %d is invalid\n", c->nreslevels);
         return AVERROR_INVALIDDATA;
     }
c81a7063
 
a1b9004b
     if (c->nreslevels <= s->reduction_factor) {
         /* we are forced to update reduction_factor as its requested value is
            not compatible with this bitstream, and as we might have used it
            already in setup earlier we have to fail this frame until
            reinitialization is implemented */
         av_log(s->avctx, AV_LOG_ERROR, "reduction_factor too large for this bitstream, max is %d\n", c->nreslevels - 1);
         s->reduction_factor = c->nreslevels - 1;
         return AVERROR(EINVAL);
     }
 
c81a7063
     /* compute number of resolution levels to decode */
a1b9004b
     c->nreslevels2decode = c->nreslevels - s->reduction_factor;
c81a7063
 
cb39dfb8
     c->log2_cblk_width  = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk width
     c->log2_cblk_height = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk height
 
     if (c->log2_cblk_width > 10 || c->log2_cblk_height > 10 ||
fbcc03db
         c->log2_cblk_width + c->log2_cblk_height > 12) {
cb39dfb8
         av_log(s->avctx, AV_LOG_ERROR, "cblk size invalid\n");
         return AVERROR_INVALIDDATA;
     }
c81a7063
 
9a271a93
     if (c->log2_cblk_width > 6 || c->log2_cblk_height > 6) {
         avpriv_request_sample(s->avctx, "cblk size > 64");
         return AVERROR_PATCHWELCOME;
     }
 
0b426316
     c->cblk_style = bytestream2_get_byteu(&s->g);
c81a7063
     if (c->cblk_style != 0) { // cblk style
9d56ccf5
         av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style);
c81a7063
     }
0b426316
     c->transform = bytestream2_get_byteu(&s->g); // DWT transformation type
c81a7063
     /* set integer 9/7 DWT in case of BITEXACT flag */
     if ((s->avctx->flags & CODEC_FLAG_BITEXACT) && (c->transform == FF_DWT97))
         c->transform = FF_DWT97_INT;
 
     if (c->csty & JPEG2000_CSTY_PREC) {
         int i;
         for (i = 0; i < c->nreslevels; i++) {
0b426316
             byte = bytestream2_get_byte(&s->g);
c81a7063
             c->log2_prec_widths[i]  =  byte       & 0x0F;    // precinct PPx
             c->log2_prec_heights[i] = (byte >> 4) & 0x0F;    // precinct PPy
         }
bd89b2b2
     } else {
         memset(c->log2_prec_widths , 15, sizeof(c->log2_prec_widths ));
         memset(c->log2_prec_heights, 15, sizeof(c->log2_prec_heights));
c81a7063
     }
     return 0;
 }
 
 /* get coding parameters for a particular tile or whole image*/
 static int get_cod(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c,
                    uint8_t *properties)
 {
     Jpeg2000CodingStyle tmp;
66c4d544
     int compno, ret;
c81a7063
 
0b426316
     if (bytestream2_get_bytes_left(&s->g) < 5)
5efadcb8
         return AVERROR_INVALIDDATA;
c81a7063
 
0b426316
     tmp.csty = bytestream2_get_byteu(&s->g);
c81a7063
 
     // get progression order
0b426316
     tmp.prog_order = bytestream2_get_byteu(&s->g);
c81a7063
 
1a3598aa
     tmp.nlayers    = bytestream2_get_be16u(&s->g);
     tmp.mct        = bytestream2_get_byteu(&s->g); // multiple component transformation
c81a7063
 
21d0f75f
     if (tmp.mct && s->ncomponents < 3) {
cf04af20
         av_log(s->avctx, AV_LOG_ERROR,
cc8163e1
                "MCT %"PRIu8" with too few components (%d)\n",
cf04af20
                tmp.mct, s->ncomponents);
21d0f75f
         return AVERROR_INVALIDDATA;
     }
 
66c4d544
     if ((ret = get_cox(s, &tmp)) < 0)
         return ret;
 
c81a7063
     for (compno = 0; compno < s->ncomponents; compno++)
         if (!(properties[compno] & HAD_COC))
             memcpy(c + compno, &tmp, sizeof(tmp));
     return 0;
 }
 
 /* Get coding parameters for a component in the whole image or a
  * particular tile. */
 static int get_coc(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c,
                    uint8_t *properties)
 {
66c4d544
     int compno, ret;
c81a7063
 
0b426316
     if (bytestream2_get_bytes_left(&s->g) < 2)
5efadcb8
         return AVERROR_INVALIDDATA;
c81a7063
 
0b426316
     compno = bytestream2_get_byteu(&s->g);
c81a7063
 
e850a064
     if (compno >= s->ncomponents) {
eae63e3c
         av_log(s->avctx, AV_LOG_ERROR,
                "Invalid compno %d. There are %d components in the image.\n",
                compno, s->ncomponents);
e850a064
         return AVERROR_INVALIDDATA;
     }
 
c81a7063
     c      += compno;
0b426316
     c->csty = bytestream2_get_byteu(&s->g);
66c4d544
 
     if ((ret = get_cox(s, c)) < 0)
         return ret;
c81a7063
 
     properties[compno] |= HAD_COC;
     return 0;
 }
 
 /* Get common part for QCD and QCC segments. */
 static int get_qcx(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q)
 {
     int i, x;
 
0b426316
     if (bytestream2_get_bytes_left(&s->g) < 1)
5efadcb8
         return AVERROR_INVALIDDATA;
c81a7063
 
0b426316
     x = bytestream2_get_byteu(&s->g); // Sqcd
c81a7063
 
     q->nguardbits = x >> 5;
     q->quantsty   = x & 0x1f;
 
     if (q->quantsty == JPEG2000_QSTY_NONE) {
         n -= 3;
1a3598aa
         if (bytestream2_get_bytes_left(&s->g) < n ||
57bc64e2
             n > JPEG2000_MAX_DECLEVELS*3)
5efadcb8
             return AVERROR_INVALIDDATA;
c81a7063
         for (i = 0; i < n; i++)
0b426316
             q->expn[i] = bytestream2_get_byteu(&s->g) >> 3;
c81a7063
     } else if (q->quantsty == JPEG2000_QSTY_SI) {
0b426316
         if (bytestream2_get_bytes_left(&s->g) < 2)
5efadcb8
             return AVERROR_INVALIDDATA;
0b426316
         x          = bytestream2_get_be16u(&s->g);
c81a7063
         q->expn[0] = x >> 11;
         q->mant[0] = x & 0x7ff;
be327100
         for (i = 1; i < JPEG2000_MAX_DECLEVELS * 3; i++) {
c81a7063
             int curexpn = FFMAX(0, q->expn[0] - (i - 1) / 3);
             q->expn[i] = curexpn;
             q->mant[i] = q->mant[0];
         }
     } else {
         n = (n - 3) >> 1;
1a3598aa
         if (bytestream2_get_bytes_left(&s->g) < 2 * n ||
57bc64e2
             n > JPEG2000_MAX_DECLEVELS*3)
5efadcb8
             return AVERROR_INVALIDDATA;
c81a7063
         for (i = 0; i < n; i++) {
0b426316
             x          = bytestream2_get_be16u(&s->g);
c81a7063
             q->expn[i] = x >> 11;
             q->mant[i] = x & 0x7ff;
         }
     }
     return 0;
 }
 
 /* Get quantization parameters for a particular tile or a whole image. */
 static int get_qcd(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q,
                    uint8_t *properties)
 {
     Jpeg2000QuantStyle tmp;
5efadcb8
     int compno, ret;
c81a7063
 
55fa8989
     memset(&tmp, 0, sizeof(tmp));
 
5efadcb8
     if ((ret = get_qcx(s, n, &tmp)) < 0)
         return ret;
c81a7063
     for (compno = 0; compno < s->ncomponents; compno++)
         if (!(properties[compno] & HAD_QCC))
             memcpy(q + compno, &tmp, sizeof(tmp));
     return 0;
 }
 
 /* Get quantization parameters for a component in the whole image
  * on in a particular tile. */
 static int get_qcc(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q,
                    uint8_t *properties)
 {
     int compno;
 
0b426316
     if (bytestream2_get_bytes_left(&s->g) < 1)
5efadcb8
         return AVERROR_INVALIDDATA;
c81a7063
 
eae63e3c
     compno = bytestream2_get_byteu(&s->g);
 
c59ce1c9
     if (compno >= s->ncomponents) {
eae63e3c
         av_log(s->avctx, AV_LOG_ERROR,
                "Invalid compno %d. There are %d components in the image.\n",
                compno, s->ncomponents);
c59ce1c9
         return AVERROR_INVALIDDATA;
     }
 
c81a7063
     properties[compno] |= HAD_QCC;
     return get_qcx(s, n - 1, q + compno);
 }
 
 /* Get start of tile segment. */
f399b33c
 static int get_sot(Jpeg2000DecoderContext *s, int n)
c81a7063
 {
     Jpeg2000TilePart *tp;
     uint16_t Isot;
     uint32_t Psot;
     uint8_t TPsot;
 
0b426316
     if (bytestream2_get_bytes_left(&s->g) < 8)
5efadcb8
         return AVERROR_INVALIDDATA;
c81a7063
 
2e85737b
     s->curtileno = 0;
1a3598aa
     Isot = bytestream2_get_be16u(&s->g);        // Isot
d3cb302b
     if (Isot >= s->numXtiles * s->numYtiles)
26f6acc6
         return AVERROR_INVALIDDATA;
d3cb302b
 
2e85737b
     s->curtileno = Isot;
0b426316
     Psot  = bytestream2_get_be32u(&s->g);       // Psot
     TPsot = bytestream2_get_byteu(&s->g);       // TPsot
c81a7063
 
     /* Read TNSot but not used */
0b426316
     bytestream2_get_byteu(&s->g);               // TNsot
c81a7063
 
5deb96c5
     if (Psot > bytestream2_get_bytes_left(&s->g) + n + 2) {
cc8163e1
         av_log(s->avctx, AV_LOG_ERROR, "Psot %"PRIu32" too big\n", Psot);
5deb96c5
         return AVERROR_INVALIDDATA;
     }
d3cb302b
 
     if (TPsot >= FF_ARRAY_ELEMS(s->tile[Isot].tile_part)) {
cc8163e1
         avpriv_request_sample(s->avctx, "Support for %"PRIu8" components", TPsot);
73ffab41
         return AVERROR_PATCHWELCOME;
     }
 
aa16bbaf
     s->tile[Isot].tp_idx = TPsot;
     tp             = s->tile[Isot].tile_part + TPsot;
c81a7063
     tp->tile_index = Isot;
9d56ccf5
     tp->tp_end     = s->g.buffer + Psot - n - 2;
 
     if (!TPsot) {
         Jpeg2000Tile *tile = s->tile + s->curtileno;
c81a7063
 
9d56ccf5
         /* copy defaults */
         memcpy(tile->codsty, s->codsty, s->ncomponents * sizeof(Jpeg2000CodingStyle));
         memcpy(tile->qntsty, s->qntsty, s->ncomponents * sizeof(Jpeg2000QuantStyle));
     }
c81a7063
 
     return 0;
 }
 
 /* Tile-part lengths: see ISO 15444-1:2002, section A.7.1
  * Used to know the number of tile parts and lengths.
  * There may be multiple TLMs in the header.
  * TODO: The function is not used for tile-parts management, nor anywhere else.
  * It can be useful to allocate memory for tile parts, before managing the SOT
  * markers. Parsing the TLM header is needed to increment the input header
  * buffer.
  * This marker is mandatory for DCI. */
 static uint8_t get_tlm(Jpeg2000DecoderContext *s, int n)
 {
     uint8_t Stlm, ST, SP, tile_tlm, i;
0b426316
     bytestream2_get_byte(&s->g);               /* Ztlm: skipped */
     Stlm = bytestream2_get_byte(&s->g);
c81a7063
 
     // too complex ? ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);
     ST = (Stlm >> 4) & 0x03;
     // TODO: Manage case of ST = 0b11 --> raise error
     SP       = (Stlm >> 6) & 0x01;
     tile_tlm = (n - 4) / ((SP + 1) * 2 + ST);
     for (i = 0; i < tile_tlm; i++) {
         switch (ST) {
         case 0:
             break;
         case 1:
0b426316
             bytestream2_get_byte(&s->g);
c81a7063
             break;
         case 2:
0b426316
             bytestream2_get_be16(&s->g);
c81a7063
             break;
         case 3:
0b426316
             bytestream2_get_be32(&s->g);
c81a7063
             break;
         }
         if (SP == 0) {
0b426316
             bytestream2_get_be16(&s->g);
c81a7063
         } else {
0b426316
             bytestream2_get_be32(&s->g);
c81a7063
         }
     }
     return 0;
 }
 
 static int init_tile(Jpeg2000DecoderContext *s, int tileno)
 {
     int compno;
     int tilex = tileno % s->numXtiles;
     int tiley = tileno / s->numXtiles;
     Jpeg2000Tile *tile = s->tile + tileno;
 
     if (!tile->comp)
         return AVERROR(ENOMEM);
 
     for (compno = 0; compno < s->ncomponents; compno++) {
         Jpeg2000Component *comp = tile->comp + compno;
7a2b6342
         Jpeg2000CodingStyle *codsty = tile->codsty + compno;
         Jpeg2000QuantStyle  *qntsty = tile->qntsty + compno;
c81a7063
         int ret; // global bandno
 
         comp->coord_o[0][0] = FFMAX(tilex       * s->tile_width  + s->tile_offset_x, s->image_offset_x);
         comp->coord_o[0][1] = FFMIN((tilex + 1) * s->tile_width  + s->tile_offset_x, s->width);
         comp->coord_o[1][0] = FFMAX(tiley       * s->tile_height + s->tile_offset_y, s->image_offset_y);
         comp->coord_o[1][1] = FFMIN((tiley + 1) * s->tile_height + s->tile_offset_y, s->height);
 
8cf57efd
         comp->coord[0][0] = ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], s->reduction_factor);
         comp->coord[0][1] = ff_jpeg2000_ceildivpow2(comp->coord_o[0][1], s->reduction_factor);
         comp->coord[1][0] = ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], s->reduction_factor);
         comp->coord[1][1] = ff_jpeg2000_ceildivpow2(comp->coord_o[1][1], s->reduction_factor);
c81a7063
 
         if (ret = ff_jpeg2000_init_component(comp, codsty, qntsty,
                                              s->cbps[compno], s->cdx[compno],
                                              s->cdy[compno], s->avctx))
             return ret;
     }
     return 0;
 }
 
 /* Read the number of coding passes. */
 static int getnpasses(Jpeg2000DecoderContext *s)
 {
     int num;
     if (!get_bits(s, 1))
         return 1;
     if (!get_bits(s, 1))
         return 2;
     if ((num = get_bits(s, 2)) != 3)
         return num < 0 ? num : 3 + num;
     if ((num = get_bits(s, 5)) != 31)
         return num < 0 ? num : 6 + num;
     num = get_bits(s, 7);
     return num < 0 ? num : 37 + num;
 }
 
 static int getlblockinc(Jpeg2000DecoderContext *s)
 {
     int res = 0, ret;
     while (ret = get_bits(s, 1)) {
         if (ret < 0)
             return ret;
         res++;
     }
     return res;
 }
 
 static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s,
                                   Jpeg2000CodingStyle *codsty,
                                   Jpeg2000ResLevel *rlevel, int precno,
                                   int layno, uint8_t *expn, int numgbits)
 {
     int bandno, cblkno, ret, nb_code_blocks;
 
     if (!(ret = get_bits(s, 1))) {
         jpeg2000_flush(s);
         return 0;
     } else if (ret < 0)
         return ret;
 
     for (bandno = 0; bandno < rlevel->nbands; bandno++) {
         Jpeg2000Band *band = rlevel->band + bandno;
         Jpeg2000Prec *prec = band->prec + precno;
 
         if (band->coord[0][0] == band->coord[0][1] ||
             band->coord[1][0] == band->coord[1][1])
             continue;
         nb_code_blocks =  prec->nb_codeblocks_height *
                           prec->nb_codeblocks_width;
         for (cblkno = 0; cblkno < nb_code_blocks; cblkno++) {
             Jpeg2000Cblk *cblk = prec->cblk + cblkno;
             int incl, newpasses, llen;
 
             if (cblk->npasses)
                 incl = get_bits(s, 1);
             else
                 incl = tag_tree_decode(s, prec->cblkincl + cblkno, layno + 1) == layno;
             if (!incl)
                 continue;
             else if (incl < 0)
                 return incl;
 
3b861742
             if (!cblk->npasses) {
                 int v = expn[bandno] + numgbits - 1 -
17e5d614
                         tag_tree_decode(s, prec->zerobits + cblkno, 100);
3b861742
                 if (v < 0) {
17e5d614
                     av_log(s->avctx, AV_LOG_ERROR,
                            "nonzerobits %d invalid\n", v);
3b861742
                     return AVERROR_INVALIDDATA;
                 }
                 cblk->nonzerobits = v;
             }
c81a7063
             if ((newpasses = getnpasses(s)) < 0)
                 return newpasses;
             if ((llen = getlblockinc(s)) < 0)
                 return llen;
             cblk->lblock += llen;
             if ((ret = get_bits(s, av_log2(newpasses) + cblk->lblock)) < 0)
                 return ret;
7e201d57
             if (ret > sizeof(cblk->data)) {
                 avpriv_request_sample(s->avctx,
ced0d6c1
                                       "Block with lengthinc greater than %"SIZE_SPECIFIER"",
7e201d57
                                       sizeof(cblk->data));
                 return AVERROR_PATCHWELCOME;
             }
c81a7063
             cblk->lengthinc = ret;
             cblk->npasses  += newpasses;
         }
     }
     jpeg2000_flush(s);
 
     if (codsty->csty & JPEG2000_CSTY_EPH) {
0b426316
         if (bytestream2_peek_be16(&s->g) == JPEG2000_EPH)
             bytestream2_skip(&s->g, 2);
c81a7063
         else
             av_log(s->avctx, AV_LOG_ERROR, "EPH marker not found.\n");
     }
 
     for (bandno = 0; bandno < rlevel->nbands; bandno++) {
         Jpeg2000Band *band = rlevel->band + bandno;
         Jpeg2000Prec *prec = band->prec + precno;
 
         nb_code_blocks = prec->nb_codeblocks_height * prec->nb_codeblocks_width;
         for (cblkno = 0; cblkno < nb_code_blocks; cblkno++) {
             Jpeg2000Cblk *cblk = prec->cblk + cblkno;
914ab4cd
             if (   bytestream2_get_bytes_left(&s->g) < cblk->lengthinc
582f5334
                 || sizeof(cblk->data) < cblk->length + cblk->lengthinc + 2
e96c8015
             ) {
                 av_log(s->avctx, AV_LOG_ERROR,
8d024c51
                        "Block length %"PRIu16" or lengthinc %d is too large\n",
e96c8015
                        cblk->length, cblk->lengthinc);
5efadcb8
                 return AVERROR_INVALIDDATA;
28816f9d
             }
582f5334
 
             bytestream2_get_bufferu(&s->g, cblk->data + cblk->length, cblk->lengthinc);
c81a7063
             cblk->length   += cblk->lengthinc;
             cblk->lengthinc = 0;
         }
     }
     return 0;
 }
 
 static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
 {
d57c737a
     int ret = 0;
     int layno, reslevelno, compno, precno, ok_reslevel;
fd7e1190
     int x, y;
c81a7063
 
     s->bit_index = 8;
fd7e1190
     switch (tile->codsty[0].prog_order) {
9d56ccf5
     case JPEG2000_PGOD_RLCP:
19ff6f55
         avpriv_request_sample(s->avctx, "Progression order RLCP");
 
c81a7063
     case JPEG2000_PGOD_LRCP:
         for (layno = 0; layno < tile->codsty[0].nlayers; layno++) {
             ok_reslevel = 1;
             for (reslevelno = 0; ok_reslevel; reslevelno++) {
                 ok_reslevel = 0;
                 for (compno = 0; compno < s->ncomponents; compno++) {
                     Jpeg2000CodingStyle *codsty = tile->codsty + compno;
                     Jpeg2000QuantStyle *qntsty  = tile->qntsty + compno;
                     if (reslevelno < codsty->nreslevels) {
                         Jpeg2000ResLevel *rlevel = tile->comp[compno].reslevel +
9d56ccf5
                                                 reslevelno;
c81a7063
                         ok_reslevel = 1;
                         for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++)
5efadcb8
                             if ((ret = jpeg2000_decode_packet(s,
                                                               codsty, rlevel,
                                                               precno, layno,
                                                               qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
                                                               qntsty->nguardbits)) < 0)
                                 return ret;
c81a7063
                     }
                 }
             }
         }
         break;
 
     case JPEG2000_PGOD_CPRL:
         for (compno = 0; compno < s->ncomponents; compno++) {
             Jpeg2000CodingStyle *codsty = tile->codsty + compno;
             Jpeg2000QuantStyle *qntsty  = tile->qntsty + compno;
 
             /* Set bit stream buffer address according to tile-part.
              * For DCinema one tile-part per component, so can be
              * indexed by component. */
0b426316
             s->g = tile->tile_part[compno].tpg;
c81a7063
 
             /* Position loop (y axis)
              * TODO: Automate computing of step 256.
              * Fixed here, but to be computed before entering here. */
             for (y = 0; y < s->height; y += 256) {
                 /* Position loop (y axis)
                  * TODO: automate computing of step 256.
                  * Fixed here, but to be computed before entering here. */
                 for (x = 0; x < s->width; x += 256) {
                     for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) {
                         uint16_t prcx, prcy;
                         uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; //  ==> N_L - r
                         Jpeg2000ResLevel *rlevel = tile->comp[compno].reslevel + reslevelno;
 
                         if (!((y % (1 << (rlevel->log2_prec_height + reducedresno)) == 0) ||
                               (y == 0))) // TODO: 2nd condition simplified as try0 always =0 for dcinema
                             continue;
 
                         if (!((x % (1 << (rlevel->log2_prec_width + reducedresno)) == 0) ||
                               (x == 0))) // TODO: 2nd condition simplified as try0 always =0 for dcinema
                             continue;
 
                         // check if a precinct exists
                         prcx   = ff_jpeg2000_ceildivpow2(x, reducedresno) >> rlevel->log2_prec_width;
                         prcy   = ff_jpeg2000_ceildivpow2(y, reducedresno) >> rlevel->log2_prec_height;
                         precno = prcx + rlevel->num_precincts_x * prcy;
3d5a5e86
 
                         if (prcx >= rlevel->num_precincts_x || prcy >= rlevel->num_precincts_y)
                             return AVERROR_PATCHWELCOME;
 
c81a7063
                         for (layno = 0; layno < tile->codsty[0].nlayers; layno++) {
5efadcb8
                             if ((ret = jpeg2000_decode_packet(s, codsty, rlevel,
                                                               precno, layno,
                                                               qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
                                                               qntsty->nguardbits)) < 0)
                                 return ret;
c81a7063
                         }
                     }
                 }
             }
         }
         break;
 
d57c737a
     case JPEG2000_PGOD_RPCL:
         avpriv_request_sample(s->avctx, "Progression order RPCL");
         ret = AVERROR_PATCHWELCOME;
         break;
 
     case JPEG2000_PGOD_PCRL:
         avpriv_request_sample(s->avctx, "Progression order PCRL");
         ret = AVERROR_PATCHWELCOME;
         break;
 
c81a7063
     default:
         break;
     }
 
     /* EOC marker reached */
0b426316
     bytestream2_skip(&s->g, 2);
c81a7063
 
d57c737a
     return ret;
c81a7063
 }
 
 /* TIER-1 routines */
 static void decode_sigpass(Jpeg2000T1Context *t1, int width, int height,
9d56ccf5
                            int bpno, int bandno, int bpass_csty_symbol,
                            int vert_causal_ctx_csty_symbol)
c81a7063
 {
     int mask = 3 << (bpno - 1), y0, x, y;
 
     for (y0 = 0; y0 < height; y0 += 4)
         for (x = 0; x < width; x++)
9d56ccf5
             for (y = y0; y < height && y < y0 + 4; y++) {
                 if ((t1->flags[y+1][x+1] & JPEG2000_T1_SIG_NB)
                 && !(t1->flags[y+1][x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) {
                     int flags_mask = -1;
                     if (vert_causal_ctx_csty_symbol && y == y0 + 3)
                         flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE);
                     if (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_jpeg2000_getsigctxno(t1->flags[y+1][x+1] & flags_mask, bandno))) {
                         int xorbit, ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y+1][x+1], &xorbit);
                         if (bpass_csty_symbol)
                              t1->data[y][x] = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ? -mask : mask;
                         else
                              t1->data[y][x] = (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ^ xorbit) ?
                                                -mask : mask;
c81a7063
 
                         ff_jpeg2000_set_significance(t1, x, y,
                                                      t1->data[y][x] < 0);
                     }
                     t1->flags[y + 1][x + 1] |= JPEG2000_T1_VIS;
                 }
9d56ccf5
             }
c81a7063
 }
 
 static void decode_refpass(Jpeg2000T1Context *t1, int width, int height,
                            int bpno)
 {
     int phalf, nhalf;
     int y0, x, y;
 
     phalf = 1 << (bpno - 1);
     nhalf = -phalf;
 
     for (y0 = 0; y0 < height; y0 += 4)
         for (x = 0; x < width; x++)
             for (y = y0; y < height && y < y0 + 4; y++)
                 if ((t1->flags[y + 1][x + 1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS)) == JPEG2000_T1_SIG) {
                     int ctxno = ff_jpeg2000_getrefctxno(t1->flags[y + 1][x + 1]);
                     int r     = ff_mqc_decode(&t1->mqc,
                                               t1->mqc.cx_states + ctxno)
                                 ? phalf : nhalf;
                     t1->data[y][x]          += t1->data[y][x] < 0 ? -r : r;
                     t1->flags[y + 1][x + 1] |= JPEG2000_T1_REF;
                 }
 }
 
 static void decode_clnpass(Jpeg2000DecoderContext *s, Jpeg2000T1Context *t1,
                            int width, int height, int bpno, int bandno,
9d56ccf5
                            int seg_symbols, int vert_causal_ctx_csty_symbol)
c81a7063
 {
     int mask = 3 << (bpno - 1), y0, x, y, runlen, dec;
 
9d56ccf5
     for (y0 = 0; y0 < height; y0 += 4) {
c81a7063
         for (x = 0; x < width; x++) {
             if (y0 + 3 < height &&
                 !((t1->flags[y0 + 1][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
                   (t1->flags[y0 + 2][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
                   (t1->flags[y0 + 3][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
                   (t1->flags[y0 + 4][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)))) {
                 if (!ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_RL))
                     continue;
                 runlen = ff_mqc_decode(&t1->mqc,
                                        t1->mqc.cx_states + MQC_CX_UNI);
                 runlen = (runlen << 1) | ff_mqc_decode(&t1->mqc,
                                                        t1->mqc.cx_states +
                                                        MQC_CX_UNI);
                 dec = 1;
             } else {
                 runlen = 0;
                 dec    = 0;
             }
 
             for (y = y0 + runlen; y < y0 + 4 && y < height; y++) {
                 if (!dec) {
9d56ccf5
                     if (!(t1->flags[y+1][x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) {
                         int flags_mask = -1;
                         if (vert_causal_ctx_csty_symbol && y == y0 + 3)
                             flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE);
                         dec = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_jpeg2000_getsigctxno(t1->flags[y+1][x+1] & flags_mask,
                                                                                              bandno));
                     }
c81a7063
                 }
                 if (dec) {
                     int xorbit;
                     int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y + 1][x + 1],
                                                         &xorbit);
                     t1->data[y][x] = (ff_mqc_decode(&t1->mqc,
                                                     t1->mqc.cx_states + ctxno) ^
                                       xorbit)
                                      ? -mask : mask;
                     ff_jpeg2000_set_significance(t1, x, y, t1->data[y][x] < 0);
                 }
                 dec = 0;
                 t1->flags[y + 1][x + 1] &= ~JPEG2000_T1_VIS;
             }
         }
9d56ccf5
     }
c81a7063
     if (seg_symbols) {
         int val;
         val = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
         val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
         val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
         val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
         if (val != 0xa)
             av_log(s->avctx, AV_LOG_ERROR,
                    "Segmentation symbol value incorrect\n");
     }
 }
 
 static int decode_cblk(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty,
                        Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk,
                        int width, int height, int bandpos)
 {
     int passno = cblk->npasses, pass_t = 2, bpno = cblk->nonzerobits - 1, y;
64f6570c
     int clnpass_cnt = 0;
     int bpass_csty_symbol           = codsty->cblk_style & JPEG2000_CBLK_BYPASS;
     int vert_causal_ctx_csty_symbol = codsty->cblk_style & JPEG2000_CBLK_VSC;
c81a7063
 
9a271a93
     av_assert0(width  <= JPEG2000_MAX_CBLKW);
     av_assert0(height <= JPEG2000_MAX_CBLKH);
 
c81a7063
     for (y = 0; y < height; y++)
f67f2681
         memset(t1->data[y], 0, width * sizeof(**t1->data));
c81a7063
 
a06f0cef
     /* If code-block contains no compressed data: nothing to do. */
28816f9d
     if (!cblk->length)
a06f0cef
         return 0;
 
28816f9d
     for (y = 0; y < height + 2; y++)
589e5b52
         memset(t1->flags[y], 0, (width + 2) * sizeof(**t1->flags));
9d56ccf5
 
     cblk->data[cblk->length] = 0xff;
     cblk->data[cblk->length+1] = 0xff;
20a2d5ec
     ff_mqc_initdec(&t1->mqc, cblk->data);
c81a7063
 
     while (passno--) {
9d56ccf5
         switch(pass_t) {
c81a7063
         case 0:
9d56ccf5
             decode_sigpass(t1, width, height, bpno + 1, bandpos,
64f6570c
                            bpass_csty_symbol && (clnpass_cnt >= 4),
                            vert_causal_ctx_csty_symbol);
c81a7063
             break;
         case 1:
             decode_refpass(t1, width, height, bpno + 1);
9d56ccf5
             if (bpass_csty_symbol && clnpass_cnt >= 4)
                 ff_mqc_initdec(&t1->mqc, cblk->data);
c81a7063
             break;
         case 2:
             decode_clnpass(s, t1, width, height, bpno + 1, bandpos,
64f6570c
                            codsty->cblk_style & JPEG2000_CBLK_SEGSYM,
                            vert_causal_ctx_csty_symbol);
9d56ccf5
             clnpass_cnt = clnpass_cnt + 1;
             if (bpass_csty_symbol && clnpass_cnt >= 4)
                 ff_mqc_initdec(&t1->mqc, cblk->data);
c81a7063
             break;
         }
 
         pass_t++;
         if (pass_t == 3) {
             bpno--;
             pass_t = 0;
         }
     }
     return 0;
 }
 
 /* TODO: Verify dequantization for lossless case
  * comp->data can be float or int
  * band->stepsize can be float or int
  * depending on the type of DWT transformation.
  * see ISO/IEC 15444-1:2002 A.6.1 */
 
 /* Float dequantization of a codeblock.*/
 static void dequantization_float(int x, int y, Jpeg2000Cblk *cblk,
                                  Jpeg2000Component *comp,
                                  Jpeg2000T1Context *t1, Jpeg2000Band *band)
 {
6cbd0241
     int i, j;
     int w = cblk->coord[0][1] - cblk->coord[0][0];
     for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j) {
         float *datap = &comp->f_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x];
         int *src = t1->data[j];
         for (i = 0; i < w; ++i)
             datap[i] = src[i] * band->f_stepsize;
     }
c81a7063
 }
 
 /* Integer dequantization of a codeblock.*/
 static void dequantization_int(int x, int y, Jpeg2000Cblk *cblk,
                                Jpeg2000Component *comp,
                                Jpeg2000T1Context *t1, Jpeg2000Band *band)
 {
dc60061b
     int i, j;
     int w = cblk->coord[0][1] - cblk->coord[0][0];
     for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j) {
         int32_t *datap = &comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x];
         int *src = t1->data[j];
         for (i = 0; i < w; ++i)
f57119b8
             datap[i] = (src[i] * band->i_stepsize + (1 << 14)) >> 15;
dc60061b
     }
c81a7063
 }
 
 /* Inverse ICT parameters in float and integer.
  * int value = (float value) * (1<<16) */
 static const float f_ict_params[4] = {
     1.402f,
     0.34413f,
     0.71414f,
     1.772f
 };
 static const int   i_ict_params[4] = {
      91881,
      22553,
      46802,
     116130
 };
 
c37d735c
 static void mct_decode(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
c81a7063
 {
     int i, csize = 1;
     int32_t *src[3],  i0,  i1,  i2;
     float   *srcf[3], i0f, i1f, i2f;
 
ac3b01a9
     for (i = 1; i < 3; i++)
         if (tile->codsty[0].transform != tile->codsty[i].transform) {
             av_log(s->avctx, AV_LOG_ERROR, "Transforms mismatch, MCT not supported\n");
             return;
         }
 
c81a7063
     for (i = 0; i < 3; i++)
         if (tile->codsty[0].transform == FF_DWT97)
8bedbb82
             srcf[i] = tile->comp[i].f_data;
c81a7063
         else
8bedbb82
             src [i] = tile->comp[i].i_data;
c81a7063
 
     for (i = 0; i < 2; i++)
         csize *= tile->comp[0].coord[i][1] - tile->comp[0].coord[i][0];
cdb86136
 
c81a7063
     switch (tile->codsty[0].transform) {
     case FF_DWT97:
         for (i = 0; i < csize; i++) {
             i0f = *srcf[0] + (f_ict_params[0] * *srcf[2]);
             i1f = *srcf[0] - (f_ict_params[1] * *srcf[1])
                            - (f_ict_params[2] * *srcf[2]);
             i2f = *srcf[0] + (f_ict_params[3] * *srcf[1]);
             *srcf[0]++ = i0f;
             *srcf[1]++ = i1f;
             *srcf[2]++ = i2f;
         }
         break;
     case FF_DWT97_INT:
         for (i = 0; i < csize; i++) {
             i0 = *src[0] + (((i_ict_params[0] * *src[2]) + (1 << 15)) >> 16);
             i1 = *src[0] - (((i_ict_params[1] * *src[1]) + (1 << 15)) >> 16)
                          - (((i_ict_params[2] * *src[2]) + (1 << 15)) >> 16);
             i2 = *src[0] + (((i_ict_params[3] * *src[1]) + (1 << 15)) >> 16);
             *src[0]++ = i0;
             *src[1]++ = i1;
             *src[2]++ = i2;
         }
         break;
     case FF_DWT53:
         for (i = 0; i < csize; i++) {
             i1 = *src[0] - (*src[2] + *src[1] >> 2);
             i0 = i1 + *src[2];
             i2 = i1 + *src[1];
             *src[0]++ = i0;
             *src[1]++ = i1;
             *src[2]++ = i2;
         }
         break;
     }
 }
 
 static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
                                 AVFrame *picture)
 {
aeb2905f
     const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
c81a7063
     int compno, reslevelno, bandno;
     int x, y;
723e7b86
     int planar    = !!(pixdesc->flags & AV_PIX_FMT_FLAG_PLANAR);
     int pixelsize = planar ? 1 : pixdesc->nb_components;
c81a7063
 
     uint8_t *line;
     Jpeg2000T1Context t1;
 
3f714d1f
     /* Loop on tile components */
c81a7063
     for (compno = 0; compno < s->ncomponents; compno++) {
         Jpeg2000Component *comp     = tile->comp + compno;
         Jpeg2000CodingStyle *codsty = tile->codsty + compno;
cdb86136
 
c81a7063
         /* Loop on resolution levels */
         for (reslevelno = 0; reslevelno < codsty->nreslevels2decode; reslevelno++) {
             Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno;
             /* Loop on bands */
             for (bandno = 0; bandno < rlevel->nbands; bandno++) {
cdb86136
                 int nb_precincts, precno;
c81a7063
                 Jpeg2000Band *band = rlevel->band + bandno;
                 int cblkno = 0, bandpos;
9d56ccf5
 
c81a7063
                 bandpos = bandno + (reslevelno > 0);
 
53d5d89c
                 if (band->coord[0][0] == band->coord[0][1] ||
                     band->coord[1][0] == band->coord[1][1])
9d56ccf5
                     continue;
 
c81a7063
                 nb_precincts = rlevel->num_precincts_x * rlevel->num_precincts_y;
                 /* Loop on precincts */
                 for (precno = 0; precno < nb_precincts; precno++) {
                     Jpeg2000Prec *prec = band->prec + precno;
 
                     /* Loop on codeblocks */
                     for (cblkno = 0; cblkno < prec->nb_codeblocks_width * prec->nb_codeblocks_height; cblkno++) {
                         int x, y;
                         Jpeg2000Cblk *cblk = prec->cblk + cblkno;
                         decode_cblk(s, codsty, &t1, cblk,
                                     cblk->coord[0][1] - cblk->coord[0][0],
                                     cblk->coord[1][1] - cblk->coord[1][0],
                                     bandpos);
 
                         x = cblk->coord[0][0];
                         y = cblk->coord[1][0];
 
83fd377c
                         if (codsty->transform == FF_DWT97)
c81a7063
                             dequantization_float(x, y, cblk, comp, &t1, band);
83fd377c
                         else
                             dequantization_int(x, y, cblk, comp, &t1, band);
c81a7063
                    } /* end cblk */
                 } /*end prec */
             } /* end band */
         } /* end reslevel */
 
         /* inverse DWT */
8bedbb82
         ff_dwt_decode(&comp->dwt, codsty->transform == FF_DWT97 ? (void*)comp->f_data : (void*)comp->i_data);
c81a7063
     } /*end comp */
 
     /* inverse MCT transformation */
     if (tile->codsty[0].mct)
         mct_decode(s, tile);
 
99de97ca
     if (s->cdef[0] < 0) {
         for (x = 0; x < s->ncomponents; x++)
             s->cdef[x] = x + 1;
         if ((s->ncomponents & 1) == 0)
             s->cdef[s->ncomponents-1] = 0;
     }
 
c81a7063
     if (s->precision <= 8) {
         for (compno = 0; compno < s->ncomponents; compno++) {
             Jpeg2000Component *comp = tile->comp + compno;
c49d9448
             Jpeg2000CodingStyle *codsty = tile->codsty + compno;
8bedbb82
             float *datap = comp->f_data;
             int32_t *i_datap = comp->i_data;
6507d86f
             int cbps = s->cbps[compno];
             int w = tile->comp[compno].coord[0][1] - s->image_offset_x;
fc6de70c
             int plane = 0;
 
             if (planar)
                 plane = s->cdef[compno] ? s->cdef[compno]-1 : (s->ncomponents-1);
 
3f714d1f
 
c81a7063
             y    = tile->comp[compno].coord[1][0] - s->image_offset_y;
fe448cd2
             line = picture->data[plane] + y / s->cdy[compno] * picture->linesize[plane];
c81a7063
             for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]) {
                 uint8_t *dst;
 
                 x   = tile->comp[compno].coord[0][0] - s->image_offset_x;
fe448cd2
                 dst = line + x / s->cdx[compno] * pixelsize + compno*!planar;
c81a7063
 
c49d9448
                 if (codsty->transform == FF_DWT97) {
6507d86f
                     for (; x < w; x += s->cdx[compno]) {
                         int val = lrintf(*datap) + (1 << (cbps - 1));
                         /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
                         val = av_clip(val, 0, (1 << cbps) - 1);
                         *dst = val << (8 - cbps);
                         datap++;
fc6de70c
                         dst += pixelsize;
6507d86f
                     }
                 } else {
                     for (; x < w; x += s->cdx[compno]) {
                         int val = *i_datap + (1 << (cbps - 1));
                         /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
                         val = av_clip(val, 0, (1 << cbps) - 1);
                         *dst = val << (8 - cbps);
                         i_datap++;
fc6de70c
                         dst += pixelsize;
6507d86f
                     }
c81a7063
                 }
fc6de70c
                 line += picture->linesize[plane];
c81a7063
             }
         }
     } else {
         for (compno = 0; compno < s->ncomponents; compno++) {
             Jpeg2000Component *comp = tile->comp + compno;
c49d9448
             Jpeg2000CodingStyle *codsty = tile->codsty + compno;
8bedbb82
             float *datap = comp->f_data;
             int32_t *i_datap = comp->i_data;
c81a7063
             uint16_t *linel;
6507d86f
             int cbps = s->cbps[compno];
             int w = tile->comp[compno].coord[0][1] - s->image_offset_x;
1434df3b
             int plane = 0;
 
             if (planar)
                 plane = s->cdef[compno] ? s->cdef[compno]-1 : (s->ncomponents-1);
c81a7063
 
             y     = tile->comp[compno].coord[1][0] - s->image_offset_y;
fe448cd2
             linel = (uint16_t *)picture->data[plane] + y / s->cdy[compno] * (picture->linesize[plane] >> 1);
c81a7063
             for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]) {
                 uint16_t *dst;
cdb86136
 
c81a7063
                 x   = tile->comp[compno].coord[0][0] - s->image_offset_x;
fe448cd2
                 dst = linel + (x / s->cdx[compno] * pixelsize + compno*!planar);
c49d9448
                 if (codsty->transform == FF_DWT97) {
6507d86f
                     for (; x < w; x += s-> cdx[compno]) {
                         int  val = lrintf(*datap) + (1 << (cbps - 1));
                         /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
                         val = av_clip(val, 0, (1 << cbps) - 1);
                         /* align 12 bit values in little-endian mode */
                         *dst = val << (16 - cbps);
                         datap++;
1434df3b
                         dst += pixelsize;
6507d86f
                     }
                 } else {
                     for (; x < w; x += s-> cdx[compno]) {
                         int val = *i_datap + (1 << (cbps - 1));
                         /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
                         val = av_clip(val, 0, (1 << cbps) - 1);
                         /* align 12 bit values in little-endian mode */
                         *dst = val << (16 - cbps);
                         i_datap++;
1434df3b
                         dst += pixelsize;
6507d86f
                     }
c81a7063
                 }
1434df3b
                 linel += picture->linesize[plane] >> 1;
c81a7063
             }
         }
     }
6507d86f
 
c81a7063
     return 0;
 }
 
 static void jpeg2000_dec_cleanup(Jpeg2000DecoderContext *s)
 {
     int tileno, compno;
     for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++) {
63c0e907
         if (s->tile[tileno].comp) {
             for (compno = 0; compno < s->ncomponents; compno++) {
                 Jpeg2000Component *comp     = s->tile[tileno].comp   + compno;
                 Jpeg2000CodingStyle *codsty = s->tile[tileno].codsty + compno;
c81a7063
 
63c0e907
                 ff_jpeg2000_cleanup(comp, codsty);
             }
             av_freep(&s->tile[tileno].comp);
c81a7063
         }
     }
     av_freep(&s->tile);
fcd19d6c
     memset(s->codsty, 0, sizeof(s->codsty));
     memset(s->qntsty, 0, sizeof(s->qntsty));
9054e725
     s->numXtiles = s->numYtiles = 0;
c81a7063
 }
 
 static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
 {
     Jpeg2000CodingStyle *codsty = s->codsty;
     Jpeg2000QuantStyle *qntsty  = s->qntsty;
     uint8_t *properties         = s->properties;
 
     for (;;) {
         int len, ret = 0;
         uint16_t marker;
0b426316
         int oldpos;
c81a7063
 
0b426316
         if (bytestream2_get_bytes_left(&s->g) < 2) {
c81a7063
             av_log(s->avctx, AV_LOG_ERROR, "Missing EOC\n");
             break;
         }
 
0b426316
         marker = bytestream2_get_be16u(&s->g);
         oldpos = bytestream2_tell(&s->g);
c81a7063
 
9d56ccf5
         if (marker == JPEG2000_SOD) {
b26bcd08
             Jpeg2000Tile *tile;
             Jpeg2000TilePart *tp;
9d56ccf5
 
18a245a2
             if (!s->tile) {
                 av_log(s->avctx, AV_LOG_ERROR, "Missing SIZ\n");
                 return AVERROR_INVALIDDATA;
             }
2dd38a1d
             if (s->curtileno < 0) {
                 av_log(s->avctx, AV_LOG_ERROR, "Missing SOT\n");
                 return AVERROR_INVALIDDATA;
             }
b26bcd08
 
             tile = s->tile + s->curtileno;
             tp = tile->tile_part + tile->tp_idx;
32fc8d6d
             if (tp->tp_end < s->g.buffer) {
                 av_log(s->avctx, AV_LOG_ERROR, "Invalid tpend\n");
                 return AVERROR_INVALIDDATA;
             }
9d56ccf5
             bytestream2_init(&tp->tpg, s->g.buffer, tp->tp_end - s->g.buffer);
             bytestream2_skip(&s->g, tp->tp_end - s->g.buffer);
 
             continue;
         }
c81a7063
         if (marker == JPEG2000_EOC)
             break;
 
69e4d8e6
         len = bytestream2_get_be16(&s->g);
         if (len < 2 || bytestream2_get_bytes_left(&s->g) < len - 2)
5efadcb8
             return AVERROR_INVALIDDATA;
fd54dd02
 
c81a7063
         switch (marker) {
         case JPEG2000_SIZ:
             ret = get_siz(s);
17e66c9f
             if (!s->tile)
                 s->numXtiles = s->numYtiles = 0;
c81a7063
             break;
         case JPEG2000_COC:
             ret = get_coc(s, codsty, properties);
             break;
         case JPEG2000_COD:
             ret = get_cod(s, codsty, properties);
             break;
         case JPEG2000_QCC:
             ret = get_qcc(s, len, qntsty, properties);
             break;
         case JPEG2000_QCD:
             ret = get_qcd(s, len, qntsty, properties);
             break;
         case JPEG2000_SOT:
9d56ccf5
             if (!(ret = get_sot(s, len))) {
bbf43c70
                 av_assert1(s->curtileno >= 0);
9d56ccf5
                 codsty = s->tile[s->curtileno].codsty;
                 qntsty = s->tile[s->curtileno].qntsty;
                 properties = s->tile[s->curtileno].properties;
             }
c81a7063
             break;
         case JPEG2000_COM:
             // the comment is ignored
0b426316
             bytestream2_skip(&s->g, len - 2);
c81a7063
             break;
         case JPEG2000_TLM:
             // Tile-part lengths
             ret = get_tlm(s, len);
             break;
         default:
             av_log(s->avctx, AV_LOG_ERROR,
cc8163e1
                    "unsupported marker 0x%.4"PRIX16" at pos 0x%X\n",
0b426316
                    marker, bytestream2_tell(&s->g) - 4);
             bytestream2_skip(&s->g, len - 2);
c81a7063
             break;
         }
9d56ccf5
         if (bytestream2_tell(&s->g) - oldpos != len || ret) {
c81a7063
             av_log(s->avctx, AV_LOG_ERROR,
cc8163e1
                    "error during processing marker segment %.4"PRIx16"\n",
                    marker);
c81a7063
             return ret ? ret : -1;
         }
     }
     return 0;
 }
 
 /* Read bit stream packets --> T2 operation. */
 static int jpeg2000_read_bitstream_packets(Jpeg2000DecoderContext *s)
 {
     int ret = 0;
9d56ccf5
     int tileno;
c81a7063
 
9d56ccf5
     for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++) {
         Jpeg2000Tile *tile = s->tile + tileno;
 
         if (ret = init_tile(s, tileno))
             return ret;
 
         s->g = tile->tile_part[0].tpg;
         if (ret = jpeg2000_decode_packets(s, tile))
             return ret;
     }
c81a7063
 
     return 0;
 }
 
 static int jp2_find_codestream(Jpeg2000DecoderContext *s)
 {
bff371e3
     uint32_t atom_size, atom, atom_end;
     int search_range = 10;
c81a7063
 
bff371e3
     while (search_range
57bc64e2
            &&
            bytestream2_get_bytes_left(&s->g) >= 8) {
0b426316
         atom_size = bytestream2_get_be32u(&s->g);
         atom      = bytestream2_get_be32u(&s->g);
bff371e3
         atom_end  = bytestream2_tell(&s->g) + atom_size - 8;
 
         if (atom == JP2_CODESTREAM)
             return 1;
 
         if (bytestream2_get_bytes_left(&s->g) < atom_size || atom_end < atom_size)
             return 0;
 
         if (atom == JP2_HEADER &&
b39a6bbe
                    atom_size >= 16) {
bff371e3
             uint32_t atom2_size, atom2, atom2_end;
b39a6bbe
             do {
                 atom2_size = bytestream2_get_be32u(&s->g);
                 atom2      = bytestream2_get_be32u(&s->g);
bff371e3
                 atom2_end  = bytestream2_tell(&s->g) + atom2_size - 8;
                 if (atom2_size < 8 || atom2_end > atom_end || atom2_end < atom2_size)
b39a6bbe
                     break;
                 if (atom2 == JP2_CODESTREAM) {
                     return 1;
                 } else if (atom2 == MKBETAG('c','o','l','r') && atom2_size >= 7) {
                     int method = bytestream2_get_byteu(&s->g);
                     bytestream2_skipu(&s->g, 2);
                     if (method == 1) {
                         s->colour_space = bytestream2_get_be32u(&s->g);
                     }
                 } else if (atom2 == MKBETAG('p','c','l','r') && atom2_size >= 6) {
                     int i, size, colour_count, colour_channels, colour_depth[3];
                     uint32_t r, g, b;
                     colour_count = bytestream2_get_be16u(&s->g);
                     colour_channels = bytestream2_get_byteu(&s->g);
                     // FIXME: Do not ignore channel_sign
                     colour_depth[0] = (bytestream2_get_byteu(&s->g) & 0x7f) + 1;
                     colour_depth[1] = (bytestream2_get_byteu(&s->g) & 0x7f) + 1;
                     colour_depth[2] = (bytestream2_get_byteu(&s->g) & 0x7f) + 1;
                     size = (colour_depth[0] + 7 >> 3) * colour_count +
                            (colour_depth[1] + 7 >> 3) * colour_count +
                            (colour_depth[2] + 7 >> 3) * colour_count;
                     if (colour_count > 256   ||
                         colour_channels != 3 ||
                         colour_depth[0] > 16 ||
                         colour_depth[1] > 16 ||
                         colour_depth[2] > 16 ||
                         atom2_size < size) {
                         avpriv_request_sample(s->avctx, "Unknown palette");
bff371e3
                         bytestream2_seek(&s->g, atom2_end, SEEK_SET);
b39a6bbe
                         continue;
                     }
                     s->pal8 = 1;
                     for (i = 0; i < colour_count; i++) {
                         if (colour_depth[0] <= 8) {
                             r = bytestream2_get_byteu(&s->g) << 8 - colour_depth[0];
                             r |= r >> colour_depth[0];
                         } else {
                             r = bytestream2_get_be16u(&s->g) >> colour_depth[0] - 8;
                         }
                         if (colour_depth[1] <= 8) {
                             g = bytestream2_get_byteu(&s->g) << 8 - colour_depth[1];
                             r |= r >> colour_depth[1];
                         } else {
                             g = bytestream2_get_be16u(&s->g) >> colour_depth[1] - 8;
                         }
                         if (colour_depth[2] <= 8) {
                             b = bytestream2_get_byteu(&s->g) << 8 - colour_depth[2];
                             r |= r >> colour_depth[2];
                         } else {
                             b = bytestream2_get_be16u(&s->g) >> colour_depth[2] - 8;
                         }
                         s->palette[i] = 0xffu << 24 | r << 16 | g << 8 | b;
                     }
bff371e3
                 } else if (atom2 == MKBETAG('c','d','e','f') && atom2_size >= 2) {
99de97ca
                     int n = bytestream2_get_be16u(&s->g);
                     for (; n>0; n--) {
                         int cn   = bytestream2_get_be16(&s->g);
db330104
                         int av_unused typ  = bytestream2_get_be16(&s->g);
99de97ca
                         int asoc = bytestream2_get_be16(&s->g);
                         if (cn < 4 || asoc < 4)
                             s->cdef[cn] = asoc;
                     }
b39a6bbe
                 }
bff371e3
                 bytestream2_seek(&s->g, atom2_end, SEEK_SET);
             } while (atom_end - atom2_end >= 8);
c81a7063
         } else {
             search_range--;
         }
bff371e3
         bytestream2_seek(&s->g, atom_end, SEEK_SET);
c81a7063
     }
 
     return 0;
 }
 
 static int jpeg2000_decode_frame(AVCodecContext *avctx, void *data,
                                  int *got_frame, AVPacket *avpkt)
 {
     Jpeg2000DecoderContext *s = avctx->priv_data;
2e2d2466
     ThreadFrame frame = { .f = data };
c81a7063
     AVFrame *picture = data;
     int tileno, ret;
 
     s->avctx     = avctx;
0b426316
     bytestream2_init(&s->g, avpkt->data, avpkt->size);
9d56ccf5
     s->curtileno = -1;
99de97ca
     memset(s->cdef, -1, sizeof(s->cdef));
c81a7063
 
9d56ccf5
     if (bytestream2_get_bytes_left(&s->g) < 2) {
26f6acc6
         ret = AVERROR_INVALIDDATA;
9d56ccf5
         goto end;
     }
c81a7063
 
     // check if the image is in jp2 format
0b426316
     if (bytestream2_get_bytes_left(&s->g) >= 12 &&
        (bytestream2_get_be32u(&s->g) == 12) &&
        (bytestream2_get_be32u(&s->g) == JP2_SIG_TYPE) &&
        (bytestream2_get_be32u(&s->g) == JP2_SIG_VALUE)) {
c81a7063
         if (!jp2_find_codestream(s)) {
             av_log(avctx, AV_LOG_ERROR,
5efadcb8
                    "Could not find Jpeg2000 codestream atom.\n");
26f6acc6
             ret = AVERROR_INVALIDDATA;
9d56ccf5
             goto end;
c81a7063
         }
0b426316
     } else {
         bytestream2_seek(&s->g, 0, SEEK_SET);
c81a7063
     }
 
4ced3090
     while (bytestream2_get_bytes_left(&s->g) >= 3 && bytestream2_peek_be16(&s->g) != JPEG2000_SOC)
         bytestream2_skip(&s->g, 1);
 
0b426316
     if (bytestream2_get_be16u(&s->g) != JPEG2000_SOC) {
c81a7063
         av_log(avctx, AV_LOG_ERROR, "SOC marker not present\n");
26f6acc6
         ret = AVERROR_INVALIDDATA;
9d56ccf5
         goto end;
c81a7063
     }
     if (ret = jpeg2000_read_main_headers(s))
45a1694f
         goto end;
c81a7063
 
     /* get picture buffer */
d2021f74
     if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
45a1694f
         goto end;
c81a7063
     picture->pict_type = AV_PICTURE_TYPE_I;
     picture->key_frame = 1;
 
     if (ret = jpeg2000_read_bitstream_packets(s))
45a1694f
         goto end;
9d56ccf5
 
c81a7063
     for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++)
         if (ret = jpeg2000_decode_tile(s, s->tile + tileno, picture))
45a1694f
             goto end;
9d56ccf5
 
c81a7063
     jpeg2000_dec_cleanup(s);
 
     *got_frame = 1;
 
b39a6bbe
     if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
         memcpy(picture->data[1], s->palette, 256 * sizeof(uint32_t));
 
0b426316
     return bytestream2_tell(&s->g);
1a3598aa
 
45a1694f
 end:
974420a7
     jpeg2000_dec_cleanup(s);
     return ret;
c81a7063
 }
 
fe4d5fe9
 static av_cold void jpeg2000_init_static_data(AVCodec *codec)
70f96615
 {
     ff_jpeg2000_init_tier1_luts();
dd1382ac
     ff_mqc_init_context_tables();
70f96615
 }
 
c81a7063
 #define OFFSET(x) offsetof(Jpeg2000DecoderContext, x)
 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
 
 static const AVOption options[] = {
     { "lowres",  "Lower the decoding resolution by a power of two",
f9581f14
         OFFSET(reduction_factor), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, JPEG2000_MAX_RESLEVELS - 1, VD },
c81a7063
     { NULL },
 };
 
 static const AVProfile profiles[] = {
     { FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0,  "JPEG 2000 codestream restriction 0"   },
     { FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1,  "JPEG 2000 codestream restriction 1"   },
     { FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION, "JPEG 2000 no codestream restrictions" },
     { FF_PROFILE_JPEG2000_DCINEMA_2K,             "JPEG 2000 digital cinema 2K"          },
     { FF_PROFILE_JPEG2000_DCINEMA_4K,             "JPEG 2000 digital cinema 4K"          },
     { FF_PROFILE_UNKNOWN },
 };
 
0915b531
 static const AVClass jpeg2000_class = {
c81a7063
     .class_name = "jpeg2000",
     .item_name  = av_default_item_name,
     .option     = options,
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
 AVCodec ff_jpeg2000_decoder = {
70f96615
     .name             = "jpeg2000",
     .long_name        = NULL_IF_CONFIG_SMALL("JPEG 2000"),
     .type             = AVMEDIA_TYPE_VIDEO,
     .id               = AV_CODEC_ID_JPEG2000,
     .capabilities     = CODEC_CAP_FRAME_THREADS,
     .priv_data_size   = sizeof(Jpeg2000DecoderContext),
     .init_static_data = jpeg2000_init_static_data,
     .decode           = jpeg2000_decode_frame,
0915b531
     .priv_class       = &jpeg2000_class,
8cf57efd
     .max_lowres       = 5,
70f96615
     .profiles         = NULL_IF_CONFIG_SMALL(profiles)
c81a7063
 };