diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-04-01 13:43:44 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-04-01 13:43:44 +0200 |
commit | 254f653b24cd110fb452531bcad13083d592354e (patch) | |
tree | 7cd302678f8d9ac5b7ba8109f3f366388322b77a | |
parent | 879072018f682012d05a400e44df29daef831f47 (diff) | |
download | ffmpeg-254f653b24cd110fb452531bcad13083d592354e.tar.gz |
avcodec/jpeglsdec: add PAL8 support
Fixes Ticket3478
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/jpeglsdec.c | 48 | ||||
-rw-r--r-- | libavcodec/mjpegdec.c | 2 | ||||
-rw-r--r-- | libavcodec/mjpegdec.h | 1 |
3 files changed, 48 insertions, 3 deletions
diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c index 190b9b6d26..003656ff9d 100644 --- a/libavcodec/jpeglsdec.c +++ b/libavcodec/jpeglsdec.c @@ -50,8 +50,9 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s) { int id; + int tid, wt, maxtab, i, j; - skip_bits(&s->gb, 16); /* length: FIXME: verify field validity */ + int len = get_bits(&s->gb, 16); /* length: FIXME: verify field validity */ id = get_bits(&s->gb, 8); switch (id) { @@ -66,9 +67,50 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s) //FIXME quant table? break; case 2: + s->palette_index = 0; case 3: - av_log(s->avctx, AV_LOG_ERROR, "palette not supported\n"); - return AVERROR(ENOSYS); + tid= get_bits(&s->gb, 8); + wt = get_bits(&s->gb, 8); + + if (len < 5) + return AVERROR_INVALIDDATA; + + if (wt < 1 || wt > MAX_COMPONENTS) { + avpriv_request_sample(s->avctx, "wt %d", wt); + return AVERROR_PATCHWELCOME; + } + + if ((5 + wt*(s->maxval+1)) < 65535) + maxtab = s->maxval; + else + maxtab = 65530/wt - 1; + + if(s->avctx->debug & FF_DEBUG_PICT_INFO) { + av_log(s->avctx, AV_LOG_DEBUG, "LSE palette %d tid:%d wt:%d maxtab:%d\n", id, tid, wt, maxtab); + } + if (maxtab >= 256) { + avpriv_request_sample(s->avctx, ">8bit palette"); + return AVERROR_PATCHWELCOME; + } + maxtab = FFMIN(maxtab, (len - 5) / wt + s->palette_index); + + if (s->palette_index > maxtab) + return AVERROR_INVALIDDATA; + + if ((s->avctx->pix_fmt == AV_PIX_FMT_GRAY8 || s->avctx->pix_fmt == AV_PIX_FMT_PAL8) && + (s->picture_ptr->format == AV_PIX_FMT_GRAY8 || s->picture_ptr->format == AV_PIX_FMT_PAL8)) { + uint32_t *pal = s->picture_ptr->data[1]; + s->picture_ptr->format = + s->avctx->pix_fmt = AV_PIX_FMT_PAL8; + for (i=s->palette_index; i<maxtab; i++) { + pal[i] = 0; + for (j=0; j<wt; j++) { + pal[i] |= get_bits(&s->gb, 8) << (8*wt); + } + } + s->palette_index = i; + } + break; case 4: av_log(s->avctx, AV_LOG_ERROR, "oversize image not supported\n"); return AVERROR(ENOSYS); diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 3c103953f9..9f7d08fc85 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -517,6 +517,8 @@ unk_pixfmt: s->upscale_h = s->upscale_v = 0; if (s->nb_components > 1) s->avctx->pix_fmt = AV_PIX_FMT_RGB24; + else if (s->palette_index && s->bits <= 8) + s->avctx->pix_fmt = AV_PIX_FMT_PAL8; else if (s->bits <= 8) s->avctx->pix_fmt = AV_PIX_FMT_GRAY8; else diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h index 77bbfed1d9..a94778846e 100644 --- a/libavcodec/mjpegdec.h +++ b/libavcodec/mjpegdec.h @@ -102,6 +102,7 @@ typedef struct MJpegDecodeContext { int16_t (*blocks[MAX_COMPONENTS])[64]; ///< intermediate sums (progressive mode) uint8_t *last_nnz[MAX_COMPONENTS]; uint64_t coefs_finished[MAX_COMPONENTS]; ///< bitmask of which coefs have been completely decoded (progressive mode) + int palette_index; ScanTable scantable; DSPContext dsp; HpelDSPContext hdsp; |