diff options
Diffstat (limited to 'libavcodec/jpeglsdec.c')
-rw-r--r-- | libavcodec/jpeglsdec.c | 107 |
1 files changed, 81 insertions, 26 deletions
diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c index df72ca338f..1dda2073e5 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 */ @@ -39,7 +39,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 @@ -148,6 +148,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; @@ -207,6 +209,9 @@ 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; @@ -276,9 +281,9 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, JLSState *state; int off = 0, stride = 1, width, shift, ret = 0; - zero = av_mallocz(s->picture_ptr->linesize[0]); + zero = av_mallocz(s->picture.linesize[0]); last = zero; - cur = s->picture_ptr->data[0]; + cur = s->picture.data[0]; state = av_mallocz(sizeof(JLSState)); /* initialize JPEG-LS state from JPEG parameters */ @@ -297,21 +302,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++) { @@ -323,7 +330,7 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, t = *((uint16_t *)last); } last = cur; - cur += s->picture_ptr->linesize[0]; + cur += s->picture.linesize[0]; if (s->restart_interval && !--s->restart_count) { align_get_bits(&s->gb); @@ -333,12 +340,13 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, } else if (ilv == 1) { /* line interleaving */ int j; int Rc[3] = { 0, 0, 0 }; - memset(cur, 0, s->picture_ptr->linesize[0]); - width = s->width * 3; + stride = (s->nb_components > 1) ? 3 : 1; + memset(cur, 0, s->picture.linesize[0]); + 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) { @@ -347,7 +355,7 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, } } last = cur; - cur += s->picture_ptr->linesize[0]; + cur += s->picture.linesize[0]; } } else if (ilv == 2) { /* sample interleaving */ avpriv_report_missing_feature(s->avctx, "Sample interleaved images"); @@ -355,26 +363,73 @@ 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.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.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; w = s->width * s->nb_components; if (s->bits <= 8) { - uint8_t *src = s->picture_ptr->data[0]; + uint8_t *src = s->picture.data[0]; for (i = 0; i < s->height; i++) { for (x = off; x < w; x += stride) src[x] <<= shift; - src += s->picture_ptr->linesize[0]; + src += s->picture.linesize[0]; } } else { - uint16_t *src = (uint16_t *)s->picture_ptr->data[0]; + uint16_t *src = (uint16_t *)s->picture.data[0]; for (i = 0; i < s->height; i++) { for (x = 0; x < w; x++) src[x] <<= shift; - src += s->picture_ptr->linesize[0] / 2; + src += s->picture.linesize[0] / 2; } } } |