avcodec/jpeg2000dec: Parse POCs
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
1f1e0a2971
commit
2ec0ba1e22
@ -47,6 +47,23 @@
|
||||
#define HAD_COC 0x01
|
||||
#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 {
|
||||
uint8_t tile_index; // Tile index who refers the tile-part
|
||||
const uint8_t *tp_end;
|
||||
@ -60,6 +77,7 @@ typedef struct Jpeg2000Tile {
|
||||
uint8_t properties[4];
|
||||
Jpeg2000CodingStyle codsty[4];
|
||||
Jpeg2000QuantStyle qntsty[4];
|
||||
Jpeg2000POC poc;
|
||||
Jpeg2000TilePart tile_part[256];
|
||||
uint16_t tp_idx; // Tile-part index
|
||||
int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
|
||||
@ -89,6 +107,7 @@ typedef struct Jpeg2000DecoderContext {
|
||||
|
||||
Jpeg2000CodingStyle codsty[4];
|
||||
Jpeg2000QuantStyle qntsty[4];
|
||||
Jpeg2000POC poc;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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. */
|
||||
static int get_sot(Jpeg2000DecoderContext *s, int n)
|
||||
{
|
||||
@ -668,6 +748,8 @@ static int get_sot(Jpeg2000DecoderContext *s, int n)
|
||||
/* copy defaults */
|
||||
memcpy(tile->codsty, s->codsty, s->ncomponents * sizeof(Jpeg2000CodingStyle));
|
||||
memcpy(tile->qntsty, s->qntsty, s->ncomponents * sizeof(Jpeg2000QuantStyle));
|
||||
memcpy(&tile->poc , &s->poc , sizeof(tile->poc));
|
||||
tile->poc.is_default = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1680,6 +1762,7 @@ static void jpeg2000_dec_cleanup(Jpeg2000DecoderContext *s)
|
||||
av_freep(&s->tile);
|
||||
memset(s->codsty, 0, sizeof(s->codsty));
|
||||
memset(s->qntsty, 0, sizeof(s->qntsty));
|
||||
memset(&s->poc , 0, sizeof(s->poc));
|
||||
s->numXtiles = s->numYtiles = 0;
|
||||
}
|
||||
|
||||
@ -1687,6 +1770,7 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
|
||||
{
|
||||
Jpeg2000CodingStyle *codsty = s->codsty;
|
||||
Jpeg2000QuantStyle *qntsty = s->qntsty;
|
||||
Jpeg2000POC *poc = &s->poc;
|
||||
uint8_t *properties = s->properties;
|
||||
|
||||
for (;;) {
|
||||
@ -1753,11 +1837,15 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
|
||||
case JPEG2000_QCD:
|
||||
ret = get_qcd(s, len, qntsty, properties);
|
||||
break;
|
||||
case JPEG2000_POC:
|
||||
ret = get_poc(s, len, poc);
|
||||
break;
|
||||
case JPEG2000_SOT:
|
||||
if (!(ret = get_sot(s, len))) {
|
||||
av_assert1(s->curtileno >= 0);
|
||||
codsty = s->tile[s->curtileno].codsty;
|
||||
qntsty = s->tile[s->curtileno].qntsty;
|
||||
poc = &s->tile[s->curtileno].poc;
|
||||
properties = s->tile[s->curtileno].properties;
|
||||
}
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user