yading@10: /* yading@10: * JPEG-LS decoder yading@10: * Copyright (c) 2003 Michael Niedermayer yading@10: * Copyright (c) 2006 Konstantin Shishkov yading@10: * yading@10: * This file is part of FFmpeg. yading@10: * yading@10: * FFmpeg is free software; you can redistribute it and/or yading@10: * modify it under the terms of the GNU Lesser General Public yading@10: * License as published by the Free Software Foundation; either yading@10: * version 2.1 of the License, or (at your option) any later version. yading@10: * yading@10: * FFmpeg is distributed in the hope that it will be useful, yading@10: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@10: * Lesser General Public License for more details. yading@10: * yading@10: * You should have received a copy of the GNU Lesser General Public yading@10: * License along with FFmpeg; if not, write to the Free Software yading@10: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@10: */ yading@10: yading@10: /** yading@10: * @file yading@10: * JPEG-LS decoder. yading@10: */ yading@10: yading@10: #include "avcodec.h" yading@10: #include "get_bits.h" yading@10: #include "golomb.h" yading@10: #include "mathops.h" yading@10: #include "mjpeg.h" yading@10: #include "mjpegdec.h" yading@10: #include "jpegls.h" yading@10: #include "jpeglsdec.h" yading@10: yading@10: yading@10: /* yading@10: * Uncomment this to significantly speed up decoding of broken JPEG-LS yading@10: * (or test broken JPEG-LS decoder) and slow down ordinary decoding a bit. yading@10: * yading@10: * There is no Golomb code with length >= 32 bits possible, so check and yading@10: * avoid situation of 32 zeros, FFmpeg Golomb decoder is painfully slow yading@10: * on this errors. yading@10: */ yading@10: //#define JLS_BROKEN yading@10: yading@10: yading@10: /** yading@10: * Decode LSE block with initialization parameters yading@10: */ yading@10: int ff_jpegls_decode_lse(MJpegDecodeContext *s) yading@10: { yading@10: int id; yading@10: yading@10: skip_bits(&s->gb, 16); /* length: FIXME: verify field validity */ yading@10: id = get_bits(&s->gb, 8); yading@10: yading@10: switch(id){ yading@10: case 1: yading@10: s->maxval= get_bits(&s->gb, 16); yading@10: s->t1= get_bits(&s->gb, 16); yading@10: s->t2= get_bits(&s->gb, 16); yading@10: s->t3= get_bits(&s->gb, 16); yading@10: s->reset= get_bits(&s->gb, 16); yading@10: yading@10: // ff_jpegls_reset_coding_parameters(s, 0); yading@10: //FIXME quant table? yading@10: break; yading@10: case 2: yading@10: case 3: yading@10: av_log(s->avctx, AV_LOG_ERROR, "palette not supported\n"); yading@10: return -1; yading@10: case 4: yading@10: av_log(s->avctx, AV_LOG_ERROR, "oversize image not supported\n"); yading@10: return -1; yading@10: default: yading@10: av_log(s->avctx, AV_LOG_ERROR, "invalid id %d\n", id); yading@10: return -1; yading@10: } yading@10: av_dlog(s->avctx, "ID=%i, T=%i,%i,%i\n", id, s->t1, s->t2, s->t3); yading@10: yading@10: return 0; yading@10: } yading@10: yading@10: /** yading@10: * Get context-dependent Golomb code, decode it and update context yading@10: */ yading@10: static inline int ls_get_code_regular(GetBitContext *gb, JLSState *state, int Q){ yading@10: int k, ret; yading@10: yading@10: for(k = 0; (state->N[Q] << k) < state->A[Q]; k++); yading@10: yading@10: #ifdef JLS_BROKEN yading@10: if(!show_bits_long(gb, 32))return -1; yading@10: #endif yading@10: ret = get_ur_golomb_jpegls(gb, k, state->limit, state->qbpp); yading@10: yading@10: /* decode mapped error */ yading@10: if(ret & 1) yading@10: ret = -((ret + 1) >> 1); yading@10: else yading@10: ret >>= 1; yading@10: yading@10: /* for NEAR=0, k=0 and 2*B[Q] <= - N[Q] mapping is reversed */ yading@10: if(!state->near && !k && (2 * state->B[Q] <= -state->N[Q])) yading@10: ret = -(ret + 1); yading@10: yading@10: ret= ff_jpegls_update_state_regular(state, Q, ret); yading@10: yading@10: return ret; yading@10: } yading@10: yading@10: /** yading@10: * Get Golomb code, decode it and update state for run termination yading@10: */ yading@10: static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, int RItype, int limit_add){ yading@10: int k, ret, temp, map; yading@10: int Q = 365 + RItype; yading@10: yading@10: temp= state->A[Q]; yading@10: if(RItype) yading@10: temp += state->N[Q] >> 1; yading@10: yading@10: for(k = 0; (state->N[Q] << k) < temp; k++); yading@10: yading@10: #ifdef JLS_BROKEN yading@10: if(!show_bits_long(gb, 32))return -1; yading@10: #endif yading@10: ret = get_ur_golomb_jpegls(gb, k, state->limit - limit_add - 1, state->qbpp); yading@10: yading@10: /* decode mapped error */ yading@10: map = 0; yading@10: if(!k && (RItype || ret) && (2 * state->B[Q] < state->N[Q])) yading@10: map = 1; yading@10: ret += RItype + map; yading@10: yading@10: if(ret & 1){ yading@10: ret = map - ((ret + 1) >> 1); yading@10: state->B[Q]++; yading@10: } else { yading@10: ret = ret >> 1; yading@10: } yading@10: yading@10: /* update state */ yading@10: state->A[Q] += FFABS(ret) - RItype; yading@10: ret *= state->twonear; yading@10: ff_jpegls_downscale_state(state, Q); yading@10: yading@10: return ret; yading@10: } yading@10: yading@10: /** yading@10: * Decode one line of image yading@10: */ yading@10: static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, void *last, void *dst, int last2, int w, int stride, int comp, int bits){ yading@10: int i, x = 0; yading@10: int Ra, Rb, Rc, Rd; yading@10: int D0, D1, D2; yading@10: yading@10: while(x < w) { yading@10: int err, pred; yading@10: yading@10: /* compute gradients */ yading@10: Ra = x ? R(dst, x - stride) : R(last, x); yading@10: Rb = R(last, x); yading@10: Rc = x ? R(last, x - stride) : last2; yading@10: Rd = (x >= w - stride) ? R(last, x) : R(last, x + stride); yading@10: D0 = Rd - Rb; yading@10: D1 = Rb - Rc; yading@10: D2 = Rc - Ra; yading@10: /* run mode */ yading@10: if((FFABS(D0) <= state->near) && (FFABS(D1) <= state->near) && (FFABS(D2) <= state->near)) { yading@10: int r; yading@10: int RItype; yading@10: yading@10: /* decode full runs while available */ yading@10: while(get_bits1(&s->gb)) { yading@10: int r; yading@10: r = 1 << ff_log2_run[state->run_index[comp]]; yading@10: if(x + r * stride > w) { yading@10: r = (w - x) / stride; yading@10: } yading@10: for(i = 0; i < r; i++) { yading@10: W(dst, x, Ra); yading@10: x += stride; yading@10: } yading@10: /* if EOL reached, we stop decoding */ yading@10: if(r != (1 << ff_log2_run[state->run_index[comp]])) yading@10: return; yading@10: if(state->run_index[comp] < 31) yading@10: state->run_index[comp]++; yading@10: if(x + stride > w) yading@10: return; yading@10: } yading@10: /* decode aborted run */ yading@10: r = ff_log2_run[state->run_index[comp]]; yading@10: if(r) yading@10: r = get_bits_long(&s->gb, r); yading@10: if(x + r * stride > w) { yading@10: r = (w - x) / stride; yading@10: } yading@10: for(i = 0; i < r; i++) { yading@10: W(dst, x, Ra); yading@10: x += stride; yading@10: } yading@10: yading@10: /* decode run termination value */ yading@10: Rb = R(last, x); yading@10: RItype = (FFABS(Ra - Rb) <= state->near) ? 1 : 0; yading@10: err = ls_get_code_runterm(&s->gb, state, RItype, ff_log2_run[state->run_index[comp]]); yading@10: if(state->run_index[comp]) yading@10: state->run_index[comp]--; yading@10: yading@10: if(state->near && RItype){ yading@10: pred = Ra + err; yading@10: } else { yading@10: if(Rb < Ra) yading@10: pred = Rb - err; yading@10: else yading@10: pred = Rb + err; yading@10: } yading@10: } else { /* regular mode */ yading@10: int context, sign; yading@10: yading@10: context = ff_jpegls_quantize(state, D0) * 81 + ff_jpegls_quantize(state, D1) * 9 + ff_jpegls_quantize(state, D2); yading@10: pred = mid_pred(Ra, Ra + Rb - Rc, Rb); yading@10: yading@10: if(context < 0){ yading@10: context = -context; yading@10: sign = 1; yading@10: }else{ yading@10: sign = 0; yading@10: } yading@10: yading@10: if(sign){ yading@10: pred = av_clip(pred - state->C[context], 0, state->maxval); yading@10: err = -ls_get_code_regular(&s->gb, state, context); yading@10: } else { yading@10: pred = av_clip(pred + state->C[context], 0, state->maxval); yading@10: err = ls_get_code_regular(&s->gb, state, context); yading@10: } yading@10: yading@10: /* we have to do something more for near-lossless coding */ yading@10: pred += err; yading@10: } yading@10: if(state->near){ yading@10: if(pred < -state->near) yading@10: pred += state->range * state->twonear; yading@10: else if(pred > state->maxval + state->near) yading@10: pred -= state->range * state->twonear; yading@10: pred = av_clip(pred, 0, state->maxval); yading@10: } yading@10: yading@10: pred &= state->maxval; yading@10: W(dst, x, pred); yading@10: x += stride; yading@10: } yading@10: } yading@10: yading@10: int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transform, int ilv){ yading@10: int i, t = 0; yading@10: uint8_t *zero, *last, *cur; yading@10: JLSState *state; yading@10: int off = 0, stride = 1, width, shift; yading@10: yading@10: zero = av_mallocz(s->picture.linesize[0]); yading@10: last = zero; yading@10: cur = s->picture.data[0]; yading@10: yading@10: state = av_mallocz(sizeof(JLSState)); yading@10: /* initialize JPEG-LS state from JPEG parameters */ yading@10: state->near = near; yading@10: state->bpp = (s->bits < 2) ? 2 : s->bits; yading@10: state->maxval = s->maxval; yading@10: state->T1 = s->t1; yading@10: state->T2 = s->t2; yading@10: state->T3 = s->t3; yading@10: state->reset = s->reset; yading@10: ff_jpegls_reset_coding_parameters(state, 0); yading@10: ff_jpegls_init_state(state); yading@10: yading@10: if(s->bits <= 8) yading@10: shift = point_transform + (8 - s->bits); yading@10: else yading@10: shift = point_transform + (16 - s->bits); yading@10: yading@10: if (s->avctx->debug & FF_DEBUG_PICT_INFO) { yading@10: 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", yading@10: s->width, s->height, state->near, state->maxval, yading@10: state->T1, state->T2, state->T3, yading@10: state->reset, state->limit, state->qbpp, state->range); yading@10: av_log(s->avctx, AV_LOG_DEBUG, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n", yading@10: ilv, point_transform, s->bits, s->cur_scan); yading@10: } yading@10: if(ilv == 0) { /* separate planes */ yading@10: stride = (s->nb_components > 1) ? 3 : 1; yading@10: off = av_clip(s->cur_scan - 1, 0, stride - 1); yading@10: width = s->width * stride; yading@10: cur += off; yading@10: for(i = 0; i < s->height; i++) { yading@10: if(s->bits <= 8){ yading@10: ls_decode_line(state, s, last, cur, t, width, stride, off, 8); yading@10: t = last[0]; yading@10: }else{ yading@10: ls_decode_line(state, s, last, cur, t, width, stride, off, 16); yading@10: t = *((uint16_t*)last); yading@10: } yading@10: last = cur; yading@10: cur += s->picture.linesize[0]; yading@10: yading@10: if (s->restart_interval && !--s->restart_count) { yading@10: align_get_bits(&s->gb); yading@10: skip_bits(&s->gb, 16); /* skip RSTn */ yading@10: } yading@10: } yading@10: } else if(ilv == 1) { /* line interleaving */ yading@10: int j; yading@10: int Rc[3] = {0, 0, 0}; yading@10: stride = (s->nb_components > 1) ? 3 : 1; yading@10: memset(cur, 0, s->picture.linesize[0]); yading@10: width = s->width * stride; yading@10: for(i = 0; i < s->height; i++) { yading@10: for(j = 0; j < stride; j++) { yading@10: ls_decode_line(state, s, last + j, cur + j, Rc[j], width, stride, j, 8); yading@10: Rc[j] = last[j]; yading@10: yading@10: if (s->restart_interval && !--s->restart_count) { yading@10: align_get_bits(&s->gb); yading@10: skip_bits(&s->gb, 16); /* skip RSTn */ yading@10: } yading@10: } yading@10: last = cur; yading@10: cur += s->picture.linesize[0]; yading@10: } yading@10: } else if(ilv == 2) { /* sample interleaving */ yading@10: av_log(s->avctx, AV_LOG_ERROR, "Sample interleaved images are not supported.\n"); yading@10: av_free(state); yading@10: av_free(zero); yading@10: return -1; yading@10: } yading@10: yading@10: if(shift){ /* we need to do point transform or normalize samples */ yading@10: int x, w; yading@10: yading@10: w = s->width * s->nb_components; yading@10: yading@10: if(s->bits <= 8){ yading@10: uint8_t *src = s->picture.data[0]; yading@10: yading@10: for(i = 0; i < s->height; i++){ yading@10: for(x = off; x < w; x+= stride){ yading@10: src[x] <<= shift; yading@10: } yading@10: src += s->picture.linesize[0]; yading@10: } yading@10: }else{ yading@10: uint16_t *src = (uint16_t*) s->picture.data[0]; yading@10: yading@10: for(i = 0; i < s->height; i++){ yading@10: for(x = 0; x < w; x++){ yading@10: src[x] <<= shift; yading@10: } yading@10: src += s->picture.linesize[0]/2; yading@10: } yading@10: } yading@10: } yading@10: av_free(state); yading@10: av_free(zero); yading@10: yading@10: return 0; yading@10: } yading@10: yading@10: yading@10: AVCodec ff_jpegls_decoder = { yading@10: .name = "jpegls", yading@10: .type = AVMEDIA_TYPE_VIDEO, yading@10: .id = AV_CODEC_ID_JPEGLS, yading@10: .priv_data_size = sizeof(MJpegDecodeContext), yading@10: .init = ff_mjpeg_decode_init, yading@10: .close = ff_mjpeg_decode_end, yading@10: .decode = ff_mjpeg_decode_frame, yading@10: .capabilities = CODEC_CAP_DR1, yading@10: .long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"), yading@10: };