xref: /third_party/ffmpeg/libavcodec/snowdec.c (revision cabdff1a)
1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * This file is part of FFmpeg.
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
10cabdff1aSopenharmony_ci *
11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14cabdff1aSopenharmony_ci * Lesser General Public License for more details.
15cabdff1aSopenharmony_ci *
16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19cabdff1aSopenharmony_ci */
20cabdff1aSopenharmony_ci
21cabdff1aSopenharmony_ci#include "libavutil/intmath.h"
22cabdff1aSopenharmony_ci#include "libavutil/log.h"
23cabdff1aSopenharmony_ci#include "libavutil/opt.h"
24cabdff1aSopenharmony_ci#include "avcodec.h"
25cabdff1aSopenharmony_ci#include "codec_internal.h"
26cabdff1aSopenharmony_ci#include "snow_dwt.h"
27cabdff1aSopenharmony_ci#include "snow.h"
28cabdff1aSopenharmony_ci
29cabdff1aSopenharmony_ci#include "rangecoder.h"
30cabdff1aSopenharmony_ci#include "mathops.h"
31cabdff1aSopenharmony_ci
32cabdff1aSopenharmony_cistatic av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer * sb, IDWTELEM * old_buffer, int plane_index, int add, int mb_y){
33cabdff1aSopenharmony_ci    Plane *p= &s->plane[plane_index];
34cabdff1aSopenharmony_ci    const int mb_w= s->b_width  << s->block_max_depth;
35cabdff1aSopenharmony_ci    const int mb_h= s->b_height << s->block_max_depth;
36cabdff1aSopenharmony_ci    int x, y, mb_x;
37cabdff1aSopenharmony_ci    int block_size = MB_SIZE >> s->block_max_depth;
38cabdff1aSopenharmony_ci    int block_w    = plane_index ? block_size>>s->chroma_h_shift : block_size;
39cabdff1aSopenharmony_ci    int block_h    = plane_index ? block_size>>s->chroma_v_shift : block_size;
40cabdff1aSopenharmony_ci    const uint8_t *obmc  = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth];
41cabdff1aSopenharmony_ci    int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
42cabdff1aSopenharmony_ci    int ref_stride= s->current_picture->linesize[plane_index];
43cabdff1aSopenharmony_ci    uint8_t *dst8= s->current_picture->data[plane_index];
44cabdff1aSopenharmony_ci    int w= p->width;
45cabdff1aSopenharmony_ci    int h= p->height;
46cabdff1aSopenharmony_ci
47cabdff1aSopenharmony_ci    if(s->keyframe || (s->avctx->debug&512)){
48cabdff1aSopenharmony_ci        if(mb_y==mb_h)
49cabdff1aSopenharmony_ci            return;
50cabdff1aSopenharmony_ci
51cabdff1aSopenharmony_ci        if(add){
52cabdff1aSopenharmony_ci            for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
53cabdff1aSopenharmony_ci//                DWTELEM * line = slice_buffer_get_line(sb, y);
54cabdff1aSopenharmony_ci                IDWTELEM * line = sb->line[y];
55cabdff1aSopenharmony_ci                for(x=0; x<w; x++){
56cabdff1aSopenharmony_ci//                    int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
57cabdff1aSopenharmony_ci                    int v= line[x] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
58cabdff1aSopenharmony_ci                    v >>= FRAC_BITS;
59cabdff1aSopenharmony_ci                    if(v&(~255)) v= ~(v>>31);
60cabdff1aSopenharmony_ci                    dst8[x + y*ref_stride]= v;
61cabdff1aSopenharmony_ci                }
62cabdff1aSopenharmony_ci            }
63cabdff1aSopenharmony_ci        }else{
64cabdff1aSopenharmony_ci            for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
65cabdff1aSopenharmony_ci//                DWTELEM * line = slice_buffer_get_line(sb, y);
66cabdff1aSopenharmony_ci                IDWTELEM * line = sb->line[y];
67cabdff1aSopenharmony_ci                for(x=0; x<w; x++){
68cabdff1aSopenharmony_ci                    line[x] -= 128 << FRAC_BITS;
69cabdff1aSopenharmony_ci//                    buf[x + y*w]-= 128<<FRAC_BITS;
70cabdff1aSopenharmony_ci                }
71cabdff1aSopenharmony_ci            }
72cabdff1aSopenharmony_ci        }
73cabdff1aSopenharmony_ci
74cabdff1aSopenharmony_ci        return;
75cabdff1aSopenharmony_ci    }
76cabdff1aSopenharmony_ci
77cabdff1aSopenharmony_ci    for(mb_x=0; mb_x<=mb_w; mb_x++){
78cabdff1aSopenharmony_ci        add_yblock(s, 1, sb, old_buffer, dst8, obmc,
79cabdff1aSopenharmony_ci                   block_w*mb_x - block_w/2,
80cabdff1aSopenharmony_ci                   block_h*mb_y - block_h/2,
81cabdff1aSopenharmony_ci                   block_w, block_h,
82cabdff1aSopenharmony_ci                   w, h,
83cabdff1aSopenharmony_ci                   w, ref_stride, obmc_stride,
84cabdff1aSopenharmony_ci                   mb_x - 1, mb_y - 1,
85cabdff1aSopenharmony_ci                   add, 0, plane_index);
86cabdff1aSopenharmony_ci    }
87cabdff1aSopenharmony_ci
88cabdff1aSopenharmony_ci    if(s->avmv && mb_y < mb_h && plane_index == 0)
89cabdff1aSopenharmony_ci        for(mb_x=0; mb_x<mb_w; mb_x++){
90cabdff1aSopenharmony_ci            AVMotionVector *avmv = s->avmv + s->avmv_index;
91cabdff1aSopenharmony_ci            const int b_width = s->b_width  << s->block_max_depth;
92cabdff1aSopenharmony_ci            const int b_stride= b_width;
93cabdff1aSopenharmony_ci            BlockNode *bn= &s->block[mb_x + mb_y*b_stride];
94cabdff1aSopenharmony_ci
95cabdff1aSopenharmony_ci            if (bn->type)
96cabdff1aSopenharmony_ci                continue;
97cabdff1aSopenharmony_ci
98cabdff1aSopenharmony_ci            s->avmv_index++;
99cabdff1aSopenharmony_ci
100cabdff1aSopenharmony_ci            avmv->w = block_w;
101cabdff1aSopenharmony_ci            avmv->h = block_h;
102cabdff1aSopenharmony_ci            avmv->dst_x = block_w*mb_x - block_w/2;
103cabdff1aSopenharmony_ci            avmv->dst_y = block_h*mb_y - block_h/2;
104cabdff1aSopenharmony_ci            avmv->motion_scale = 8;
105cabdff1aSopenharmony_ci            avmv->motion_x = bn->mx * s->mv_scale;
106cabdff1aSopenharmony_ci            avmv->motion_y = bn->my * s->mv_scale;
107cabdff1aSopenharmony_ci            avmv->src_x = avmv->dst_x + avmv->motion_x / 8;
108cabdff1aSopenharmony_ci            avmv->src_y = avmv->dst_y + avmv->motion_y / 8;
109cabdff1aSopenharmony_ci            avmv->source= -1 - bn->ref;
110cabdff1aSopenharmony_ci            avmv->flags = 0;
111cabdff1aSopenharmony_ci        }
112cabdff1aSopenharmony_ci}
113cabdff1aSopenharmony_ci
114cabdff1aSopenharmony_cistatic inline void decode_subband_slice_buffered(SnowContext *s, SubBand *b, slice_buffer * sb, int start_y, int h, int save_state[1]){
115cabdff1aSopenharmony_ci    const int w= b->width;
116cabdff1aSopenharmony_ci    int y;
117cabdff1aSopenharmony_ci    const int qlog= av_clip(s->qlog + (int64_t)b->qlog, 0, QROOT*16);
118cabdff1aSopenharmony_ci    int qmul= ff_qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
119cabdff1aSopenharmony_ci    int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
120cabdff1aSopenharmony_ci    int new_index = 0;
121cabdff1aSopenharmony_ci
122cabdff1aSopenharmony_ci    if(b->ibuf == s->spatial_idwt_buffer || s->qlog == LOSSLESS_QLOG){
123cabdff1aSopenharmony_ci        qadd= 0;
124cabdff1aSopenharmony_ci        qmul= 1<<QEXPSHIFT;
125cabdff1aSopenharmony_ci    }
126cabdff1aSopenharmony_ci
127cabdff1aSopenharmony_ci    /* If we are on the second or later slice, restore our index. */
128cabdff1aSopenharmony_ci    if (start_y != 0)
129cabdff1aSopenharmony_ci        new_index = save_state[0];
130cabdff1aSopenharmony_ci
131cabdff1aSopenharmony_ci
132cabdff1aSopenharmony_ci    for(y=start_y; y<h; y++){
133cabdff1aSopenharmony_ci        int x = 0;
134cabdff1aSopenharmony_ci        int v;
135cabdff1aSopenharmony_ci        IDWTELEM * line = slice_buffer_get_line(sb, y * b->stride_line + b->buf_y_offset) + b->buf_x_offset;
136cabdff1aSopenharmony_ci        memset(line, 0, b->width*sizeof(IDWTELEM));
137cabdff1aSopenharmony_ci        v = b->x_coeff[new_index].coeff;
138cabdff1aSopenharmony_ci        x = b->x_coeff[new_index++].x;
139cabdff1aSopenharmony_ci        while(x < w){
140cabdff1aSopenharmony_ci            register int t= (int)( (v>>1)*(unsigned)qmul + qadd)>>QEXPSHIFT;
141cabdff1aSopenharmony_ci            register int u= -(v&1);
142cabdff1aSopenharmony_ci            line[x] = (t^u) - u;
143cabdff1aSopenharmony_ci
144cabdff1aSopenharmony_ci            v = b->x_coeff[new_index].coeff;
145cabdff1aSopenharmony_ci            x = b->x_coeff[new_index++].x;
146cabdff1aSopenharmony_ci        }
147cabdff1aSopenharmony_ci    }
148cabdff1aSopenharmony_ci
149cabdff1aSopenharmony_ci    /* Save our variables for the next slice. */
150cabdff1aSopenharmony_ci    save_state[0] = new_index;
151cabdff1aSopenharmony_ci
152cabdff1aSopenharmony_ci    return;
153cabdff1aSopenharmony_ci}
154cabdff1aSopenharmony_ci
155cabdff1aSopenharmony_cistatic int decode_q_branch(SnowContext *s, int level, int x, int y){
156cabdff1aSopenharmony_ci    const int w= s->b_width << s->block_max_depth;
157cabdff1aSopenharmony_ci    const int rem_depth= s->block_max_depth - level;
158cabdff1aSopenharmony_ci    const int index= (x + y*w) << rem_depth;
159cabdff1aSopenharmony_ci    int trx= (x+1)<<rem_depth;
160cabdff1aSopenharmony_ci    const BlockNode *left  = x ? &s->block[index-1] : &null_block;
161cabdff1aSopenharmony_ci    const BlockNode *top   = y ? &s->block[index-w] : &null_block;
162cabdff1aSopenharmony_ci    const BlockNode *tl    = y && x ? &s->block[index-w-1] : left;
163cabdff1aSopenharmony_ci    const BlockNode *tr    = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
164cabdff1aSopenharmony_ci    int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
165cabdff1aSopenharmony_ci    int res;
166cabdff1aSopenharmony_ci
167cabdff1aSopenharmony_ci    if(s->keyframe){
168cabdff1aSopenharmony_ci        set_blocks(s, level, x, y, null_block.color[0], null_block.color[1], null_block.color[2], null_block.mx, null_block.my, null_block.ref, BLOCK_INTRA);
169cabdff1aSopenharmony_ci        return 0;
170cabdff1aSopenharmony_ci    }
171cabdff1aSopenharmony_ci
172cabdff1aSopenharmony_ci    if(level==s->block_max_depth || get_rac(&s->c, &s->block_state[4 + s_context])){
173cabdff1aSopenharmony_ci        int type, mx, my;
174cabdff1aSopenharmony_ci        int l = left->color[0];
175cabdff1aSopenharmony_ci        int cb= left->color[1];
176cabdff1aSopenharmony_ci        int cr= left->color[2];
177cabdff1aSopenharmony_ci        unsigned ref = 0;
178cabdff1aSopenharmony_ci        int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
179cabdff1aSopenharmony_ci        int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 0*av_log2(2*FFABS(tr->mx - top->mx));
180cabdff1aSopenharmony_ci        int my_context= av_log2(2*FFABS(left->my - top->my)) + 0*av_log2(2*FFABS(tr->my - top->my));
181cabdff1aSopenharmony_ci
182cabdff1aSopenharmony_ci        type= get_rac(&s->c, &s->block_state[1 + left->type + top->type]) ? BLOCK_INTRA : 0;
183cabdff1aSopenharmony_ci        if(type){
184cabdff1aSopenharmony_ci            int ld, cbd, crd;
185cabdff1aSopenharmony_ci            pred_mv(s, &mx, &my, 0, left, top, tr);
186cabdff1aSopenharmony_ci            ld = get_symbol(&s->c, &s->block_state[32], 1);
187cabdff1aSopenharmony_ci            if (ld < -255 || ld > 255) {
188cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
189cabdff1aSopenharmony_ci            }
190cabdff1aSopenharmony_ci            l += ld;
191cabdff1aSopenharmony_ci            if (s->nb_planes > 2) {
192cabdff1aSopenharmony_ci                cbd = get_symbol(&s->c, &s->block_state[64], 1);
193cabdff1aSopenharmony_ci                crd = get_symbol(&s->c, &s->block_state[96], 1);
194cabdff1aSopenharmony_ci                if (cbd < -255 || cbd > 255 || crd < -255 || crd > 255) {
195cabdff1aSopenharmony_ci                    return AVERROR_INVALIDDATA;
196cabdff1aSopenharmony_ci                }
197cabdff1aSopenharmony_ci                cb += cbd;
198cabdff1aSopenharmony_ci                cr += crd;
199cabdff1aSopenharmony_ci            }
200cabdff1aSopenharmony_ci        }else{
201cabdff1aSopenharmony_ci            if(s->ref_frames > 1)
202cabdff1aSopenharmony_ci                ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0);
203cabdff1aSopenharmony_ci            if (ref >= s->ref_frames) {
204cabdff1aSopenharmony_ci                av_log(s->avctx, AV_LOG_ERROR, "Invalid ref\n");
205cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
206cabdff1aSopenharmony_ci            }
207cabdff1aSopenharmony_ci            pred_mv(s, &mx, &my, ref, left, top, tr);
208cabdff1aSopenharmony_ci            mx+= (unsigned)get_symbol(&s->c, &s->block_state[128 + 32*(mx_context + 16*!!ref)], 1);
209cabdff1aSopenharmony_ci            my+= (unsigned)get_symbol(&s->c, &s->block_state[128 + 32*(my_context + 16*!!ref)], 1);
210cabdff1aSopenharmony_ci        }
211cabdff1aSopenharmony_ci        set_blocks(s, level, x, y, l, cb, cr, mx, my, ref, type);
212cabdff1aSopenharmony_ci    }else{
213cabdff1aSopenharmony_ci        if ((res = decode_q_branch(s, level+1, 2*x+0, 2*y+0)) < 0 ||
214cabdff1aSopenharmony_ci            (res = decode_q_branch(s, level+1, 2*x+1, 2*y+0)) < 0 ||
215cabdff1aSopenharmony_ci            (res = decode_q_branch(s, level+1, 2*x+0, 2*y+1)) < 0 ||
216cabdff1aSopenharmony_ci            (res = decode_q_branch(s, level+1, 2*x+1, 2*y+1)) < 0)
217cabdff1aSopenharmony_ci            return res;
218cabdff1aSopenharmony_ci    }
219cabdff1aSopenharmony_ci    return 0;
220cabdff1aSopenharmony_ci}
221cabdff1aSopenharmony_ci
222cabdff1aSopenharmony_cistatic void dequantize_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int start_y, int end_y){
223cabdff1aSopenharmony_ci    const int w= b->width;
224cabdff1aSopenharmony_ci    const int qlog= av_clip(s->qlog + (int64_t)b->qlog, 0, QROOT*16);
225cabdff1aSopenharmony_ci    const int qmul= ff_qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
226cabdff1aSopenharmony_ci    const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
227cabdff1aSopenharmony_ci    int x,y;
228cabdff1aSopenharmony_ci
229cabdff1aSopenharmony_ci    if(s->qlog == LOSSLESS_QLOG) return;
230cabdff1aSopenharmony_ci
231cabdff1aSopenharmony_ci    for(y=start_y; y<end_y; y++){
232cabdff1aSopenharmony_ci//        DWTELEM * line = slice_buffer_get_line_from_address(sb, src + (y * stride));
233cabdff1aSopenharmony_ci        IDWTELEM * line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
234cabdff1aSopenharmony_ci        for(x=0; x<w; x++){
235cabdff1aSopenharmony_ci            int i= line[x];
236cabdff1aSopenharmony_ci            if(i<0){
237cabdff1aSopenharmony_ci                line[x]= -((-i*(unsigned)qmul + qadd)>>(QEXPSHIFT)); //FIXME try different bias
238cabdff1aSopenharmony_ci            }else if(i>0){
239cabdff1aSopenharmony_ci                line[x]=  (( i*(unsigned)qmul + qadd)>>(QEXPSHIFT));
240cabdff1aSopenharmony_ci            }
241cabdff1aSopenharmony_ci        }
242cabdff1aSopenharmony_ci    }
243cabdff1aSopenharmony_ci}
244cabdff1aSopenharmony_ci
245cabdff1aSopenharmony_cistatic void correlate_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median, int start_y, int end_y){
246cabdff1aSopenharmony_ci    const int w= b->width;
247cabdff1aSopenharmony_ci    int x,y;
248cabdff1aSopenharmony_ci
249cabdff1aSopenharmony_ci    IDWTELEM * line=0; // silence silly "could be used without having been initialized" warning
250cabdff1aSopenharmony_ci    IDWTELEM * prev;
251cabdff1aSopenharmony_ci
252cabdff1aSopenharmony_ci    if (start_y != 0)
253cabdff1aSopenharmony_ci        line = slice_buffer_get_line(sb, ((start_y - 1) * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
254cabdff1aSopenharmony_ci
255cabdff1aSopenharmony_ci    for(y=start_y; y<end_y; y++){
256cabdff1aSopenharmony_ci        prev = line;
257cabdff1aSopenharmony_ci//        line = slice_buffer_get_line_from_address(sb, src + (y * stride));
258cabdff1aSopenharmony_ci        line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
259cabdff1aSopenharmony_ci        for(x=0; x<w; x++){
260cabdff1aSopenharmony_ci            if(x){
261cabdff1aSopenharmony_ci                if(use_median){
262cabdff1aSopenharmony_ci                    if(y && x+1<w) line[x] += mid_pred(line[x - 1], prev[x], prev[x + 1]);
263cabdff1aSopenharmony_ci                    else  line[x] += line[x - 1];
264cabdff1aSopenharmony_ci                }else{
265cabdff1aSopenharmony_ci                    if(y) line[x] += mid_pred(line[x - 1], prev[x], line[x - 1] + prev[x] - prev[x - 1]);
266cabdff1aSopenharmony_ci                    else  line[x] += line[x - 1];
267cabdff1aSopenharmony_ci                }
268cabdff1aSopenharmony_ci            }else{
269cabdff1aSopenharmony_ci                if(y) line[x] += prev[x];
270cabdff1aSopenharmony_ci            }
271cabdff1aSopenharmony_ci        }
272cabdff1aSopenharmony_ci    }
273cabdff1aSopenharmony_ci}
274cabdff1aSopenharmony_ci
275cabdff1aSopenharmony_cistatic void decode_qlogs(SnowContext *s){
276cabdff1aSopenharmony_ci    int plane_index, level, orientation;
277cabdff1aSopenharmony_ci
278cabdff1aSopenharmony_ci    for(plane_index=0; plane_index < s->nb_planes; plane_index++){
279cabdff1aSopenharmony_ci        for(level=0; level<s->spatial_decomposition_count; level++){
280cabdff1aSopenharmony_ci            for(orientation=level ? 1:0; orientation<4; orientation++){
281cabdff1aSopenharmony_ci                int q;
282cabdff1aSopenharmony_ci                if     (plane_index==2) q= s->plane[1].band[level][orientation].qlog;
283cabdff1aSopenharmony_ci                else if(orientation==2) q= s->plane[plane_index].band[level][1].qlog;
284cabdff1aSopenharmony_ci                else                    q= get_symbol(&s->c, s->header_state, 1);
285cabdff1aSopenharmony_ci                s->plane[plane_index].band[level][orientation].qlog= q;
286cabdff1aSopenharmony_ci            }
287cabdff1aSopenharmony_ci        }
288cabdff1aSopenharmony_ci    }
289cabdff1aSopenharmony_ci}
290cabdff1aSopenharmony_ci
291cabdff1aSopenharmony_ci#define GET_S(dst, check) \
292cabdff1aSopenharmony_ci    tmp= get_symbol(&s->c, s->header_state, 0);\
293cabdff1aSopenharmony_ci    if(!(check)){\
294cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "Error " #dst " is %d\n", tmp);\
295cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;\
296cabdff1aSopenharmony_ci    }\
297cabdff1aSopenharmony_ci    dst= tmp;
298cabdff1aSopenharmony_ci
299cabdff1aSopenharmony_cistatic int decode_header(SnowContext *s){
300cabdff1aSopenharmony_ci    int plane_index, tmp;
301cabdff1aSopenharmony_ci    uint8_t kstate[32];
302cabdff1aSopenharmony_ci
303cabdff1aSopenharmony_ci    memset(kstate, MID_STATE, sizeof(kstate));
304cabdff1aSopenharmony_ci
305cabdff1aSopenharmony_ci    s->keyframe= get_rac(&s->c, kstate);
306cabdff1aSopenharmony_ci    if(s->keyframe || s->always_reset){
307cabdff1aSopenharmony_ci        ff_snow_reset_contexts(s);
308cabdff1aSopenharmony_ci        s->spatial_decomposition_type=
309cabdff1aSopenharmony_ci        s->qlog=
310cabdff1aSopenharmony_ci        s->qbias=
311cabdff1aSopenharmony_ci        s->mv_scale=
312cabdff1aSopenharmony_ci        s->block_max_depth= 0;
313cabdff1aSopenharmony_ci    }
314cabdff1aSopenharmony_ci    if(s->keyframe){
315cabdff1aSopenharmony_ci        GET_S(s->version, tmp <= 0U)
316cabdff1aSopenharmony_ci        s->always_reset= get_rac(&s->c, s->header_state);
317cabdff1aSopenharmony_ci        s->temporal_decomposition_type= get_symbol(&s->c, s->header_state, 0);
318cabdff1aSopenharmony_ci        s->temporal_decomposition_count= get_symbol(&s->c, s->header_state, 0);
319cabdff1aSopenharmony_ci        GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS)
320cabdff1aSopenharmony_ci        s->colorspace_type= get_symbol(&s->c, s->header_state, 0);
321cabdff1aSopenharmony_ci        if (s->colorspace_type == 1) {
322cabdff1aSopenharmony_ci            s->avctx->pix_fmt= AV_PIX_FMT_GRAY8;
323cabdff1aSopenharmony_ci            s->nb_planes = 1;
324cabdff1aSopenharmony_ci        } else if(s->colorspace_type == 0) {
325cabdff1aSopenharmony_ci            s->chroma_h_shift= get_symbol(&s->c, s->header_state, 0);
326cabdff1aSopenharmony_ci            s->chroma_v_shift= get_symbol(&s->c, s->header_state, 0);
327cabdff1aSopenharmony_ci
328cabdff1aSopenharmony_ci            if(s->chroma_h_shift == 1 && s->chroma_v_shift==1){
329cabdff1aSopenharmony_ci                s->avctx->pix_fmt= AV_PIX_FMT_YUV420P;
330cabdff1aSopenharmony_ci            }else if(s->chroma_h_shift == 0 && s->chroma_v_shift==0){
331cabdff1aSopenharmony_ci                s->avctx->pix_fmt= AV_PIX_FMT_YUV444P;
332cabdff1aSopenharmony_ci            }else if(s->chroma_h_shift == 2 && s->chroma_v_shift==2){
333cabdff1aSopenharmony_ci                s->avctx->pix_fmt= AV_PIX_FMT_YUV410P;
334cabdff1aSopenharmony_ci            } else {
335cabdff1aSopenharmony_ci                av_log(s, AV_LOG_ERROR, "unsupported color subsample mode %d %d\n", s->chroma_h_shift, s->chroma_v_shift);
336cabdff1aSopenharmony_ci                s->chroma_h_shift = s->chroma_v_shift = 1;
337cabdff1aSopenharmony_ci                s->avctx->pix_fmt= AV_PIX_FMT_YUV420P;
338cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
339cabdff1aSopenharmony_ci            }
340cabdff1aSopenharmony_ci            s->nb_planes = 3;
341cabdff1aSopenharmony_ci        } else {
342cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "unsupported color space\n");
343cabdff1aSopenharmony_ci            s->chroma_h_shift = s->chroma_v_shift = 1;
344cabdff1aSopenharmony_ci            s->avctx->pix_fmt= AV_PIX_FMT_YUV420P;
345cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
346cabdff1aSopenharmony_ci        }
347cabdff1aSopenharmony_ci
348cabdff1aSopenharmony_ci
349cabdff1aSopenharmony_ci        s->spatial_scalability= get_rac(&s->c, s->header_state);
350cabdff1aSopenharmony_ci//        s->rate_scalability= get_rac(&s->c, s->header_state);
351cabdff1aSopenharmony_ci        GET_S(s->max_ref_frames, tmp < (unsigned)MAX_REF_FRAMES)
352cabdff1aSopenharmony_ci        s->max_ref_frames++;
353cabdff1aSopenharmony_ci
354cabdff1aSopenharmony_ci        decode_qlogs(s);
355cabdff1aSopenharmony_ci    }
356cabdff1aSopenharmony_ci
357cabdff1aSopenharmony_ci    if(!s->keyframe){
358cabdff1aSopenharmony_ci        if(get_rac(&s->c, s->header_state)){
359cabdff1aSopenharmony_ci            for(plane_index=0; plane_index<FFMIN(s->nb_planes, 2); plane_index++){
360cabdff1aSopenharmony_ci                int htaps, i, sum=0;
361cabdff1aSopenharmony_ci                Plane *p= &s->plane[plane_index];
362cabdff1aSopenharmony_ci                p->diag_mc= get_rac(&s->c, s->header_state);
363cabdff1aSopenharmony_ci                htaps= get_symbol(&s->c, s->header_state, 0);
364cabdff1aSopenharmony_ci                if((unsigned)htaps >= HTAPS_MAX/2 - 1)
365cabdff1aSopenharmony_ci                    return AVERROR_INVALIDDATA;
366cabdff1aSopenharmony_ci                htaps = htaps*2 + 2;
367cabdff1aSopenharmony_ci                p->htaps= htaps;
368cabdff1aSopenharmony_ci                for(i= htaps/2; i; i--){
369cabdff1aSopenharmony_ci                    unsigned hcoeff = get_symbol(&s->c, s->header_state, 0);
370cabdff1aSopenharmony_ci                    if (hcoeff > 127)
371cabdff1aSopenharmony_ci                        return AVERROR_INVALIDDATA;
372cabdff1aSopenharmony_ci                    p->hcoeff[i]= hcoeff * (1-2*(i&1));
373cabdff1aSopenharmony_ci                    sum += p->hcoeff[i];
374cabdff1aSopenharmony_ci                }
375cabdff1aSopenharmony_ci                p->hcoeff[0]= 32-sum;
376cabdff1aSopenharmony_ci            }
377cabdff1aSopenharmony_ci            s->plane[2].diag_mc= s->plane[1].diag_mc;
378cabdff1aSopenharmony_ci            s->plane[2].htaps  = s->plane[1].htaps;
379cabdff1aSopenharmony_ci            memcpy(s->plane[2].hcoeff, s->plane[1].hcoeff, sizeof(s->plane[1].hcoeff));
380cabdff1aSopenharmony_ci        }
381cabdff1aSopenharmony_ci        if(get_rac(&s->c, s->header_state)){
382cabdff1aSopenharmony_ci            GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS)
383cabdff1aSopenharmony_ci            decode_qlogs(s);
384cabdff1aSopenharmony_ci        }
385cabdff1aSopenharmony_ci    }
386cabdff1aSopenharmony_ci
387cabdff1aSopenharmony_ci    s->spatial_decomposition_type+= (unsigned)get_symbol(&s->c, s->header_state, 1);
388cabdff1aSopenharmony_ci    if(s->spatial_decomposition_type > 1U){
389cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_type %d not supported\n", s->spatial_decomposition_type);
390cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
391cabdff1aSopenharmony_ci    }
392cabdff1aSopenharmony_ci    if(FFMIN(s->avctx-> width>>s->chroma_h_shift,
393cabdff1aSopenharmony_ci             s->avctx->height>>s->chroma_v_shift) >> (s->spatial_decomposition_count-1) <= 1){
394cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_count %d too large for size\n", s->spatial_decomposition_count);
395cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
396cabdff1aSopenharmony_ci    }
397cabdff1aSopenharmony_ci    if (s->avctx->width > 65536-4) {
398cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "Width %d is too large\n", s->avctx->width);
399cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
400cabdff1aSopenharmony_ci    }
401cabdff1aSopenharmony_ci
402cabdff1aSopenharmony_ci
403cabdff1aSopenharmony_ci    s->qlog           += (unsigned)get_symbol(&s->c, s->header_state, 1);
404cabdff1aSopenharmony_ci    s->mv_scale       += (unsigned)get_symbol(&s->c, s->header_state, 1);
405cabdff1aSopenharmony_ci    s->qbias          += (unsigned)get_symbol(&s->c, s->header_state, 1);
406cabdff1aSopenharmony_ci    s->block_max_depth+= (unsigned)get_symbol(&s->c, s->header_state, 1);
407cabdff1aSopenharmony_ci    if(s->block_max_depth > 1 || s->block_max_depth < 0 || s->mv_scale > 256U){
408cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "block_max_depth= %d is too large\n", s->block_max_depth);
409cabdff1aSopenharmony_ci        s->block_max_depth= 0;
410cabdff1aSopenharmony_ci        s->mv_scale = 0;
411cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
412cabdff1aSopenharmony_ci    }
413cabdff1aSopenharmony_ci    if (FFABS(s->qbias) > 127) {
414cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "qbias %d is too large\n", s->qbias);
415cabdff1aSopenharmony_ci        s->qbias = 0;
416cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
417cabdff1aSopenharmony_ci    }
418cabdff1aSopenharmony_ci
419cabdff1aSopenharmony_ci    return 0;
420cabdff1aSopenharmony_ci}
421cabdff1aSopenharmony_ci
422cabdff1aSopenharmony_cistatic int decode_blocks(SnowContext *s){
423cabdff1aSopenharmony_ci    int x, y;
424cabdff1aSopenharmony_ci    int w= s->b_width;
425cabdff1aSopenharmony_ci    int h= s->b_height;
426cabdff1aSopenharmony_ci    int res;
427cabdff1aSopenharmony_ci
428cabdff1aSopenharmony_ci    for(y=0; y<h; y++){
429cabdff1aSopenharmony_ci        for(x=0; x<w; x++){
430cabdff1aSopenharmony_ci            if (s->c.bytestream >= s->c.bytestream_end)
431cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
432cabdff1aSopenharmony_ci            if ((res = decode_q_branch(s, 0, x, y)) < 0)
433cabdff1aSopenharmony_ci                return res;
434cabdff1aSopenharmony_ci        }
435cabdff1aSopenharmony_ci    }
436cabdff1aSopenharmony_ci    return 0;
437cabdff1aSopenharmony_ci}
438cabdff1aSopenharmony_ci
439cabdff1aSopenharmony_cistatic int decode_frame(AVCodecContext *avctx, AVFrame *picture,
440cabdff1aSopenharmony_ci                        int *got_frame, AVPacket *avpkt)
441cabdff1aSopenharmony_ci{
442cabdff1aSopenharmony_ci    const uint8_t *buf = avpkt->data;
443cabdff1aSopenharmony_ci    int buf_size = avpkt->size;
444cabdff1aSopenharmony_ci    SnowContext *s = avctx->priv_data;
445cabdff1aSopenharmony_ci    RangeCoder * const c= &s->c;
446cabdff1aSopenharmony_ci    int bytes_read;
447cabdff1aSopenharmony_ci    int level, orientation, plane_index;
448cabdff1aSopenharmony_ci    int res;
449cabdff1aSopenharmony_ci
450cabdff1aSopenharmony_ci    ff_init_range_decoder(c, buf, buf_size);
451cabdff1aSopenharmony_ci    ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
452cabdff1aSopenharmony_ci
453cabdff1aSopenharmony_ci    s->current_picture->pict_type= AV_PICTURE_TYPE_I; //FIXME I vs. P
454cabdff1aSopenharmony_ci    if ((res = decode_header(s)) < 0)
455cabdff1aSopenharmony_ci        return res;
456cabdff1aSopenharmony_ci    if ((res=ff_snow_common_init_after_header(avctx)) < 0)
457cabdff1aSopenharmony_ci        return res;
458cabdff1aSopenharmony_ci
459cabdff1aSopenharmony_ci    // realloc slice buffer for the case that spatial_decomposition_count changed
460cabdff1aSopenharmony_ci    ff_slice_buffer_destroy(&s->sb);
461cabdff1aSopenharmony_ci    if ((res = ff_slice_buffer_init(&s->sb, s->plane[0].height,
462cabdff1aSopenharmony_ci                                    (MB_SIZE >> s->block_max_depth) +
463cabdff1aSopenharmony_ci                                    s->spatial_decomposition_count * 11 + 1,
464cabdff1aSopenharmony_ci                                    s->plane[0].width,
465cabdff1aSopenharmony_ci                                    s->spatial_idwt_buffer)) < 0)
466cabdff1aSopenharmony_ci        return res;
467cabdff1aSopenharmony_ci
468cabdff1aSopenharmony_ci    for(plane_index=0; plane_index < s->nb_planes; plane_index++){
469cabdff1aSopenharmony_ci        Plane *p= &s->plane[plane_index];
470cabdff1aSopenharmony_ci        p->fast_mc= p->diag_mc && p->htaps==6 && p->hcoeff[0]==40
471cabdff1aSopenharmony_ci                                              && p->hcoeff[1]==-10
472cabdff1aSopenharmony_ci                                              && p->hcoeff[2]==2;
473cabdff1aSopenharmony_ci    }
474cabdff1aSopenharmony_ci
475cabdff1aSopenharmony_ci    ff_snow_alloc_blocks(s);
476cabdff1aSopenharmony_ci
477cabdff1aSopenharmony_ci    if((res = ff_snow_frame_start(s)) < 0)
478cabdff1aSopenharmony_ci        return res;
479cabdff1aSopenharmony_ci
480cabdff1aSopenharmony_ci    s->current_picture->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
481cabdff1aSopenharmony_ci
482cabdff1aSopenharmony_ci    //keyframe flag duplication mess FIXME
483cabdff1aSopenharmony_ci    if(avctx->debug&FF_DEBUG_PICT_INFO)
484cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR,
485cabdff1aSopenharmony_ci               "keyframe:%d qlog:%d qbias: %d mvscale: %d "
486cabdff1aSopenharmony_ci               "decomposition_type:%d decomposition_count:%d\n",
487cabdff1aSopenharmony_ci               s->keyframe, s->qlog, s->qbias, s->mv_scale,
488cabdff1aSopenharmony_ci               s->spatial_decomposition_type,
489cabdff1aSopenharmony_ci               s->spatial_decomposition_count
490cabdff1aSopenharmony_ci              );
491cabdff1aSopenharmony_ci
492cabdff1aSopenharmony_ci    if (s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_MVS) {
493cabdff1aSopenharmony_ci        size_t size;
494cabdff1aSopenharmony_ci        res = av_size_mult(s->b_width * s->b_height, sizeof(AVMotionVector) << (s->block_max_depth*2), &size);
495cabdff1aSopenharmony_ci        if (res)
496cabdff1aSopenharmony_ci            return res;
497cabdff1aSopenharmony_ci        av_fast_malloc(&s->avmv, &s->avmv_size, size);
498cabdff1aSopenharmony_ci        if (!s->avmv)
499cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
500cabdff1aSopenharmony_ci    } else {
501cabdff1aSopenharmony_ci        s->avmv_size = 0;
502cabdff1aSopenharmony_ci        av_freep(&s->avmv);
503cabdff1aSopenharmony_ci    }
504cabdff1aSopenharmony_ci    s->avmv_index = 0;
505cabdff1aSopenharmony_ci
506cabdff1aSopenharmony_ci    if ((res = decode_blocks(s)) < 0)
507cabdff1aSopenharmony_ci        return res;
508cabdff1aSopenharmony_ci
509cabdff1aSopenharmony_ci    for(plane_index=0; plane_index < s->nb_planes; plane_index++){
510cabdff1aSopenharmony_ci        Plane *p= &s->plane[plane_index];
511cabdff1aSopenharmony_ci        int w= p->width;
512cabdff1aSopenharmony_ci        int h= p->height;
513cabdff1aSopenharmony_ci        int x, y;
514cabdff1aSopenharmony_ci        int decode_state[MAX_DECOMPOSITIONS][4][1]; /* Stored state info for unpack_coeffs. 1 variable per instance. */
515cabdff1aSopenharmony_ci
516cabdff1aSopenharmony_ci        if(s->avctx->debug&2048){
517cabdff1aSopenharmony_ci            memset(s->spatial_dwt_buffer, 0, sizeof(DWTELEM)*w*h);
518cabdff1aSopenharmony_ci            predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
519cabdff1aSopenharmony_ci
520cabdff1aSopenharmony_ci            for(y=0; y<h; y++){
521cabdff1aSopenharmony_ci                for(x=0; x<w; x++){
522cabdff1aSopenharmony_ci                    int v= s->current_picture->data[plane_index][y*s->current_picture->linesize[plane_index] + x];
523cabdff1aSopenharmony_ci                    s->mconly_picture->data[plane_index][y*s->mconly_picture->linesize[plane_index] + x]= v;
524cabdff1aSopenharmony_ci                }
525cabdff1aSopenharmony_ci            }
526cabdff1aSopenharmony_ci        }
527cabdff1aSopenharmony_ci
528cabdff1aSopenharmony_ci        for(level=0; level<s->spatial_decomposition_count; level++){
529cabdff1aSopenharmony_ci            for(orientation=level ? 1 : 0; orientation<4; orientation++){
530cabdff1aSopenharmony_ci                SubBand *b= &p->band[level][orientation];
531cabdff1aSopenharmony_ci                unpack_coeffs(s, b, b->parent, orientation);
532cabdff1aSopenharmony_ci            }
533cabdff1aSopenharmony_ci        }
534cabdff1aSopenharmony_ci
535cabdff1aSopenharmony_ci        {
536cabdff1aSopenharmony_ci        const int mb_h= s->b_height << s->block_max_depth;
537cabdff1aSopenharmony_ci        const int block_size = MB_SIZE >> s->block_max_depth;
538cabdff1aSopenharmony_ci        const int block_h    = plane_index ? block_size>>s->chroma_v_shift : block_size;
539cabdff1aSopenharmony_ci        int mb_y;
540cabdff1aSopenharmony_ci        DWTCompose cs[MAX_DECOMPOSITIONS];
541cabdff1aSopenharmony_ci        int yd=0, yq=0;
542cabdff1aSopenharmony_ci        int y;
543cabdff1aSopenharmony_ci        int end_y;
544cabdff1aSopenharmony_ci
545cabdff1aSopenharmony_ci        ff_spatial_idwt_buffered_init(cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count);
546cabdff1aSopenharmony_ci        for(mb_y=0; mb_y<=mb_h; mb_y++){
547cabdff1aSopenharmony_ci
548cabdff1aSopenharmony_ci            int slice_starty = block_h*mb_y;
549cabdff1aSopenharmony_ci            int slice_h = block_h*(mb_y+1);
550cabdff1aSopenharmony_ci
551cabdff1aSopenharmony_ci            if (!(s->keyframe || s->avctx->debug&512)){
552cabdff1aSopenharmony_ci                slice_starty = FFMAX(0, slice_starty - (block_h >> 1));
553cabdff1aSopenharmony_ci                slice_h -= (block_h >> 1);
554cabdff1aSopenharmony_ci            }
555cabdff1aSopenharmony_ci
556cabdff1aSopenharmony_ci            for(level=0; level<s->spatial_decomposition_count; level++){
557cabdff1aSopenharmony_ci                for(orientation=level ? 1 : 0; orientation<4; orientation++){
558cabdff1aSopenharmony_ci                    SubBand *b= &p->band[level][orientation];
559cabdff1aSopenharmony_ci                    int start_y;
560cabdff1aSopenharmony_ci                    int end_y;
561cabdff1aSopenharmony_ci                    int our_mb_start = mb_y;
562cabdff1aSopenharmony_ci                    int our_mb_end = (mb_y + 1);
563cabdff1aSopenharmony_ci                    const int extra= 3;
564cabdff1aSopenharmony_ci                    start_y = (mb_y ? ((block_h * our_mb_start) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra: 0);
565cabdff1aSopenharmony_ci                    end_y = (((block_h * our_mb_end) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra);
566cabdff1aSopenharmony_ci                    if (!(s->keyframe || s->avctx->debug&512)){
567cabdff1aSopenharmony_ci                        start_y = FFMAX(0, start_y - (block_h >> (1+s->spatial_decomposition_count - level)));
568cabdff1aSopenharmony_ci                        end_y = FFMAX(0, end_y - (block_h >> (1+s->spatial_decomposition_count - level)));
569cabdff1aSopenharmony_ci                    }
570cabdff1aSopenharmony_ci                    start_y = FFMIN(b->height, start_y);
571cabdff1aSopenharmony_ci                    end_y = FFMIN(b->height, end_y);
572cabdff1aSopenharmony_ci
573cabdff1aSopenharmony_ci                    if (start_y != end_y){
574cabdff1aSopenharmony_ci                        if (orientation == 0){
575cabdff1aSopenharmony_ci                            SubBand * correlate_band = &p->band[0][0];
576cabdff1aSopenharmony_ci                            int correlate_end_y = FFMIN(b->height, end_y + 1);
577cabdff1aSopenharmony_ci                            int correlate_start_y = FFMIN(b->height, (start_y ? start_y + 1 : 0));
578cabdff1aSopenharmony_ci                            decode_subband_slice_buffered(s, correlate_band, &s->sb, correlate_start_y, correlate_end_y, decode_state[0][0]);
579cabdff1aSopenharmony_ci                            correlate_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, 1, 0, correlate_start_y, correlate_end_y);
580cabdff1aSopenharmony_ci                            dequantize_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, start_y, end_y);
581cabdff1aSopenharmony_ci                        }
582cabdff1aSopenharmony_ci                        else
583cabdff1aSopenharmony_ci                            decode_subband_slice_buffered(s, b, &s->sb, start_y, end_y, decode_state[level][orientation]);
584cabdff1aSopenharmony_ci                    }
585cabdff1aSopenharmony_ci                }
586cabdff1aSopenharmony_ci            }
587cabdff1aSopenharmony_ci
588cabdff1aSopenharmony_ci            for(; yd<slice_h; yd+=4){
589cabdff1aSopenharmony_ci                ff_spatial_idwt_buffered_slice(&s->dwt, cs, &s->sb, s->temp_idwt_buffer, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count, yd);
590cabdff1aSopenharmony_ci            }
591cabdff1aSopenharmony_ci
592cabdff1aSopenharmony_ci            if(s->qlog == LOSSLESS_QLOG){
593cabdff1aSopenharmony_ci                for(; yq<slice_h && yq<h; yq++){
594cabdff1aSopenharmony_ci                    IDWTELEM * line = slice_buffer_get_line(&s->sb, yq);
595cabdff1aSopenharmony_ci                    for(x=0; x<w; x++){
596cabdff1aSopenharmony_ci                        line[x] *= 1<<FRAC_BITS;
597cabdff1aSopenharmony_ci                    }
598cabdff1aSopenharmony_ci                }
599cabdff1aSopenharmony_ci            }
600cabdff1aSopenharmony_ci
601cabdff1aSopenharmony_ci            predict_slice_buffered(s, &s->sb, s->spatial_idwt_buffer, plane_index, 1, mb_y);
602cabdff1aSopenharmony_ci
603cabdff1aSopenharmony_ci            y = FFMIN(p->height, slice_starty);
604cabdff1aSopenharmony_ci            end_y = FFMIN(p->height, slice_h);
605cabdff1aSopenharmony_ci            while(y < end_y)
606cabdff1aSopenharmony_ci                ff_slice_buffer_release(&s->sb, y++);
607cabdff1aSopenharmony_ci        }
608cabdff1aSopenharmony_ci
609cabdff1aSopenharmony_ci        ff_slice_buffer_flush(&s->sb);
610cabdff1aSopenharmony_ci        }
611cabdff1aSopenharmony_ci
612cabdff1aSopenharmony_ci    }
613cabdff1aSopenharmony_ci
614cabdff1aSopenharmony_ci    emms_c();
615cabdff1aSopenharmony_ci
616cabdff1aSopenharmony_ci    ff_snow_release_buffer(avctx);
617cabdff1aSopenharmony_ci
618cabdff1aSopenharmony_ci    if(!(s->avctx->debug&2048))
619cabdff1aSopenharmony_ci        res = av_frame_ref(picture, s->current_picture);
620cabdff1aSopenharmony_ci    else
621cabdff1aSopenharmony_ci        res = av_frame_ref(picture, s->mconly_picture);
622cabdff1aSopenharmony_ci    if (res >= 0 && s->avmv_index) {
623cabdff1aSopenharmony_ci        AVFrameSideData *sd;
624cabdff1aSopenharmony_ci
625cabdff1aSopenharmony_ci        sd = av_frame_new_side_data(picture, AV_FRAME_DATA_MOTION_VECTORS, s->avmv_index * sizeof(AVMotionVector));
626cabdff1aSopenharmony_ci        if (!sd)
627cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
628cabdff1aSopenharmony_ci        memcpy(sd->data, s->avmv, s->avmv_index * sizeof(AVMotionVector));
629cabdff1aSopenharmony_ci    }
630cabdff1aSopenharmony_ci
631cabdff1aSopenharmony_ci    if (res < 0)
632cabdff1aSopenharmony_ci        return res;
633cabdff1aSopenharmony_ci
634cabdff1aSopenharmony_ci    *got_frame = 1;
635cabdff1aSopenharmony_ci
636cabdff1aSopenharmony_ci    bytes_read= c->bytestream - c->bytestream_start;
637cabdff1aSopenharmony_ci    if(bytes_read ==0) av_log(s->avctx, AV_LOG_ERROR, "error at end of frame\n"); //FIXME
638cabdff1aSopenharmony_ci
639cabdff1aSopenharmony_ci    return bytes_read;
640cabdff1aSopenharmony_ci}
641cabdff1aSopenharmony_ci
642cabdff1aSopenharmony_cistatic av_cold int decode_end(AVCodecContext *avctx)
643cabdff1aSopenharmony_ci{
644cabdff1aSopenharmony_ci    SnowContext *s = avctx->priv_data;
645cabdff1aSopenharmony_ci
646cabdff1aSopenharmony_ci    ff_slice_buffer_destroy(&s->sb);
647cabdff1aSopenharmony_ci
648cabdff1aSopenharmony_ci    ff_snow_common_end(s);
649cabdff1aSopenharmony_ci
650cabdff1aSopenharmony_ci    s->avmv_size = 0;
651cabdff1aSopenharmony_ci    av_freep(&s->avmv);
652cabdff1aSopenharmony_ci
653cabdff1aSopenharmony_ci    return 0;
654cabdff1aSopenharmony_ci}
655cabdff1aSopenharmony_ci
656cabdff1aSopenharmony_ciconst FFCodec ff_snow_decoder = {
657cabdff1aSopenharmony_ci    .p.name         = "snow",
658cabdff1aSopenharmony_ci    .p.long_name    = NULL_IF_CONFIG_SMALL("Snow"),
659cabdff1aSopenharmony_ci    .p.type         = AVMEDIA_TYPE_VIDEO,
660cabdff1aSopenharmony_ci    .p.id           = AV_CODEC_ID_SNOW,
661cabdff1aSopenharmony_ci    .priv_data_size = sizeof(SnowContext),
662cabdff1aSopenharmony_ci    .init           = ff_snow_common_init,
663cabdff1aSopenharmony_ci    .close          = decode_end,
664cabdff1aSopenharmony_ci    FF_CODEC_DECODE_CB(decode_frame),
665cabdff1aSopenharmony_ci    .p.capabilities = AV_CODEC_CAP_DR1 /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/,
666cabdff1aSopenharmony_ci    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
667cabdff1aSopenharmony_ci                      FF_CODEC_CAP_INIT_CLEANUP,
668cabdff1aSopenharmony_ci};
669