diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2015-06-26 18:04:16 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2015-06-26 20:59:05 +0200 |
commit | 2ec0ba1e220358e21751071053131a152ea24d57 (patch) | |
tree | 242acb39f9f68984b926945546f3ac148d67a579 | |
parent | 1f1e0a2971b2a01f275bb5088c2e36166514be64 (diff) | |
download | ffmpeg-2ec0ba1e220358e21751071053131a152ea24d57.tar.gz |
avcodec/jpeg2000dec: Parse POCs
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/jpeg2000dec.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index d463b074ca..e3a964b94b 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -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; |