⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpeglsdec.c

📁 ffmpeg移植到symbian的全部源代码
💻 C
字号:
/* * JPEG-LS decoder * Copyright (c) 2003 Michael Niedermayer * Copyright (c) 2006 Konstantin Shishkov * * This file is part of FFmpeg. * * 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. * * 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 FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *//** * @file jpeglsdec.c * JPEG-LS decoder. */#include "avcodec.h"#include "bitstream.h"#include "golomb.h"#include "mjpeg.h"#include "mjpegdec.h"#include "jpegls.h"#include "jpeglsdec.h"/** Uncomment this to significantly speed up decoding of broken JPEG-LS* (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, FFmpeg Golomb decoder is painfully slow* on this errors.*///#define JLS_BROKEN/** * Decode LSE block with initialization parameters */int ff_jpegls_decode_lse(MJpegDecodeContext *s){    int len, id;    /* XXX: verify len field validity */    len = get_bits(&s->gb, 16);    id = get_bits(&s->gb, 8);    switch(id){    case 1:        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);//        ff_jpegls_reset_coding_parameters(s, 0);        //FIXME quant table?        break;    case 2:    case 3:        av_log(s->avctx, AV_LOG_ERROR, "palette not supported\n");        return -1;    case 4:        av_log(s->avctx, AV_LOG_ERROR, "oversize image not supported\n");        return -1;    default:        av_log(s->avctx, AV_LOG_ERROR, "invalid id %d\n", id);        return -1;    }//    av_log(s->avctx, AV_LOG_DEBUG, "ID=%i, T=%i,%i,%i\n", id, s->t1, s->t2, s->t3);    return 0;}/** * Get context-dependent Golomb code, decode it and update context */static inline int ls_get_code_regular(GetBitContext *gb, JLSState *state, int Q){    int k, ret;    for(k = 0; (state->N[Q] << k) < state->A[Q]; k++);#ifdef JLS_BROKEN    if(!show_bits_long(gb, 32))return -1;#endif    ret = get_ur_golomb_jpegls(gb, k, state->limit, state->qbpp);    /* decode mapped error */    if(ret & 1)        ret = -((ret + 1) >> 1);    else        ret >>= 1;    /* for NEAR=0, k=0 and 2*B[Q] <= - N[Q] mapping is reversed */    if(!state->near && !k && (2 * state->B[Q] <= -state->N[Q]))        ret = -(ret + 1);    ret= ff_jpegls_update_state_regular(state, Q, ret);    return ret;}/** * Get Golomb code, decode it and update state for run termination */static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, int RItype, int limit_add){    int k, ret, temp, map;    int Q = 365 + RItype;    temp=  state->A[Q];    if(RItype)        temp += state->N[Q] >> 1;    for(k = 0; (state->N[Q] << k) < temp; k++);#ifdef JLS_BROKEN    if(!show_bits_long(gb, 32))return -1;#endif    ret = get_ur_golomb_jpegls(gb, k, state->limit - limit_add - 1, state->qbpp);    /* decode mapped error */    map = 0;    if(!k && (RItype || ret) && (2 * state->B[Q] < state->N[Q]))        map = 1;    ret += RItype + map;    if(ret & 1){        ret = map - ((ret + 1) >> 1);        state->B[Q]++;    } else {        ret = ret >> 1;    }    /* update state */    state->A[Q] += FFABS(ret) - RItype;    ret *= state->twonear;    ff_jpegls_downscale_state(state, Q);    return ret;}/** * Decode one line of image */static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, void *last, void *dst, int last2, int w, int stride, int comp, int bits){    int i, x = 0;    int Ra, Rb, Rc, Rd;    int D0, D1, D2;    while(x < w) {        int err, pred;        /* compute gradients */        Ra = x ? R(dst, x - stride) : R(last, x);        Rb = R(last, x);        Rc = x ? R(last, x - stride) : last2;        Rd = (x >= w - stride) ? R(last, x) : R(last, x + stride);        D0 = Rd - Rb;        D1 = Rb - Rc;        D2 = Rc - Ra;        /* run mode */        if((FFABS(D0) <= state->near) && (FFABS(D1) <= state->near) && (FFABS(D2) <= state->near)) {            int r;            int RItype;            /* decode full runs while available */            while(get_bits1(&s->gb)) {                int r;                r = 1 << ff_log2_run[state->run_index[comp]];                if(x + r * stride > w) {                    r = (w - x) / stride;                }                for(i = 0; i < r; i++) {                    W(dst, x, Ra);                    x += stride;                }                /* if EOL reached, we stop decoding */                if(r != (1 << ff_log2_run[state->run_index[comp]]))                    return;                if(state->run_index[comp] < 31)                    state->run_index[comp]++;                if(x + stride > w)                    return;            }            /* decode aborted run */            r = ff_log2_run[state->run_index[comp]];            if(r)                r = get_bits_long(&s->gb, r);            for(i = 0; i < r; i++) {                W(dst, x, Ra);                x += stride;            }            /* decode run termination value */            Rb = R(last, x);            RItype = (FFABS(Ra - Rb) <= state->near) ? 1 : 0;            err = ls_get_code_runterm(&s->gb, state, RItype, ff_log2_run[state->run_index[comp]]);            if(state->run_index[comp])                state->run_index[comp]--;            if(state->near && RItype){                pred = Ra + err;            } else {                if(Rb < Ra)                    pred = Rb - err;                else                    pred = Rb + err;            }        } else { /* regular mode */            int context, sign;            context = ff_jpegls_quantize(state, D0) * 81 + ff_jpegls_quantize(state, D1) * 9 + ff_jpegls_quantize(state, D2);            pred = mid_pred(Ra, Ra + Rb - Rc, Rb);            if(context < 0){                context = -context;                sign = 1;            }else{                sign = 0;            }            if(sign){                pred = av_clip(pred - state->C[context], 0, state->maxval);                err = -ls_get_code_regular(&s->gb, state, context);            } else {                pred = av_clip(pred + state->C[context], 0, state->maxval);                err = ls_get_code_regular(&s->gb, state, context);            }            /* we have to do something more for near-lossless coding */            pred += err;        }        if(state->near){            if(pred < -state->near)                pred += state->range * state->twonear;            else if(pred > state->maxval + state->near)                pred -= state->range * state->twonear;            pred = av_clip(pred, 0, state->maxval);        }        pred &= state->maxval;        W(dst, x, pred);        x += stride;    }}int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transform, int ilv){    int i, t = 0;    uint8_t *zero, *last, *cur;    JLSState *state;    int off = 0, stride = 1, width, shift;    zero = av_mallocz(s->picture.linesize[0]);    last = zero;    cur = s->picture.data[0];    state = av_mallocz(sizeof(JLSState));    /* initialize JPEG-LS state from JPEG parameters */    state->near = near;    state->bpp = (s->bits < 2) ? 2 : s->bits;    state->maxval = s->maxval;    state->T1 = s->t1;    state->T2 = s->t2;    state->T3 = s->t3;    state->reset = s->reset;    ff_jpegls_reset_coding_parameters(state, 0);    ff_jpegls_init_state(state);    if(s->bits <= 8)        shift = point_transform + (8 - s->bits);    else        shift = point_transform + (16 - s->bits);//    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 */        off = s->cur_scan - 1;        stride = (s->nb_components > 1) ? 3 : 1;        width = s->width * stride;        cur += off;        for(i = 0; i < s->height; i++) {            if(s->bits <= 8){                ls_decode_line(state, s, last, cur, t, width, stride, off,  8);                t = last[0];            }else{                ls_decode_line(state, s, last, cur, t, width, stride, off, 16);                t = *((uint16_t*)last);            }            last = cur;            cur += s->picture.linesize[0];            if (s->restart_interval && !--s->restart_count) {                align_get_bits(&s->gb);                skip_bits(&s->gb, 16); /* skip RSTn */            }        }    } else if(ilv == 1) { /* line interleaving */        int j;        int Rc[3] = {0, 0, 0};        memset(cur, 0, s->picture.linesize[0]);        width = s->width * 3;        for(i = 0; i < s->height; i++) {            for(j = 0; j < 3; j++) {                ls_decode_line(state, s, last + j, cur + j, Rc[j], width, 3, j, 8);                Rc[j] = last[j];                if (s->restart_interval && !--s->restart_count) {                    align_get_bits(&s->gb);                    skip_bits(&s->gb, 16); /* skip RSTn */                }            }            last = cur;            cur += s->picture.linesize[0];        }    } else if(ilv == 2) { /* sample interleaving */        av_log(s->avctx, AV_LOG_ERROR, "Sample interleaved images are not supported.\n");        av_free(state);        av_free(zero);        return -1;    }    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.data[0];            for(i = 0; i < s->height; i++){                for(x = off; x < w; x+= stride){                    src[x] <<= shift;                }                src += s->picture.linesize[0];            }        }else{            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.linesize[0]/2;            }        }    }    av_free(state);    av_free(zero);    return 0;}AVCodec jpegls_decoder = {    "jpegls",    CODEC_TYPE_VIDEO,    CODEC_ID_JPEGLS,    sizeof(MJpegDecodeContext),    ff_mjpeg_decode_init,    NULL,    ff_mjpeg_decode_end,    ff_mjpeg_decode_frame,    CODEC_CAP_DR1,#ifdef __CW32__    0,    0,    0,    0,    NULL_IF_CONFIG_SMALL("JPEG-LS"),#else    .long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"),#endif};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -