diff options
Diffstat (limited to 'chromium/third_party/ffmpeg/libavcodec/jpeglsdec.c')
-rw-r--r-- | chromium/third_party/ffmpeg/libavcodec/jpeglsdec.c | 60 |
1 files changed, 56 insertions, 4 deletions
diff --git a/chromium/third_party/ffmpeg/libavcodec/jpeglsdec.c b/chromium/third_party/ffmpeg/libavcodec/jpeglsdec.c index 190b9b6d264..fb3762dad05 100644 --- a/chromium/third_party/ffmpeg/libavcodec/jpeglsdec.c +++ b/chromium/third_party/ffmpeg/libavcodec/jpeglsdec.c @@ -50,27 +50,79 @@ 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); id = get_bits(&s->gb, 8); switch (id) { case 1: + if (len < 13) + return AVERROR_INVALIDDATA; + s->maxval = get_bits(&s->gb, 16); s->t1 = get_bits(&s->gb, 16); s->t2 = get_bits(&s->gb, 16); s->t3 = get_bits(&s->gb, 16); s->reset = get_bits(&s->gb, 16); + if(s->avctx->debug & FF_DEBUG_PICT_INFO) { + av_log(s->avctx, AV_LOG_DEBUG, "Coding parameters maxval:%d T1:%d T2:%d T3:%d reset:%d\n", + s->maxval, s->t1, s->t2, s->t3, s->reset); + } + // ff_jpegls_reset_coding_parameters(s, 0); //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 (!s->maxval) + maxtab = 255; + else 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 = (uint32_t *)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-j-1)); + } + } + s->palette_index = i; + } + break; case 4: - av_log(s->avctx, AV_LOG_ERROR, "oversize image not supported\n"); + avpriv_request_sample(s->avctx, "oversize image"); return AVERROR(ENOSYS); default: av_log(s->avctx, AV_LOG_ERROR, "invalid id %d\n", id); |