func: static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, int *tp_index,
  
                                    Jpeg2000CodingStyle *codsty,
  
                                    Jpeg2000ResLevel *rlevel, int precno,
  
                                    int layno, uint8_t *expn, int numgbits)
  
  {
  
      int bandno, cblkno, ret, nb_code_blocks;
  
      int cwsno;
  
  
  
      if (layno < rlevel->band[0].prec[precno].decoded_layers)
  
          return 0;
  
      rlevel->band[0].prec[precno].decoded_layers = layno + 1;
  
  
  
      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;
  
          }
  
      }
  
  
  
      if (bytestream2_peek_be32(&s->g) == JPEG2000_SOP_FIXED_BYTES)
  
          bytestream2_skip(&s->g, JPEG2000_SOP_BYTE_LENGTH);
  
  
  
      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;
  
  
  
              if (!cblk->npasses) {
  
                  int v = expn[bandno] + numgbits - 1 -
  
                          tag_tree_decode(s, prec->zerobits + cblkno, 100);
  
                  if (v < 0 || v > 30) {
  
                      av_log(s->avctx, AV_LOG_ERROR,
  
                             "nonzerobits %d invalid or unsupported\n", v);
  
                      return AVERROR_INVALIDDATA;
  
                  }
  
                  cblk->nonzerobits = v;
  
              }
  
              if ((newpasses = getnpasses(s)) < 0)
  
                  return newpasses;
  
              av_assert2(newpasses > 0);
  
              if (cblk->npasses + newpasses >= JPEG2000_MAX_PASSES) {
  
                  avpriv_request_sample(s->avctx, "Too many passes");
  
                  return AVERROR_PATCHWELCOME;
  
              }
  
              if ((llen = getlblockinc(s)) < 0)
  
                  return llen;
  
              if (cblk->lblock + llen + av_log2(newpasses) > 16) {
  
                  avpriv_request_sample(s->avctx,
  
                                        "Block with length beyond 16 bits");
  
                  return AVERROR_PATCHWELCOME;
  
              }
  
  
  
              cblk->lblock += llen;
  
  
  
              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;
  
                  if (ret > sizeof(cblk->data)) {
  
                      avpriv_request_sample(s->avctx,
  
                                          "Block with lengthinc greater than %"SIZE_SPECIFIER"",
  
                                          sizeof(cblk->data));
  
                      return AVERROR_PATCHWELCOME;
  
                  }
  
                  cblk->lengthinc[cblk->nb_lengthinc++] = ret;
  
                  cblk->npasses  += newpasses1;
  
                  newpasses -= newpasses1;
  
              } while(newpasses);
  
          }
  
      }
  
      jpeg2000_flush(s);
  
  
  
      if (codsty->csty & JPEG2000_CSTY_EPH) {
  
          if (bytestream2_peek_be16(&s->g) == JPEG2000_EPH)
  
              bytestream2_skip(&s->g, 2);
  
          else
  
              av_log(s->avctx, AV_LOG_ERROR, "EPH marker not found. instead %X\n", bytestream2_peek_be32(&s->g));
  
      }
  
  
  
      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;
  
              for (cwsno = 0; cwsno < cblk->nb_lengthinc; cwsno ++) {
  
                  if (   bytestream2_get_bytes_left(&s->g) < cblk->lengthinc[cwsno]
  
                      || sizeof(cblk->data) < cblk->length + cblk->lengthinc[cwsno] + 4
  
                  ) {
  
                      av_log(s->avctx, AV_LOG_ERROR,
  
                          "Block length %"PRIu16" or lengthinc %d is too large, left %d\n",
  
                          cblk->length, cblk->lengthinc[cwsno], bytestream2_get_bytes_left(&s->g));
  
                      return AVERROR_INVALIDDATA;
  
                  }
  
  
  
                  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;
  
                  }
  
              }
  
          }
  
      }
  
      return 0;
  
  }
  