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>
4c1aac89
 #include <math.h>
cc8163e1
 
fe4d5fe9
 #include "libavutil/attributes.h"
bbf43c70
 #include "libavutil/avassert.h"
c81a7063
 #include "libavutil/common.h"
0eb7de19
 #include "libavutil/imgutils.h"
c81a7063
 #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"
c9f2ec8a
 #include "jpeg2000dsp.h"
2c681139
 #include "profiles.h"
c81a7063
 
 #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
 
2ec0ba1e
 #define MAX_POCS 32
 
 typedef struct Jpeg2000POCEntry {
     uint16_t LYEpoc;
     uint16_t CSpoc;
     uint16_t CEpoc;
     uint8_t RSpoc;
     uint8_t REpoc;
     uint8_t Ppoc;
 } Jpeg2000POCEntry;
 
 typedef struct Jpeg2000POC {
     Jpeg2000POCEntry poc[MAX_POCS];
     int nb_poc;
     int is_default;
 } Jpeg2000POC;
 
c81a7063
 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];
2ec0ba1e
     Jpeg2000POC         poc;
5ba9ec82
     Jpeg2000TilePart    tile_part[256];
9d56ccf5
     uint16_t tp_idx;                    // Tile-part index
6c4a2f11
     int coord[2][2];                    // border coordinates {{x0, x1}, {y0, y1}}
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;
4c1aac89
     AVRational      sar;
c81a7063
 
     Jpeg2000CodingStyle codsty[4];
     Jpeg2000QuantStyle  qntsty[4];
2ec0ba1e
     Jpeg2000POC         poc;
c81a7063
 
     int             bit_index;
 
5dbbb762
     int             curtileno;
 
c81a7063
     Jpeg2000Tile    *tile;
c9f2ec8a
     Jpeg2000DSPContext dsp;
c81a7063
 
     /*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;
 
742a26c4
     if (!node) {
         av_log(s->avctx, AV_LOG_ERROR, "missing node\n");
09d5929f
         return AVERROR_INVALIDDATA;
742a26c4
     }
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);
 
3dea13e7
     av_assert2(desc);
 
b39a6bbe
     if (desc->nb_components != components) {
         return 0;
     }
 
     switch (components) {
     case 4:
5d8e836d
         match = match && desc->comp[3].depth >= bpc &&
b39a6bbe
                          (log2_chroma_wh >> 14 & 3) == 0 &&
                          (log2_chroma_wh >> 12 & 3) == 0;
     case 3:
5d8e836d
         match = match && desc->comp[2].depth >= bpc &&
b39a6bbe
                          (log2_chroma_wh >> 10 & 3) == desc->log2_chroma_w &&
                          (log2_chroma_wh >>  8 & 3) == desc->log2_chroma_h;
     case 2:
5d8e836d
         match = match && desc->comp[1].depth >= bpc &&
b39a6bbe
                          (log2_chroma_wh >>  6 & 3) == desc->log2_chroma_w &&
                          (log2_chroma_wh >>  4 & 3) == desc->log2_chroma_h;
 
     case 1:
5d8e836d
         match = match && desc->comp[0].depth >= bpc &&
b39a6bbe
                          (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
f018b1f3
 #define GRAY_PIXEL_FORMATS  AV_PIX_FMT_GRAY8,AV_PIX_FMT_GRAY8A,AV_PIX_FMT_GRAY16,AV_PIX_FMT_YA16
b39a6bbe
 #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};
5b2f9790
 static const enum AVPixelFormat xyz_pix_fmts[]  = {XYZ_PIXEL_FORMATS,
                                                    YUV_PIXEL_FORMATS};
b39a6bbe
 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;
f3da6fbf
     int ret;
c81a7063
 
742a26c4
     if (bytestream2_get_bytes_left(&s->g) < 36) {
         av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for SIZ\n");
26f6acc6
         return AVERROR_INVALIDDATA;
742a26c4
     }
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;
     }
0eb7de19
     if (av_image_check_size(s->width, s->height, 0, s->avctx)) {
6ef819c4
         avpriv_request_sample(s->avctx, "Large Dimensions");
         return AVERROR_PATCHWELCOME;
     }
780669ef
 
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",
b58a3c89
                               ncomponents);
278a923c
         return AVERROR_PATCHWELCOME;
     }
 
89325417
     if (s->tile_offset_x < 0 || s->tile_offset_y < 0 ||
         s->image_offset_x < s->tile_offset_x ||
9c181249
         s->image_offset_y < s->tile_offset_y ||
         s->tile_width  + (int64_t)s->tile_offset_x <= s->image_offset_x ||
         s->tile_height + (int64_t)s->tile_offset_y <= s->image_offset_y
     ) {
5782e0ba
         av_log(s->avctx, AV_LOG_ERROR, "Tile offsets are invalid\n");
89325417
         return AVERROR_INVALIDDATA;
     }
 
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
 
742a26c4
     if (bytestream2_get_bytes_left(&s->g) < 3 * s->ncomponents) {
         av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for %d components in SIZ\n", s->ncomponents);
5efadcb8
         return AVERROR_INVALIDDATA;
742a26c4
     }
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 */
f3da6fbf
     ret = ff_set_dimensions(s->avctx,
             ff_jpeg2000_ceildivpow2(s->width  - s->image_offset_x,
                                                s->reduction_factor),
             ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y,
                                                s->reduction_factor));
     if (ret < 0)
         return ret;
c81a7063
 
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;
         }
     }
ad072a13
 
     if (i == possible_fmts_nb) {
         if (ncomponents == 4 &&
             s->cdy[0] == 1 && s->cdx[0] == 1 &&
             s->cdy[1] == 1 && s->cdx[1] == 1 &&
             s->cdy[2] == s->cdy[3] && s->cdx[2] == s->cdx[3]) {
             if (s->precision == 8 && s->cdy[2] == 2 && s->cdx[2] == 2 && !s->pal8) {
                 s->avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
                 s->cdef[0] = 0;
                 s->cdef[1] = 1;
                 s->cdef[2] = 2;
                 s->cdef[3] = 3;
                 i = 0;
             }
         }
     }
 
 
8001e9f7
     if (i == possible_fmts_nb) {
b39a6bbe
         av_log(s->avctx, AV_LOG_ERROR,
                "Unknown pix_fmt, profile: %d, colour_space: %d, "
132bf0bb
                "components: %d, precision: %d\n"
                "cdx[0]: %d, cdy[0]: %d\n"
                "cdx[1]: %d, cdy[1]: %d\n"
                "cdx[2]: %d, cdy[2]: %d\n"
                "cdx[3]: %d, cdy[3]: %d\n",
b39a6bbe
                s->avctx->profile, s->colour_space, ncomponents, s->precision,
132bf0bb
                s->cdx[0],
                s->cdy[0],
                ncomponents > 1 ? s->cdx[1] : 0,
                ncomponents > 1 ? s->cdy[1] : 0,
b39a6bbe
                ncomponents > 2 ? s->cdx[2] : 0,
132bf0bb
                ncomponents > 2 ? s->cdy[2] : 0,
                ncomponents > 3 ? s->cdx[3] : 0,
                ncomponents > 3 ? s->cdy[3] : 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;
 
742a26c4
     if (bytestream2_get_bytes_left(&s->g) < 5) {
         av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for COX\n");
26f6acc6
         return AVERROR_INVALIDDATA;
742a26c4
     }
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
 
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);
2f1dd4a3
         if (c->cblk_style & JPEG2000_CBLK_BYPASS)
             av_log(s->avctx, AV_LOG_WARNING, "Selective arithmetic coding bypass\n");
c81a7063
     }
0b426316
     c->transform = bytestream2_get_byteu(&s->g); // DWT transformation type
c81a7063
     /* set integer 9/7 DWT in case of BITEXACT flag */
7c6eb0a1
     if ((s->avctx->flags & AV_CODEC_FLAG_BITEXACT) && (c->transform == FF_DWT97))
c81a7063
         c->transform = FF_DWT97_INT;
c239fcb9
     else if (c->transform == FF_DWT53) {
         s->avctx->properties |= FF_CODEC_PROPERTY_LOSSLESS;
     }
c81a7063
 
     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
2d8bf3d1
             if (i)
                 if (c->log2_prec_widths[i] == 0 || c->log2_prec_heights[i] == 0) {
                     av_log(s->avctx, AV_LOG_ERROR, "PPx %d PPy %d invalid\n",
                            c->log2_prec_widths[i], c->log2_prec_heights[i]);
                     c->log2_prec_widths[i] = c->log2_prec_heights[i] = 1;
                     return AVERROR_INVALIDDATA;
                 }
c81a7063
         }
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
 
742a26c4
     if (bytestream2_get_bytes_left(&s->g) < 5) {
         av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for COD\n");
5efadcb8
         return AVERROR_INVALIDDATA;
742a26c4
     }
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
 
742a26c4
     if (bytestream2_get_bytes_left(&s->g) < 2) {
         av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for COC\n");
5efadcb8
         return AVERROR_INVALIDDATA;
742a26c4
     }
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);
 }
 
2ec0ba1e
 static int get_poc(Jpeg2000DecoderContext *s, int size, Jpeg2000POC *p)
 {
     int i;
     int elem_size = s->ncomponents <= 257 ? 7 : 9;
     Jpeg2000POC tmp = {{{0}}};
 
     if (bytestream2_get_bytes_left(&s->g) < 5 || size < 2 + elem_size) {
         av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for POC\n");
         return AVERROR_INVALIDDATA;
     }
 
     if (elem_size > 7) {
daf2c35f
         avpriv_request_sample(s->avctx, "Fat POC not supported");
2ec0ba1e
         return AVERROR_PATCHWELCOME;
     }
 
     tmp.nb_poc = (size - 2) / elem_size;
     if (tmp.nb_poc > MAX_POCS) {
daf2c35f
         avpriv_request_sample(s->avctx, "Too many POCs (%d)", tmp.nb_poc);
2ec0ba1e
         return AVERROR_PATCHWELCOME;
     }
 
     for (i = 0; i<tmp.nb_poc; i++) {
         Jpeg2000POCEntry *e = &tmp.poc[i];
         e->RSpoc  = bytestream2_get_byteu(&s->g);
         e->CSpoc  = bytestream2_get_byteu(&s->g);
         e->LYEpoc = bytestream2_get_be16u(&s->g);
         e->REpoc  = bytestream2_get_byteu(&s->g);
         e->CEpoc  = bytestream2_get_byteu(&s->g);
         e->Ppoc   = bytestream2_get_byteu(&s->g);
         if (!e->CEpoc)
             e->CEpoc = 256;
         if (e->CEpoc > s->ncomponents)
             e->CEpoc = s->ncomponents;
         if (   e->RSpoc >= e->REpoc || e->REpoc > 33
             || e->CSpoc >= e->CEpoc || e->CEpoc > s->ncomponents
             || !e->LYEpoc) {
             av_log(s->avctx, AV_LOG_ERROR, "POC Entry %d is invalid (%d, %d, %d, %d, %d, %d)\n", i,
                 e->RSpoc, e->CSpoc, e->LYEpoc, e->REpoc, e->CEpoc, e->Ppoc
             );
             return AVERROR_INVALIDDATA;
         }
     }
 
     if (!p->nb_poc || p->is_default) {
         *p = tmp;
     } else {
         if (p->nb_poc + tmp.nb_poc > MAX_POCS) {
             av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for POC\n");
             return AVERROR_INVALIDDATA;
         }
         memcpy(p->poc + p->nb_poc, tmp.poc, tmp.nb_poc * sizeof(tmp.poc[0]));
         p->nb_poc += tmp.nb_poc;
     }
 
     p->is_default = 0;
 
     return 0;
 }
 
 
c81a7063
 /* Get start of tile segment. */
f399b33c
 static int get_sot(Jpeg2000DecoderContext *s, int n)
c81a7063
 {
     Jpeg2000TilePart *tp;
     uint16_t Isot;
     uint32_t Psot;
bb9f4f94
     unsigned TPsot;
c81a7063
 
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
 
b6ee1912
     if (!Psot)
e2298b3f
         Psot = bytestream2_get_bytes_left(&s->g) - 2 + n + 2;
b6ee1912
 
e2298b3f
     if (Psot > bytestream2_get_bytes_left(&s->g) - 2 + n + 2) {
cc8163e1
         av_log(s->avctx, AV_LOG_ERROR, "Psot %"PRIu32" too big\n", Psot);
5deb96c5
         return AVERROR_INVALIDDATA;
     }
d3cb302b
 
bb9f4f94
     av_assert0(TPsot < FF_ARRAY_ELEMS(s->tile[Isot].tile_part));
73ffab41
 
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));
2ec0ba1e
         memcpy(&tile->poc  , &s->poc  , sizeof(tile->poc));
         tile->poc.is_default = 1;
9d56ccf5
     }
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;
 }
 
45db9218
 static uint8_t get_plt(Jpeg2000DecoderContext *s, int n)
 {
     int i;
 
971b3779
     av_log(s->avctx, AV_LOG_DEBUG,
45db9218
             "PLT marker at pos 0x%X\n", bytestream2_tell(&s->g) - 4);
 
     /*Zplt =*/ bytestream2_get_byte(&s->g);
 
     for (i = 0; i < n - 3; i++) {
         bytestream2_get_byte(&s->g);
     }
 
     return 0;
 }
 
c81a7063
 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);
 
65d3359f
     tile->coord[0][0] = av_clip(tilex       * (int64_t)s->tile_width  + s->tile_offset_x, s->image_offset_x, s->width);
     tile->coord[0][1] = av_clip((tilex + 1) * (int64_t)s->tile_width  + s->tile_offset_x, s->image_offset_x, s->width);
     tile->coord[1][0] = av_clip(tiley       * (int64_t)s->tile_height + s->tile_offset_y, s->image_offset_y, s->height);
     tile->coord[1][1] = av_clip((tiley + 1) * (int64_t)s->tile_height + s->tile_offset_y, s->image_offset_y, s->height);
6c4a2f11
 
c81a7063
     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
 
6c4a2f11
         comp->coord_o[0][0] = tile->coord[0][0];
         comp->coord_o[0][1] = tile->coord[0][1];
         comp->coord_o[1][0] = tile->coord[1][0];
         comp->coord_o[1][1] = tile->coord[1][1];
074159ed
         if (compno) {
             comp->coord_o[0][0] /= s->cdx[compno];
             comp->coord_o[0][1] /= s->cdx[compno];
             comp->coord_o[1][0] /= s->cdy[compno];
             comp->coord_o[1][1] /= s->cdy[compno];
         }
c81a7063
 
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;
 }
 
e7adb02d
 static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, int *tp_index,
c81a7063
                                   Jpeg2000CodingStyle *codsty,
                                   Jpeg2000ResLevel *rlevel, int precno,
                                   int layno, uint8_t *expn, int numgbits)
 {
     int bandno, cblkno, ret, nb_code_blocks;
dc73c7ad
     int cwsno;
c81a7063
 
c72a8319
     if (layno < rlevel->band[0].prec[precno].decoded_layers)
         return 0;
     rlevel->band[0].prec[precno].decoded_layers = layno + 1;
 
e7adb02d
     if (bytestream2_get_bytes_left(&s->g) == 0 && s->bit_index == 8) {
         if (*tp_index < FF_ARRAY_ELEMS(tile->tile_part) - 1) {
             s->g = tile->tile_part[++(*tp_index)].tpg;
         }
     }
 
4ec14ce1
     if (bytestream2_peek_be32(&s->g) == JPEG2000_SOP_FIXED_BYTES)
         bytestream2_skip(&s->g, JPEG2000_SOP_BYTE_LENGTH);
a58f1bcc
 
c81a7063
     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);
dfb61ea2
                 if (v < 0 || v > 30) {
17e5d614
                     av_log(s->avctx, AV_LOG_ERROR,
dfb61ea2
                            "nonzerobits %d invalid or unsupported\n", v);
3b861742
                     return AVERROR_INVALIDDATA;
                 }
                 cblk->nonzerobits = v;
             }
c81a7063
             if ((newpasses = getnpasses(s)) < 0)
                 return newpasses;
b395fd3d
             av_assert2(newpasses > 0);
             if (cblk->npasses + newpasses >= JPEG2000_MAX_PASSES) {
daf2c35f
                 avpriv_request_sample(s->avctx, "Too many passes");
b395fd3d
                 return AVERROR_PATCHWELCOME;
             }
c81a7063
             if ((llen = getlblockinc(s)) < 0)
                 return llen;
5ccca4eb
             if (cblk->lblock + llen + av_log2(newpasses) > 16) {
                 avpriv_request_sample(s->avctx,
daf2c35f
                                       "Block with length beyond 16 bits");
5ccca4eb
                 return AVERROR_PATCHWELCOME;
             }
 
c81a7063
             cblk->lblock += llen;
dc73c7ad
 
             cblk->nb_lengthinc = 0;
             cblk->nb_terminationsinc = 0;
             do {
                 int newpasses1 = 0;
 
                 while (newpasses1 < newpasses) {
                     newpasses1 ++;
                     if (needs_termination(codsty->cblk_style, cblk->npasses + newpasses1 - 1)) {
                         cblk->nb_terminationsinc ++;
                         break;
                     }
                 }
 
                 if ((ret = get_bits(s, av_log2(newpasses1) + cblk->lblock)) < 0)
                     return ret;
3d5822d9
                 if (ret > cblk->data_allocated) {
                     size_t new_size = FFMAX(2*cblk->data_allocated, ret);
                     void *new = av_realloc(cblk->data, new_size);
                     if (new) {
                         cblk->data = new;
                         cblk->data_allocated = new_size;
                     }
                 }
                 if (ret > cblk->data_allocated) {
dc73c7ad
                     avpriv_request_sample(s->avctx,
                                         "Block with lengthinc greater than %"SIZE_SPECIFIER"",
3d5822d9
                                         cblk->data_allocated);
dc73c7ad
                     return AVERROR_PATCHWELCOME;
                 }
                 cblk->lengthinc[cblk->nb_lengthinc++] = ret;
                 cblk->npasses  += newpasses1;
                 newpasses -= newpasses1;
             } while(newpasses);
c81a7063
         }
     }
     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
c56ba5c2
             av_log(s->avctx, AV_LOG_ERROR, "EPH marker not found. instead %X\n", bytestream2_peek_be32(&s->g));
c81a7063
     }
 
     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;
dc73c7ad
             for (cwsno = 0; cwsno < cblk->nb_lengthinc; cwsno ++) {
3d5822d9
                 if (cblk->data_allocated < cblk->length + cblk->lengthinc[cwsno] + 4) {
                     size_t new_size = FFMAX(2*cblk->data_allocated, cblk->length + cblk->lengthinc[cwsno] + 4);
                     void *new = av_realloc(cblk->data, new_size);
                     if (new) {
                         cblk->data = new;
                         cblk->data_allocated = new_size;
                     }
                 }
dc73c7ad
                 if (   bytestream2_get_bytes_left(&s->g) < cblk->lengthinc[cwsno]
3d5822d9
                     || cblk->data_allocated < cblk->length + cblk->lengthinc[cwsno] + 4
dc73c7ad
                 ) {
                     av_log(s->avctx, AV_LOG_ERROR,
5ef578d0
                         "Block length %"PRIu16" or lengthinc %d is too large, left %d\n",
                         cblk->length, cblk->lengthinc[cwsno], bytestream2_get_bytes_left(&s->g));
dc73c7ad
                     return AVERROR_INVALIDDATA;
                 }
582f5334
 
dc73c7ad
                 bytestream2_get_bufferu(&s->g, cblk->data + cblk->length, cblk->lengthinc[cwsno]);
                 cblk->length   += cblk->lengthinc[cwsno];
                 cblk->lengthinc[cwsno] = 0;
                 if (cblk->nb_terminationsinc) {
                     cblk->nb_terminationsinc--;
                     cblk->nb_terminations++;
                     cblk->data[cblk->length++] = 0xFF;
                     cblk->data[cblk->length++] = 0xFF;
                     cblk->data_start[cblk->nb_terminations] = cblk->length;
                 }
             }
c81a7063
         }
     }
     return 0;
 }
 
c72a8319
 static int jpeg2000_decode_packets_po_iteration(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
                                              int RSpoc, int CSpoc,
                                              int LYEpoc, int REpoc, int CEpoc,
b75c0a72
                                              int Ppoc, int *tp_index)
c81a7063
 {
d57c737a
     int ret = 0;
     int layno, reslevelno, compno, precno, ok_reslevel;
fd7e1190
     int x, y;
c3517c37
     int step_x, step_y;
c81a7063
 
c72a8319
     switch (Ppoc) {
9d56ccf5
     case JPEG2000_PGOD_RLCP:
1b3fbe41
         av_log(s->avctx, AV_LOG_DEBUG, "Progression order RLCP\n");
9c893921
         ok_reslevel = 1;
c72a8319
         for (reslevelno = RSpoc; ok_reslevel && reslevelno < REpoc; reslevelno++) {
9c893921
             ok_reslevel = 0;
c72a8319
             for (layno = 0; layno < LYEpoc; layno++) {
                 for (compno = CSpoc; compno < CEpoc; compno++) {
9c893921
                     Jpeg2000CodingStyle *codsty = tile->codsty + compno;
                     Jpeg2000QuantStyle *qntsty  = tile->qntsty + compno;
                     if (reslevelno < codsty->nreslevels) {
                         Jpeg2000ResLevel *rlevel = tile->comp[compno].reslevel +
                                                 reslevelno;
                         ok_reslevel = 1;
                         for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++)
b75c0a72
                             if ((ret = jpeg2000_decode_packet(s, tile, tp_index,
9c893921
                                                               codsty, rlevel,
                                                               precno, layno,
                                                               qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
                                                               qntsty->nguardbits)) < 0)
                                 return ret;
                     }
                 }
             }
         }
         break;
19ff6f55
 
c81a7063
     case JPEG2000_PGOD_LRCP:
91c8025c
         av_log(s->avctx, AV_LOG_DEBUG, "Progression order LRCP\n");
c72a8319
         for (layno = 0; layno < LYEpoc; layno++) {
c81a7063
             ok_reslevel = 1;
c72a8319
             for (reslevelno = RSpoc; ok_reslevel && reslevelno < REpoc; reslevelno++) {
c81a7063
                 ok_reslevel = 0;
c72a8319
                 for (compno = CSpoc; compno < CEpoc; compno++) {
c81a7063
                     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++)
b75c0a72
                             if ((ret = jpeg2000_decode_packet(s, tile, tp_index,
5efadcb8
                                                               codsty, rlevel,
                                                               precno, layno,
                                                               qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
                                                               qntsty->nguardbits)) < 0)
                                 return ret;
c81a7063
                     }
                 }
             }
         }
         break;
 
     case JPEG2000_PGOD_CPRL:
91c8025c
         av_log(s->avctx, AV_LOG_DEBUG, "Progression order CPRL\n");
c72a8319
         for (compno = CSpoc; compno < CEpoc; compno++) {
7c244349
             Jpeg2000Component *comp     = tile->comp + compno;
c81a7063
             Jpeg2000CodingStyle *codsty = tile->codsty + compno;
             Jpeg2000QuantStyle *qntsty  = tile->qntsty + compno;
c3517c37
             step_x = 32;
             step_y = 32;
86efe831
 
c72a8319
             for (reslevelno = RSpoc; reslevelno < FFMIN(codsty->nreslevels, REpoc); reslevelno++) {
86efe831
                 uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; //  ==> N_L - r
7c244349
                 Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno;
86efe831
                 step_x = FFMIN(step_x, rlevel->log2_prec_width  + reducedresno);
                 step_y = FFMIN(step_y, rlevel->log2_prec_height + reducedresno);
             }
9e704755
             av_assert0(step_x < 32 && step_y < 32);
86efe831
             step_x = 1<<step_x;
             step_y = 1<<step_y;
c81a7063
 
7ca0cd58
             for (y = tile->coord[1][0]; y < tile->coord[1][1]; y = (y/step_y + 1)*step_y) {
                 for (x = tile->coord[0][0]; x < tile->coord[0][1]; x = (x/step_x + 1)*step_x) {
c72a8319
                     for (reslevelno = RSpoc; reslevelno < FFMIN(codsty->nreslevels, REpoc); reslevelno++) {
eb1beb9e
                         unsigned prcx, prcy;
c81a7063
                         uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; //  ==> N_L - r
7c244349
                         Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno;
7ca0cd58
                         int xc = x / s->cdx[compno];
                         int yc = y / s->cdy[compno];
c81a7063
 
7ca0cd58
                         if (yc % (1 << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check
c81a7063
                             continue;
 
7ca0cd58
                         if (xc % (1 << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check
c81a7063
                             continue;
 
                         // check if a precinct exists
7ca0cd58
                         prcx   = ff_jpeg2000_ceildivpow2(xc, reducedresno) >> rlevel->log2_prec_width;
                         prcy   = ff_jpeg2000_ceildivpow2(yc, reducedresno) >> rlevel->log2_prec_height;
eb1beb9e
                         prcx  -= ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], reducedresno) >> rlevel->log2_prec_width;
                         prcy  -= ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], reducedresno) >> rlevel->log2_prec_height;
 
c81a7063
                         precno = prcx + rlevel->num_precincts_x * prcy;
3d5a5e86
 
eaa86850
                         if (prcx >= rlevel->num_precincts_x || prcy >= rlevel->num_precincts_y) {
                             av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n",
                                    prcx, prcy, rlevel->num_precincts_x, rlevel->num_precincts_y);
                             continue;
                         }
3d5a5e86
 
c72a8319
                         for (layno = 0; layno < LYEpoc; layno++) {
b75c0a72
                             if ((ret = jpeg2000_decode_packet(s, tile, tp_index, codsty, rlevel,
5efadcb8
                                                               precno, layno,
                                                               qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
                                                               qntsty->nguardbits)) < 0)
                                 return ret;
c81a7063
                         }
                     }
                 }
             }
         }
         break;
 
d57c737a
     case JPEG2000_PGOD_RPCL:
612f8cae
         av_log(s->avctx, AV_LOG_WARNING, "Progression order RPCL\n");
         ok_reslevel = 1;
c72a8319
         for (reslevelno = RSpoc; ok_reslevel && reslevelno < REpoc; reslevelno++) {
612f8cae
             ok_reslevel = 0;
9ff5e797
             step_x = 30;
             step_y = 30;
c72a8319
             for (compno = CSpoc; compno < CEpoc; compno++) {
612f8cae
                 Jpeg2000Component *comp     = tile->comp + compno;
                 Jpeg2000CodingStyle *codsty = tile->codsty + compno;
 
                 if (reslevelno < codsty->nreslevels) {
                     uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; //  ==> N_L - r
                     Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno;
                     step_x = FFMIN(step_x, rlevel->log2_prec_width  + reducedresno);
                     step_y = FFMIN(step_y, rlevel->log2_prec_height + reducedresno);
                 }
             }
             step_x = 1<<step_x;
             step_y = 1<<step_y;
 
7ca0cd58
             for (y = tile->coord[1][0]; y < tile->coord[1][1]; y = (y/step_y + 1)*step_y) {
                 for (x = tile->coord[0][0]; x < tile->coord[0][1]; x = (x/step_x + 1)*step_x) {
c72a8319
                     for (compno = CSpoc; compno < CEpoc; compno++) {
612f8cae
                         Jpeg2000Component *comp     = tile->comp + compno;
                         Jpeg2000CodingStyle *codsty = tile->codsty + compno;
                         Jpeg2000QuantStyle *qntsty  = tile->qntsty + compno;
                         uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; //  ==> N_L - r
                         Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno;
                         unsigned prcx, prcy;
 
                         int xc = x / s->cdx[compno];
                         int yc = y / s->cdy[compno];
 
5b0f55aa
                         if (reslevelno >= codsty->nreslevels)
                             continue;
 
7ca0cd58
                         if (yc % (1 << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check
612f8cae
                             continue;
 
7ca0cd58
                         if (xc % (1 << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check
612f8cae
                             continue;
 
                         // check if a precinct exists
                         prcx   = ff_jpeg2000_ceildivpow2(xc, reducedresno) >> rlevel->log2_prec_width;
                         prcy   = ff_jpeg2000_ceildivpow2(yc, reducedresno) >> rlevel->log2_prec_height;
                         prcx  -= ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], reducedresno) >> rlevel->log2_prec_width;
                         prcy  -= ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], reducedresno) >> rlevel->log2_prec_height;
 
                         precno = prcx + rlevel->num_precincts_x * prcy;
 
08326e73
                         ok_reslevel = 1;
612f8cae
                         if (prcx >= rlevel->num_precincts_x || prcy >= rlevel->num_precincts_y) {
                             av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n",
                                    prcx, prcy, rlevel->num_precincts_x, rlevel->num_precincts_y);
                             continue;
                         }
 
c72a8319
                             for (layno = 0; layno < LYEpoc; layno++) {
b75c0a72
                                 if ((ret = jpeg2000_decode_packet(s, tile, tp_index,
612f8cae
                                                                 codsty, rlevel,
                                                                 precno, layno,
                                                                 qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
                                                                 qntsty->nguardbits)) < 0)
                                     return ret;
                             }
                     }
                 }
             }
         }
d57c737a
         break;
 
     case JPEG2000_PGOD_PCRL:
f5822ea3
         av_log(s->avctx, AV_LOG_WARNING, "Progression order PCRL\n");
c3517c37
         step_x = 32;
         step_y = 32;
c72a8319
         for (compno = CSpoc; compno < CEpoc; compno++) {
c3517c37
             Jpeg2000Component *comp     = tile->comp + compno;
             Jpeg2000CodingStyle *codsty = tile->codsty + compno;
 
c72a8319
             for (reslevelno = RSpoc; reslevelno < FFMIN(codsty->nreslevels, REpoc); reslevelno++) {
c3517c37
                 uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; //  ==> N_L - r
                 Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno;
                 step_x = FFMIN(step_x, rlevel->log2_prec_width  + reducedresno);
                 step_y = FFMIN(step_y, rlevel->log2_prec_height + reducedresno);
             }
         }
c08b06c2
         if (step_x >= 31 || step_y >= 31){
             avpriv_request_sample(s->avctx, "PCRL with large step");
             return AVERROR_PATCHWELCOME;
         }
c3517c37
         step_x = 1<<step_x;
         step_y = 1<<step_y;
 
50b77e36
         for (y = tile->coord[1][0]; y < tile->coord[1][1]; y = (y/step_y + 1)*step_y) {
             for (x = tile->coord[0][0]; x < tile->coord[0][1]; x = (x/step_x + 1)*step_x) {
c72a8319
                 for (compno = CSpoc; compno < CEpoc; compno++) {
c3517c37
                     Jpeg2000Component *comp     = tile->comp + compno;
                     Jpeg2000CodingStyle *codsty = tile->codsty + compno;
                     Jpeg2000QuantStyle *qntsty  = tile->qntsty + compno;
                     int xc = x / s->cdx[compno];
                     int yc = y / s->cdy[compno];
 
c72a8319
                     for (reslevelno = RSpoc; reslevelno < FFMIN(codsty->nreslevels, REpoc); reslevelno++) {
c3517c37
                         unsigned prcx, prcy;
                         uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; //  ==> N_L - r
                         Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno;
 
50b77e36
                         if (yc % (1 << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check
c3517c37
                             continue;
 
50b77e36
                         if (xc % (1 << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check
c3517c37
                             continue;
 
                         // check if a precinct exists
                         prcx   = ff_jpeg2000_ceildivpow2(xc, reducedresno) >> rlevel->log2_prec_width;
                         prcy   = ff_jpeg2000_ceildivpow2(yc, reducedresno) >> rlevel->log2_prec_height;
                         prcx  -= ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], reducedresno) >> rlevel->log2_prec_width;
                         prcy  -= ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], reducedresno) >> rlevel->log2_prec_height;
 
                         precno = prcx + rlevel->num_precincts_x * prcy;
 
                         if (prcx >= rlevel->num_precincts_x || prcy >= rlevel->num_precincts_y) {
                             av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n",
                                    prcx, prcy, rlevel->num_precincts_x, rlevel->num_precincts_y);
                             continue;
                         }
 
c72a8319
                         for (layno = 0; layno < LYEpoc; layno++) {
b75c0a72
                             if ((ret = jpeg2000_decode_packet(s, tile, tp_index, codsty, rlevel,
c3517c37
                                                               precno, layno,
                                                               qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
                                                               qntsty->nguardbits)) < 0)
                                 return ret;
                         }
                     }
                 }
             }
         }
d57c737a
         break;
 
c81a7063
     default:
         break;
     }
 
c72a8319
     return ret;
 }
 
 static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
 {
a87ada53
     int ret = AVERROR_BUG;
     int i;
b75c0a72
     int tp_index = 0;
c72a8319
 
     s->bit_index = 8;
     if (tile->poc.nb_poc) {
         for (i=0; i<tile->poc.nb_poc; i++) {
             Jpeg2000POCEntry *e = &tile->poc.poc[i];
             ret = jpeg2000_decode_packets_po_iteration(s, tile,
                 e->RSpoc, e->CSpoc,
8672c0a6
                 FFMIN(e->LYEpoc, tile->codsty[0].nlayers),
                 e->REpoc,
                 FFMIN(e->CEpoc, s->ncomponents),
b75c0a72
                 e->Ppoc, &tp_index
c72a8319
                 );
             if (ret < 0)
                 return ret;
         }
     } else {
         ret = jpeg2000_decode_packets_po_iteration(s, tile,
             0, 0,
             tile->codsty[0].nlayers,
             33,
             s->ncomponents,
b75c0a72
             tile->codsty[0].prog_order,
             &tp_index
c72a8319
         );
     }
c81a7063
     /* 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,
4af9eb4f
                            int bpno, int bandno,
9d56ccf5
                            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++) {
96bbbeba
                 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 | JPEG2000_T1_SGN_S);
f1e17304
                 if ((t1->flags[(y+1) * t1->stride + x+1] & JPEG2000_T1_SIG_NB & flags_mask)
                 && !(t1->flags[(y+1) * t1->stride + x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) {
                     if (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_jpeg2000_getsigctxno(t1->flags[(y+1) * t1->stride + x+1] & flags_mask, bandno))) {
                         int xorbit, ctxno = ff_jpeg2000_getsgnctxno(t1->flags[(y+1) * t1->stride + x+1] & flags_mask, &xorbit);
dc73c7ad
                         if (t1->mqc.raw)
f1e17304
                              t1->data[(y) * t1->stride + x] = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ? -mask : mask;
9d56ccf5
                         else
f1e17304
                              t1->data[(y) * t1->stride + x] = (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ^ xorbit) ?
9d56ccf5
                                                -mask : mask;
c81a7063
 
                         ff_jpeg2000_set_significance(t1, x, y,
f1e17304
                                                      t1->data[(y) * t1->stride + x] < 0);
c81a7063
                     }
f1e17304
                     t1->flags[(y + 1) * t1->stride + x + 1] |= JPEG2000_T1_VIS;
c81a7063
                 }
9d56ccf5
             }
c81a7063
 }
 
 static void decode_refpass(Jpeg2000T1Context *t1, int width, int height,
96bbbeba
                            int bpno, int vert_causal_ctx_csty_symbol)
c81a7063
 {
     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++)
f1e17304
                 if ((t1->flags[(y + 1) * t1->stride + x + 1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS)) == JPEG2000_T1_SIG) {
96bbbeba
                     int flags_mask = (vert_causal_ctx_csty_symbol && y == y0 + 3) ?
                         ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE | JPEG2000_T1_SGN_S) : -1;
f1e17304
                     int ctxno = ff_jpeg2000_getrefctxno(t1->flags[(y + 1) * t1->stride + x + 1] & flags_mask);
c81a7063
                     int r     = ff_mqc_decode(&t1->mqc,
                                               t1->mqc.cx_states + ctxno)
                                 ? phalf : nhalf;
f1e17304
                     t1->data[(y) * t1->stride + x]          += t1->data[(y) * t1->stride + x] < 0 ? -r : r;
                     t1->flags[(y + 1) * t1->stride + x + 1] |= JPEG2000_T1_REF;
c81a7063
                 }
 }
 
 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++) {
96bbbeba
             int flags_mask = -1;
             if (vert_causal_ctx_csty_symbol)
                 flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE | JPEG2000_T1_SGN_S);
c81a7063
             if (y0 + 3 < height &&
f1e17304
                 !((t1->flags[(y0 + 1) * t1->stride + x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
                   (t1->flags[(y0 + 2) * t1->stride + x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
                   (t1->flags[(y0 + 3) * t1->stride + x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
                   (t1->flags[(y0 + 4) * t1->stride + x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG) & flags_mask))) {
c81a7063
                 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++) {
96bbbeba
                 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 | JPEG2000_T1_SGN_S);
c81a7063
                 if (!dec) {
f1e17304
                     if (!(t1->flags[(y+1) * t1->stride + x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) {
                         dec = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_jpeg2000_getsigctxno(t1->flags[(y+1) * t1->stride + x+1] & flags_mask,
9d56ccf5
                                                                                              bandno));
                     }
c81a7063
                 }
                 if (dec) {
                     int xorbit;
f1e17304
                     int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[(y + 1) * t1->stride + x + 1] & flags_mask,
c81a7063
                                                         &xorbit);
f1e17304
                     t1->data[(y) * t1->stride + x] = (ff_mqc_decode(&t1->mqc,
c81a7063
                                                     t1->mqc.cx_states + ctxno) ^
                                       xorbit)
                                      ? -mask : mask;
f1e17304
                     ff_jpeg2000_set_significance(t1, x, y, t1->data[(y) * t1->stride + x] < 0);
c81a7063
                 }
                 dec = 0;
f1e17304
                 t1->flags[(y + 1) * t1->stride + x + 1] &= ~JPEG2000_T1_VIS;
c81a7063
             }
         }
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)
 {
ecbd1117
     int passno = cblk->npasses, pass_t = 2, bpno = cblk->nonzerobits - 1;
dc73c7ad
     int pass_cnt = 0;
64f6570c
     int vert_causal_ctx_csty_symbol = codsty->cblk_style & JPEG2000_CBLK_VSC;
dc73c7ad
     int term_cnt = 0;
     int coder_type;
c81a7063
 
f1e17304
     av_assert0(width <= 1024U && height <= 1024U);
     av_assert0(width*height <= 4096);
9a271a93
 
f1e17304
     memset(t1->data, 0, t1->stride * height * sizeof(*t1->data));
c81a7063
 
a06f0cef
     /* If code-block contains no compressed data: nothing to do. */
28816f9d
     if (!cblk->length)
a06f0cef
         return 0;
 
f1e17304
     memset(t1->flags, 0, t1->stride * (height + 2) * sizeof(*t1->flags));
9d56ccf5
 
     cblk->data[cblk->length] = 0xff;
     cblk->data[cblk->length+1] = 0xff;
eea92133
     ff_mqc_initdec(&t1->mqc, cblk->data, 0, 1);
c81a7063
 
     while (passno--) {
a85b02dc
         if (bpno < 0) {
             av_log(s->avctx, AV_LOG_ERROR, "bpno became negative\n");
             return AVERROR_INVALIDDATA;
         }
9d56ccf5
         switch(pass_t) {
c81a7063
         case 0:
9d56ccf5
             decode_sigpass(t1, width, height, bpno + 1, bandpos,
64f6570c
                            vert_causal_ctx_csty_symbol);
c81a7063
             break;
         case 1:
96bbbeba
             decode_refpass(t1, width, height, bpno + 1, vert_causal_ctx_csty_symbol);
c81a7063
             break;
         case 2:
dc73c7ad
             av_assert2(!t1->mqc.raw);
c81a7063
             decode_clnpass(s, t1, width, height, bpno + 1, bandpos,
64f6570c
                            codsty->cblk_style & JPEG2000_CBLK_SEGSYM,
                            vert_causal_ctx_csty_symbol);
c81a7063
             break;
         }
4a3bc0d9
         if (codsty->cblk_style & JPEG2000_CBLK_RESET) // XXX no testcase for just this
             ff_mqc_init_contexts(&t1->mqc);
 
2819aeb0
         if (passno && (coder_type = needs_termination(codsty->cblk_style, pass_cnt))) {
36241c40
             if (term_cnt >= cblk->nb_terminations) {
dc73c7ad
                 av_log(s->avctx, AV_LOG_ERROR, "Missing needed termination \n");
                 return AVERROR_INVALIDDATA;
             }
5cccbc3b
             if (FFABS(cblk->data + cblk->data_start[term_cnt + 1] - 2 - t1->mqc.bp) > 0) {
                 av_log(s->avctx, AV_LOG_WARNING, "Mid mismatch %"PTRDIFF_SPECIFIER" in pass %d of %d\n",
                     cblk->data + cblk->data_start[term_cnt + 1] - 2 - t1->mqc.bp,
                     pass_cnt, cblk->npasses);
             }
 
dc73c7ad
             ff_mqc_initdec(&t1->mqc, cblk->data + cblk->data_start[++term_cnt], coder_type == 2, 0);
         }
c81a7063
 
         pass_t++;
         if (pass_t == 3) {
             bpno--;
             pass_t = 0;
         }
dc73c7ad
         pass_cnt ++;
c81a7063
     }
6b08dc39
 
20657e05
     if (cblk->data + cblk->length - 2*(term_cnt < cblk->nb_terminations) != t1->mqc.bp) {
         av_log(s->avctx, AV_LOG_WARNING, "End mismatch %"PTRDIFF_SPECIFIER"\n",
                cblk->data + cblk->length - 2*(term_cnt < cblk->nb_terminations) - t1->mqc.bp);
6b08dc39
     }
 
c81a7063
     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];
f1e17304
         int *src = t1->data + j*t1->stride;
6cbd0241
         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];
f1e17304
         int *src = t1->data + j*t1->stride;
96e73fa6
         if (band->i_stepsize == 32768) {
05ef6324
             for (i = 0; i < w; ++i)
                 datap[i] = src[i] / 2;
         } else {
             // This should be VERY uncommon
             for (i = 0; i < w; ++i)
96e73fa6
                 datap[i] = (src[i] * (int64_t)band->i_stepsize) / 65536;
05ef6324
         }
7c9fcdfa
     }
 }
 
 static void dequantization_int_97(int x, int y, Jpeg2000Cblk *cblk,
                                Jpeg2000Component *comp,
                                Jpeg2000T1Context *t1, Jpeg2000Band *band)
 {
     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];
f1e17304
         int *src = t1->data + j*t1->stride;
7c9fcdfa
         for (i = 0; i < w; ++i)
96e73fa6
             datap[i] = (src[i] * (int64_t)band->i_stepsize + (1<<15)) >> 16;
dc60061b
     }
c81a7063
 }
 
c9f2ec8a
 static inline void mct_decode(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
c81a7063
 {
     int i, csize = 1;
c9f2ec8a
     void *src[3];
c81a7063
 
12ba1b2b
     for (i = 1; i < 3; i++) {
ac3b01a9
         if (tile->codsty[0].transform != tile->codsty[i].transform) {
             av_log(s->avctx, AV_LOG_ERROR, "Transforms mismatch, MCT not supported\n");
             return;
         }
12ba1b2b
         if (memcmp(tile->comp[0].coord, tile->comp[i].coord, sizeof(tile->comp[0].coord))) {
             av_log(s->avctx, AV_LOG_ERROR, "Coords mismatch, MCT not supported\n");
             return;
         }
     }
ac3b01a9
 
c81a7063
     for (i = 0; i < 3; i++)
         if (tile->codsty[0].transform == FF_DWT97)
c9f2ec8a
             src[i] = tile->comp[i].f_data;
c81a7063
         else
c9f2ec8a
             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
 
c9f2ec8a
     s->dsp.mct_decode[tile->codsty[0].transform](src[0], src[1], src[2], csize);
c81a7063
 }
 
29b00f88
 static inline void tile_codeblocks(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
c81a7063
 {
     Jpeg2000T1Context t1;
 
     int compno, reslevelno, bandno;
 
3f714d1f
     /* Loop on tile components */
c81a7063
     for (compno = 0; compno < s->ncomponents; compno++) {
         Jpeg2000Component *comp     = tile->comp + compno;
         Jpeg2000CodingStyle *codsty = tile->codsty + compno;
cdb86136
 
f1e17304
         t1.stride = (1<<codsty->log2_cblk_width) + 2;
 
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 */
41bcc3d1
                     for (cblkno = 0;
                          cblkno < prec->nb_codeblocks_width * prec->nb_codeblocks_height;
                          cblkno++) {
c81a7063
                         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);
 
a206c132
                         x = cblk->coord[0][0] - band->coord[0][0];
                         y = cblk->coord[1][0] - band->coord[1][0];
c81a7063
 
83fd377c
                         if (codsty->transform == FF_DWT97)
c81a7063
                             dequantization_float(x, y, cblk, comp, &t1, band);
7c9fcdfa
                         else if (codsty->transform == FF_DWT97_INT)
                             dequantization_int_97(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 */
5788623d
 }
 
29b00f88
 #define WRITE_FRAME(D, PIXEL)                                                                     \
     static inline void write_frame_ ## D(Jpeg2000DecoderContext * s, Jpeg2000Tile * tile,         \
64f72bb6
                                          AVFrame * picture, int precision)                        \
29b00f88
     {                                                                                             \
64f72bb6
         const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(s->avctx->pix_fmt);               \
         int planar    = !!(pixdesc->flags & AV_PIX_FMT_FLAG_PLANAR);                              \
         int pixelsize = planar ? 1 : pixdesc->nb_components;                                      \
                                                                                                   \
29b00f88
         int compno;                                                                               \
         int x, y;                                                                                 \
                                                                                                   \
         for (compno = 0; compno < s->ncomponents; compno++) {                                     \
             Jpeg2000Component *comp     = tile->comp + compno;                                    \
             Jpeg2000CodingStyle *codsty = tile->codsty + compno;                                  \
             PIXEL *line;                                                                          \
             float *datap     = comp->f_data;                                                      \
             int32_t *i_datap = comp->i_data;                                                      \
             int cbps         = s->cbps[compno];                                                   \
             int w            = tile->comp[compno].coord[0][1] - s->image_offset_x;                \
64f72bb6
             int plane        = 0;                                                                 \
                                                                                                   \
             if (planar)                                                                           \
                 plane = s->cdef[compno] ? s->cdef[compno]-1 : (s->ncomponents-1);                 \
29b00f88
                                                                                                   \
64f72bb6
             y    = tile->comp[compno].coord[1][0] - s->image_offset_y / s->cdy[compno];           \
             line = (PIXEL *)picture->data[plane] + y * (picture->linesize[plane] / sizeof(PIXEL));\
             for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y++) {                 \
29b00f88
                 PIXEL *dst;                                                                       \
                                                                                                   \
64f72bb6
                 x   = tile->comp[compno].coord[0][0] - s->image_offset_x / s->cdx[compno];        \
                 dst = line + x * pixelsize + compno*!planar;                                      \
29b00f88
                                                                                                   \
                 if (codsty->transform == FF_DWT97) {                                              \
64f72bb6
                     for (; x < w; x++) {                                                          \
29b00f88
                         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);                                  \
64f72bb6
                         *dst = val << (precision - cbps);                                         \
29b00f88
                         datap++;                                                                  \
64f72bb6
                         dst += pixelsize;                                                         \
29b00f88
                     }                                                                             \
                 } else {                                                                          \
64f72bb6
                     for (; x < w; x++) {                                                          \
29b00f88
                         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);                                  \
64f72bb6
                         *dst = val << (precision - cbps);                                         \
29b00f88
                         i_datap++;                                                                \
64f72bb6
                         dst += pixelsize;                                                         \
29b00f88
                     }                                                                             \
                 }                                                                                 \
64f72bb6
                 line += picture->linesize[plane] / sizeof(PIXEL);                                 \
29b00f88
             }                                                                                     \
         }                                                                                         \
                                                                                                   \
     }
 
 WRITE_FRAME(8, uint8_t)
 WRITE_FRAME(16, uint16_t)
 
 #undef WRITE_FRAME
 
585cfabb
 static int jpeg2000_decode_tile(AVCodecContext *avctx, void *td,
                                 int jobnr, int threadnr)
5788623d
 {
585cfabb
     Jpeg2000DecoderContext *s = avctx->priv_data;
     AVFrame *picture = td;
     Jpeg2000Tile *tile = s->tile + jobnr;
64f72bb6
     int x;
5788623d
 
     tile_codeblocks(s, tile);
c81a7063
 
     /* inverse MCT transformation */
     if (tile->codsty[0].mct)
         mct_decode(s, tile);
 
0aada305
     for (x = 0; x < s->ncomponents; x++) {
         if (s->cdef[x] < 0) {
             for (x = 0; x < s->ncomponents; x++) {
                 s->cdef[x] = x + 1;
             }
             if ((s->ncomponents & 1) == 0)
                 s->cdef[s->ncomponents-1] = 0;
             break;
         }
99de97ca
     }
 
c81a7063
     if (s->precision <= 8) {
64f72bb6
         write_frame_8(s, tile, picture, 8);
c81a7063
     } else {
0916938a
         int precision = picture->format == AV_PIX_FMT_XYZ12 ||
213f2da4
                         picture->format == AV_PIX_FMT_RGB48 ||
                         picture->format == AV_PIX_FMT_RGBA64 ||
0916938a
                         picture->format == AV_PIX_FMT_GRAY16 ? 16 : s->precision;
028c59c1
 
64f72bb6
         write_frame_16(s, tile, picture, precision);
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));
c980c5e5
     memset(s->properties, 0, sizeof(s->properties));
2ec0ba1e
     memset(&s->poc  , 0, sizeof(s->poc));
9054e725
     s->numXtiles = s->numYtiles = 0;
44a7f17d
     s->ncomponents = 0;
c81a7063
 }
 
 static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
 {
     Jpeg2000CodingStyle *codsty = s->codsty;
     Jpeg2000QuantStyle *qntsty  = s->qntsty;
2ec0ba1e
     Jpeg2000POC         *poc    = &s->poc;
c81a7063
     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);
742a26c4
         if (len < 2 || bytestream2_get_bytes_left(&s->g) < len - 2) {
             av_log(s->avctx, AV_LOG_ERROR, "Invalid len %d left=%d\n", len, bytestream2_get_bytes_left(&s->g));
5efadcb8
             return AVERROR_INVALIDDATA;
742a26c4
         }
fd54dd02
 
c81a7063
         switch (marker) {
         case JPEG2000_SIZ:
44a7f17d
             if (s->ncomponents) {
                 av_log(s->avctx, AV_LOG_ERROR, "Duplicate SIZ\n");
                 return AVERROR_INVALIDDATA;
             }
c81a7063
             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;
2ec0ba1e
         case JPEG2000_POC:
             ret = get_poc(s, len, poc);
             break;
c81a7063
         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;
2ec0ba1e
                 poc    = &s->tile[s->curtileno].poc;
9d56ccf5
                 properties = s->tile[s->curtileno].properties;
             }
c81a7063
             break;
db53a230
         case JPEG2000_PLM:
             // the PLM marker is ignored
c81a7063
         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;
45db9218
         case JPEG2000_PLT:
             // Packet length, tile-part header
             ret = get_plt(s, len);
             break;
c81a7063
         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;
 
4bfdd967
         if ((ret = init_tile(s, tileno)) < 0)
9d56ccf5
             return ret;
 
         s->g = tile->tile_part[0].tpg;
4bfdd967
         if ((ret = jpeg2000_decode_packets(s, tile)) < 0)
9d56ccf5
             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;
a75ef150
                 atom2_size -= 8;
b39a6bbe
                 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];
b998a56b
                             g |= g >> colour_depth[1];
b39a6bbe
                         } 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];
b998a56b
                             b |= b >> colour_depth[2];
b39a6bbe
                         } 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);
f8f155a1
                         if (cn < 4 && asoc < 4)
99de97ca
                             s->cdef[cn] = asoc;
                     }
4c1aac89
                 } else if (atom2 == MKBETAG('r','e','s',' ') && atom2_size >= 18) {
                     int64_t vnum, vden, hnum, hden, vexp, hexp;
                     uint32_t resx;
                     bytestream2_skip(&s->g, 4);
                     resx = bytestream2_get_be32u(&s->g);
                     if (resx != MKBETAG('r','e','s','c') && resx != MKBETAG('r','e','s','d')) {
                         bytestream2_seek(&s->g, atom2_end, SEEK_SET);
                         continue;
                     }
                     vnum = bytestream2_get_be16u(&s->g);
                     vden = bytestream2_get_be16u(&s->g);
                     hnum = bytestream2_get_be16u(&s->g);
                     hden = bytestream2_get_be16u(&s->g);
                     vexp = bytestream2_get_byteu(&s->g);
                     hexp = bytestream2_get_byteu(&s->g);
5d0b69f3
                     if (!vnum || !vden || !hnum || !hden) {
1b006003
                         bytestream2_seek(&s->g, atom2_end, SEEK_SET);
                         av_log(s->avctx, AV_LOG_WARNING, "RES box invalid\n");
                         continue;
                     }
4c1aac89
                     if (vexp > hexp) {
                         vexp -= hexp;
                         hexp = 0;
                     } else {
                         hexp -= vexp;
                         vexp = 0;
                     }
                     if (   INT64_MAX / (hnum * vden) > pow(10, hexp)
                         && INT64_MAX / (vnum * hden) > pow(10, vexp))
                         av_reduce(&s->sar.den, &s->sar.num,
                                   hnum * vden * pow(10, hexp),
                                   vnum * hden * pow(10, vexp),
                                   INT32_MAX);
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;
 }
 
c9f2ec8a
 static av_cold int jpeg2000_decode_init(AVCodecContext *avctx)
 {
     Jpeg2000DecoderContext *s = avctx->priv_data;
 
     ff_jpeg2000dsp_init(&s->dsp);
 
     return 0;
 }
 
c81a7063
 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;
585cfabb
     int ret;
c81a7063
 
     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
 
585cfabb
     avctx->execute2(avctx, jpeg2000_decode_tile, picture, NULL, s->numXtiles * s->numYtiles);
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));
4c1aac89
     if (s->sar.num && s->sar.den)
         avctx->sample_aspect_ratio = s->sar;
     s->sar.num = s->sar.den = 0;
b39a6bbe
 
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 },
 };
 
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,
585cfabb
     .capabilities     = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_DR1,
70f96615
     .priv_data_size   = sizeof(Jpeg2000DecoderContext),
     .init_static_data = jpeg2000_init_static_data,
c9f2ec8a
     .init             = jpeg2000_decode_init,
70f96615
     .decode           = jpeg2000_decode_frame,
0915b531
     .priv_class       = &jpeg2000_class,
8cf57efd
     .max_lowres       = 5,
2c681139
     .profiles         = NULL_IF_CONFIG_SMALL(ff_jpeg2000_profiles)
c81a7063
 };