diff options
Diffstat (limited to 'libavcodec/jpeglsdec.c')
-rw-r--r-- | libavcodec/jpeglsdec.c | 154 |
1 files changed, 133 insertions, 21 deletions
diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c index 9f7735e..e85f511 100644 --- a/libavcodec/jpeglsdec.c +++ b/libavcodec/jpeglsdec.c @@ -3,20 +3,20 @@ * Copyright (c) 2003 Michael Niedermayer * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -40,7 +40,7 @@ * (or test broken JPEG-LS decoder) and slow down ordinary decoding a bit. * * There is no Golomb code with length >= 32 bits possible, so check and - * avoid situation of 32 zeros, Libav Golomb decoder is painfully slow + * avoid situation of 32 zeros, FFmpeg Golomb decoder is painfully slow * on this errors. */ //#define JLS_BROKEN @@ -51,27 +51,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); @@ -149,6 +201,8 @@ static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, ret = ret >> 1; } + if(FFABS(ret) > 0xFFFF) + return -0x10000; /* update state */ state->A[Q] += FFABS(ret) - RItype; ret *= state->twonear; @@ -208,11 +262,19 @@ static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, r = ff_log2_run[state->run_index[comp]]; if (r) r = get_bits_long(&s->gb, r); + if (x + r * stride > w) { + r = (w - x) / stride; + } for (i = 0; i < r; i++) { W(dst, x, Ra); x += stride; } + if (x >= w) { + av_log(NULL, AV_LOG_ERROR, "run overflow\n"); + return; + } + /* decode run termination value */ Rb = R(last, x); RItype = (FFABS(Ra - Rb) <= state->near) ? 1 : 0; @@ -298,21 +360,23 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, else shift = point_transform + (16 - s->bits); - av_dlog(s->avctx, - "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) " - "RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n", - s->width, s->height, state->near, state->maxval, - state->T1, state->T2, state->T3, - state->reset, state->limit, state->qbpp, state->range); - av_dlog(s->avctx, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n", - ilv, point_transform, s->bits, s->cur_scan); + if (s->avctx->debug & FF_DEBUG_PICT_INFO) { + av_log(s->avctx, AV_LOG_DEBUG, + "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) " + "RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n", + s->width, s->height, state->near, state->maxval, + state->T1, state->T2, state->T3, + state->reset, state->limit, state->qbpp, state->range); + av_log(s->avctx, AV_LOG_DEBUG, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n", + ilv, point_transform, s->bits, s->cur_scan); + } if (ilv == 0) { /* separate planes */ if (s->cur_scan > s->nb_components) { ret = AVERROR_INVALIDDATA; goto end; } - off = s->cur_scan - 1; stride = (s->nb_components > 1) ? 3 : 1; + off = av_clip(s->cur_scan - 1, 0, stride - 1); width = s->width * stride; cur += off; for (i = 0; i < s->height; i++) { @@ -334,12 +398,13 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, } else if (ilv == 1) { /* line interleaving */ int j; int Rc[3] = { 0, 0, 0 }; + stride = (s->nb_components > 1) ? 3 : 1; memset(cur, 0, s->picture_ptr->linesize[0]); - width = s->width * 3; + width = s->width * stride; for (i = 0; i < s->height; i++) { - for (j = 0; j < 3; j++) { + for (j = 0; j < stride; j++) { ls_decode_line(state, s, last + j, cur + j, - Rc[j], width, 3, j, 8); + Rc[j], width, stride, j, 8); Rc[j] = last[j]; if (s->restart_interval && !--s->restart_count) { @@ -356,6 +421,53 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, goto end; } + if (s->xfrm && s->nb_components == 3) { + int x, w; + + w = s->width * s->nb_components; + + if (s->bits <= 8) { + uint8_t *src = s->picture_ptr->data[0]; + + for (i = 0; i < s->height; i++) { + switch(s->xfrm) { + case 1: + for (x = off; x < w; x += 3) { + src[x ] += src[x+1] + 128; + src[x+2] += src[x+1] + 128; + } + break; + case 2: + for (x = off; x < w; x += 3) { + src[x ] += src[x+1] + 128; + src[x+2] += ((src[x ] + src[x+1])>>1) + 128; + } + break; + case 3: + for (x = off; x < w; x += 3) { + int g = src[x+0] - ((src[x+2]+src[x+1])>>2) + 64; + src[x+0] = src[x+2] + g + 128; + src[x+2] = src[x+1] + g + 128; + src[x+1] = g; + } + break; + case 4: + for (x = off; x < w; x += 3) { + int r = src[x+0] - (( 359 * (src[x+2]-128) + 490) >> 8); + int g = src[x+0] - (( 88 * (src[x+1]-128) - 183 * (src[x+2]-128) + 30) >> 8); + int b = src[x+0] + ((454 * (src[x+1]-128) + 574) >> 8); + src[x+0] = av_clip_uint8(r); + src[x+1] = av_clip_uint8(g); + src[x+2] = av_clip_uint8(b); + } + break; + } + src += s->picture_ptr->linesize[0]; + } + }else + avpriv_report_missing_feature(s->avctx, "16bit xfrm"); + } + if (shift) { /* we need to do point transform or normalize samples */ int x, w; |