You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
avcodec/jpeg2000dec: Parse POCs
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
@@ -47,6 +47,23 @@
|
|||||||
#define HAD_COC 0x01
|
#define HAD_COC 0x01
|
||||||
#define HAD_QCC 0x02
|
#define HAD_QCC 0x02
|
||||||
|
|
||||||
|
#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;
|
||||||
|
|
||||||
typedef struct Jpeg2000TilePart {
|
typedef struct Jpeg2000TilePart {
|
||||||
uint8_t tile_index; // Tile index who refers the tile-part
|
uint8_t tile_index; // Tile index who refers the tile-part
|
||||||
const uint8_t *tp_end;
|
const uint8_t *tp_end;
|
||||||
@@ -60,6 +77,7 @@ typedef struct Jpeg2000Tile {
|
|||||||
uint8_t properties[4];
|
uint8_t properties[4];
|
||||||
Jpeg2000CodingStyle codsty[4];
|
Jpeg2000CodingStyle codsty[4];
|
||||||
Jpeg2000QuantStyle qntsty[4];
|
Jpeg2000QuantStyle qntsty[4];
|
||||||
|
Jpeg2000POC poc;
|
||||||
Jpeg2000TilePart tile_part[256];
|
Jpeg2000TilePart tile_part[256];
|
||||||
uint16_t tp_idx; // Tile-part index
|
uint16_t tp_idx; // Tile-part index
|
||||||
int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
|
int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
|
||||||
@@ -89,6 +107,7 @@ typedef struct Jpeg2000DecoderContext {
|
|||||||
|
|
||||||
Jpeg2000CodingStyle codsty[4];
|
Jpeg2000CodingStyle codsty[4];
|
||||||
Jpeg2000QuantStyle qntsty[4];
|
Jpeg2000QuantStyle qntsty[4];
|
||||||
|
Jpeg2000POC poc;
|
||||||
|
|
||||||
int bit_index;
|
int bit_index;
|
||||||
|
|
||||||
@@ -624,6 +643,67 @@ static int get_qcc(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q,
|
|||||||
return get_qcx(s, n - 1, q + compno);
|
return get_qcx(s, n - 1, q + compno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
avpriv_request_sample(s->avctx, "Fat POC not supported\n");
|
||||||
|
return AVERROR_PATCHWELCOME;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp.nb_poc = (size - 2) / elem_size;
|
||||||
|
if (tmp.nb_poc > MAX_POCS) {
|
||||||
|
avpriv_request_sample(s->avctx, "Too many POCs (%d)\n", tmp.nb_poc);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get start of tile segment. */
|
/* Get start of tile segment. */
|
||||||
static int get_sot(Jpeg2000DecoderContext *s, int n)
|
static int get_sot(Jpeg2000DecoderContext *s, int n)
|
||||||
{
|
{
|
||||||
@@ -668,6 +748,8 @@ static int get_sot(Jpeg2000DecoderContext *s, int n)
|
|||||||
/* copy defaults */
|
/* copy defaults */
|
||||||
memcpy(tile->codsty, s->codsty, s->ncomponents * sizeof(Jpeg2000CodingStyle));
|
memcpy(tile->codsty, s->codsty, s->ncomponents * sizeof(Jpeg2000CodingStyle));
|
||||||
memcpy(tile->qntsty, s->qntsty, s->ncomponents * sizeof(Jpeg2000QuantStyle));
|
memcpy(tile->qntsty, s->qntsty, s->ncomponents * sizeof(Jpeg2000QuantStyle));
|
||||||
|
memcpy(&tile->poc , &s->poc , sizeof(tile->poc));
|
||||||
|
tile->poc.is_default = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1680,6 +1762,7 @@ static void jpeg2000_dec_cleanup(Jpeg2000DecoderContext *s)
|
|||||||
av_freep(&s->tile);
|
av_freep(&s->tile);
|
||||||
memset(s->codsty, 0, sizeof(s->codsty));
|
memset(s->codsty, 0, sizeof(s->codsty));
|
||||||
memset(s->qntsty, 0, sizeof(s->qntsty));
|
memset(s->qntsty, 0, sizeof(s->qntsty));
|
||||||
|
memset(&s->poc , 0, sizeof(s->poc));
|
||||||
s->numXtiles = s->numYtiles = 0;
|
s->numXtiles = s->numYtiles = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1687,6 +1770,7 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
|
|||||||
{
|
{
|
||||||
Jpeg2000CodingStyle *codsty = s->codsty;
|
Jpeg2000CodingStyle *codsty = s->codsty;
|
||||||
Jpeg2000QuantStyle *qntsty = s->qntsty;
|
Jpeg2000QuantStyle *qntsty = s->qntsty;
|
||||||
|
Jpeg2000POC *poc = &s->poc;
|
||||||
uint8_t *properties = s->properties;
|
uint8_t *properties = s->properties;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -1753,11 +1837,15 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
|
|||||||
case JPEG2000_QCD:
|
case JPEG2000_QCD:
|
||||||
ret = get_qcd(s, len, qntsty, properties);
|
ret = get_qcd(s, len, qntsty, properties);
|
||||||
break;
|
break;
|
||||||
|
case JPEG2000_POC:
|
||||||
|
ret = get_poc(s, len, poc);
|
||||||
|
break;
|
||||||
case JPEG2000_SOT:
|
case JPEG2000_SOT:
|
||||||
if (!(ret = get_sot(s, len))) {
|
if (!(ret = get_sot(s, len))) {
|
||||||
av_assert1(s->curtileno >= 0);
|
av_assert1(s->curtileno >= 0);
|
||||||
codsty = s->tile[s->curtileno].codsty;
|
codsty = s->tile[s->curtileno].codsty;
|
||||||
qntsty = s->tile[s->curtileno].qntsty;
|
qntsty = s->tile[s->curtileno].qntsty;
|
||||||
|
poc = &s->tile[s->curtileno].poc;
|
||||||
properties = s->tile[s->curtileno].properties;
|
properties = s->tile[s->curtileno].properties;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user