~ubuntu-branches/ubuntu/saucy/gst-libav1.0/saucy-proposed

« back to all changes in this revision

Viewing changes to gst-libs/ext/libav/libavcodec/mss12.c

  • Committer: Package Import Robot
  • Author(s): Sebastian Dröge
  • Date: 2013-07-30 09:00:15 UTC
  • mfrom: (1.1.16) (7.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20130730090015-sc1ou2yssu7q5w4e
Tags: 1.1.3-1
* New upstream development snapshot:
  + debian/control:
    - Build depend on GStreamer and gst-plugins-base >= 1.1.3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2012 Konstantin Shishkov
 
3
 *
 
4
 * This file is part of Libav.
 
5
 *
 
6
 * Libav is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU Lesser General Public
 
8
 * License as published by the Free Software Foundation; either
 
9
 * version 2.1 of the License, or (at your option) any later version.
 
10
 *
 
11
 * Libav is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * Lesser General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public
 
17
 * License along with Libav; if not, write to the Free Software
 
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
19
 */
 
20
 
 
21
/**
 
22
 * @file
 
23
 * Common functions for Microsoft Screen 1 and 2
 
24
 */
 
25
 
 
26
#include "libavutil/intfloat.h"
 
27
#include "libavutil/intreadwrite.h"
 
28
#include "avcodec.h"
 
29
#include "mss12.h"
 
30
 
 
31
enum SplitMode {
 
32
    SPLIT_VERT = 0,
 
33
    SPLIT_HOR,
 
34
    SPLIT_NONE
 
35
};
 
36
 
 
37
static const int sec_order_sizes[4] = { 1, 7, 6, 1 };
 
38
 
 
39
enum ContextDirection {
 
40
    TOP_LEFT = 0,
 
41
    TOP,
 
42
    TOP_RIGHT,
 
43
    LEFT
 
44
};
 
45
 
 
46
static int model_calc_threshold(Model *m)
 
47
{
 
48
    int thr;
 
49
 
 
50
    thr = 2 * m->weights[m->num_syms] - 1;
 
51
    thr = ((thr >> 1) + 4 * m->cum_prob[0]) / thr;
 
52
 
 
53
    return FFMIN(thr, 0x3FFF);
 
54
}
 
55
 
 
56
static void model_reset(Model *m)
 
57
{
 
58
    int i;
 
59
 
 
60
    for (i = 0; i <= m->num_syms; i++) {
 
61
        m->weights[i]  = 1;
 
62
        m->cum_prob[i] = m->num_syms - i;
 
63
    }
 
64
    m->weights[0] = 0;
 
65
    for (i = 0; i < m->num_syms; i++)
 
66
        m->idx2sym[i + 1] = i;
 
67
}
 
68
 
 
69
static av_cold void model_init(Model *m, int num_syms, int thr_weight)
 
70
{
 
71
    m->num_syms   = num_syms;
 
72
    m->thr_weight = thr_weight;
 
73
    m->threshold  = num_syms * thr_weight;
 
74
}
 
75
 
 
76
static void model_rescale_weights(Model *m)
 
77
{
 
78
    int i;
 
79
    int cum_prob;
 
80
 
 
81
    if (m->thr_weight == THRESH_ADAPTIVE)
 
82
        m->threshold = model_calc_threshold(m);
 
83
    while (m->cum_prob[0] > m->threshold) {
 
84
        cum_prob = 0;
 
85
        for (i = m->num_syms; i >= 0; i--) {
 
86
            m->cum_prob[i] = cum_prob;
 
87
            m->weights[i]  = (m->weights[i] + 1) >> 1;
 
88
            cum_prob      += m->weights[i];
 
89
        }
 
90
    }
 
91
}
 
92
 
 
93
void ff_mss12_model_update(Model *m, int val)
 
94
{
 
95
    int i;
 
96
 
 
97
    if (m->weights[val] == m->weights[val - 1]) {
 
98
        for (i = val; m->weights[i - 1] == m->weights[val]; i--);
 
99
        if (i != val) {
 
100
            int sym1, sym2;
 
101
 
 
102
            sym1 = m->idx2sym[val];
 
103
            sym2 = m->idx2sym[i];
 
104
 
 
105
            m->idx2sym[val]  = sym2;
 
106
            m->idx2sym[i]    = sym1;
 
107
 
 
108
            val = i;
 
109
        }
 
110
    }
 
111
    m->weights[val]++;
 
112
    for (i = val - 1; i >= 0; i--)
 
113
        m->cum_prob[i]++;
 
114
    model_rescale_weights(m);
 
115
}
 
116
 
 
117
static void pixctx_reset(PixContext *ctx)
 
118
{
 
119
    int i, j;
 
120
 
 
121
    if (!ctx->special_initial_cache)
 
122
        for (i = 0; i < ctx->cache_size; i++)
 
123
            ctx->cache[i] = i;
 
124
    else {
 
125
        ctx->cache[0] = 1;
 
126
        ctx->cache[1] = 2;
 
127
        ctx->cache[2] = 4;
 
128
    }
 
129
 
 
130
    model_reset(&ctx->cache_model);
 
131
    model_reset(&ctx->full_model);
 
132
 
 
133
    for (i = 0; i < 15; i++)
 
134
        for (j = 0; j < 4; j++)
 
135
            model_reset(&ctx->sec_models[i][j]);
 
136
}
 
137
 
 
138
static av_cold void pixctx_init(PixContext *ctx, int cache_size,
 
139
                                int full_model_syms, int special_initial_cache)
 
140
{
 
141
    int i, j, k, idx;
 
142
 
 
143
    ctx->cache_size            = cache_size + 4;
 
144
    ctx->num_syms              = cache_size;
 
145
    ctx->special_initial_cache = special_initial_cache;
 
146
 
 
147
    model_init(&ctx->cache_model, ctx->num_syms + 1, THRESH_LOW);
 
148
    model_init(&ctx->full_model, full_model_syms, THRESH_HIGH);
 
149
 
 
150
    for (i = 0, idx = 0; i < 4; i++)
 
151
        for (j = 0; j < sec_order_sizes[i]; j++, idx++)
 
152
            for (k = 0; k < 4; k++)
 
153
                model_init(&ctx->sec_models[idx][k], 2 + i,
 
154
                           i ? THRESH_LOW : THRESH_ADAPTIVE);
 
155
}
 
156
 
 
157
static av_always_inline int decode_pixel(ArithCoder *acoder, PixContext *pctx,
 
158
                                         uint8_t *ngb, int num_ngb, int any_ngb)
 
159
{
 
160
    int i, val, pix;
 
161
 
 
162
    val = acoder->get_model_sym(acoder, &pctx->cache_model);
 
163
    if (val < pctx->num_syms) {
 
164
        if (any_ngb) {
 
165
            int idx, j;
 
166
 
 
167
            idx = 0;
 
168
            for (i = 0; i < pctx->cache_size; i++) {
 
169
                for (j = 0; j < num_ngb; j++)
 
170
                    if (pctx->cache[i] == ngb[j])
 
171
                        break;
 
172
                if (j == num_ngb) {
 
173
                    if (idx == val)
 
174
                        break;
 
175
                    idx++;
 
176
                }
 
177
            }
 
178
            val = FFMIN(i, pctx->cache_size - 1);
 
179
        }
 
180
        pix = pctx->cache[val];
 
181
    } else {
 
182
        pix = acoder->get_model_sym(acoder, &pctx->full_model);
 
183
        for (i = 0; i < pctx->cache_size - 1; i++)
 
184
            if (pctx->cache[i] == pix)
 
185
                break;
 
186
        val = i;
 
187
    }
 
188
    if (val) {
 
189
        for (i = val; i > 0; i--)
 
190
            pctx->cache[i] = pctx->cache[i - 1];
 
191
        pctx->cache[0] = pix;
 
192
    }
 
193
 
 
194
    return pix;
 
195
}
 
196
 
 
197
static int decode_pixel_in_context(ArithCoder *acoder, PixContext *pctx,
 
198
                                   uint8_t *src, int stride, int x, int y,
 
199
                                   int has_right)
 
200
{
 
201
    uint8_t neighbours[4];
 
202
    uint8_t ref_pix[4];
 
203
    int nlen;
 
204
    int layer = 0, sub;
 
205
    int pix;
 
206
    int i, j;
 
207
 
 
208
    if (!y) {
 
209
        memset(neighbours, src[-1], 4);
 
210
    } else {
 
211
        neighbours[TOP] = src[-stride];
 
212
        if (!x) {
 
213
            neighbours[TOP_LEFT] = neighbours[LEFT] = neighbours[TOP];
 
214
        } else {
 
215
            neighbours[TOP_LEFT] = src[-stride - 1];
 
216
            neighbours[    LEFT] = src[-1];
 
217
        }
 
218
        if (has_right)
 
219
            neighbours[TOP_RIGHT] = src[-stride + 1];
 
220
        else
 
221
            neighbours[TOP_RIGHT] = neighbours[TOP];
 
222
    }
 
223
 
 
224
    sub = 0;
 
225
    if (x >= 2 && src[-2] == neighbours[LEFT])
 
226
        sub  = 1;
 
227
    if (y >= 2 && src[-2 * stride] == neighbours[TOP])
 
228
        sub |= 2;
 
229
 
 
230
    nlen = 1;
 
231
    ref_pix[0] = neighbours[0];
 
232
    for (i = 1; i < 4; i++) {
 
233
        for (j = 0; j < nlen; j++)
 
234
            if (ref_pix[j] == neighbours[i])
 
235
                break;
 
236
        if (j == nlen)
 
237
            ref_pix[nlen++] = neighbours[i];
 
238
    }
 
239
 
 
240
    switch (nlen) {
 
241
    case 1:
 
242
        layer = 0;
 
243
        break;
 
244
    case 2:
 
245
        if (neighbours[TOP] == neighbours[TOP_LEFT]) {
 
246
            if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT])
 
247
                layer = 1;
 
248
            else if (neighbours[LEFT] == neighbours[TOP_LEFT])
 
249
                layer = 2;
 
250
            else
 
251
                layer = 3;
 
252
        } else if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT]) {
 
253
            if (neighbours[LEFT] == neighbours[TOP_LEFT])
 
254
                layer = 4;
 
255
            else
 
256
                layer = 5;
 
257
        } else if (neighbours[LEFT] == neighbours[TOP_LEFT]) {
 
258
            layer = 6;
 
259
        } else {
 
260
            layer = 7;
 
261
        }
 
262
        break;
 
263
    case 3:
 
264
        if (neighbours[TOP] == neighbours[TOP_LEFT])
 
265
            layer = 8;
 
266
        else if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT])
 
267
            layer = 9;
 
268
        else if (neighbours[LEFT] == neighbours[TOP_LEFT])
 
269
            layer = 10;
 
270
        else if (neighbours[TOP_RIGHT] == neighbours[TOP])
 
271
            layer = 11;
 
272
        else if (neighbours[TOP] == neighbours[LEFT])
 
273
            layer = 12;
 
274
        else
 
275
            layer = 13;
 
276
        break;
 
277
    case 4:
 
278
        layer = 14;
 
279
        break;
 
280
    }
 
281
 
 
282
    pix = acoder->get_model_sym(acoder,
 
283
                                &pctx->sec_models[layer][sub]);
 
284
    if (pix < nlen)
 
285
        return ref_pix[pix];
 
286
    else
 
287
        return decode_pixel(acoder, pctx, ref_pix, nlen, 1);
 
288
}
 
289
 
 
290
static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_pic,
 
291
                         int x, int y, int width, int height, int stride,
 
292
                         int rgb_stride, PixContext *pctx, const uint32_t *pal)
 
293
{
 
294
    int i, j, p;
 
295
    uint8_t *rgb_dst = rgb_pic + x * 3 + y * rgb_stride;
 
296
 
 
297
    dst += x + y * stride;
 
298
 
 
299
    for (j = 0; j < height; j++) {
 
300
        for (i = 0; i < width; i++) {
 
301
            if (!i && !j)
 
302
                p = decode_pixel(acoder, pctx, NULL, 0, 0);
 
303
            else
 
304
                p = decode_pixel_in_context(acoder, pctx, dst + i, stride,
 
305
                                            i, j, width - i - 1);
 
306
            dst[i] = p;
 
307
 
 
308
            if (rgb_pic)
 
309
                AV_WB24(rgb_dst + i * 3, pal[p]);
 
310
        }
 
311
        dst     += stride;
 
312
        rgb_dst += rgb_stride;
 
313
    }
 
314
 
 
315
    return 0;
 
316
}
 
317
 
 
318
static void copy_rectangles(MSS12Context const *c,
 
319
                            int x, int y, int width, int height)
 
320
{
 
321
    int j;
 
322
 
 
323
    if (c->last_rgb_pic)
 
324
        for (j = y; j < y + height; j++) {
 
325
            memcpy(c->rgb_pic      + j * c->rgb_stride + x * 3,
 
326
                   c->last_rgb_pic + j * c->rgb_stride + x * 3,
 
327
                   width * 3);
 
328
            memcpy(c->pal_pic      + j * c->pal_stride + x,
 
329
                   c->last_pal_pic + j * c->pal_stride + x,
 
330
                   width);
 
331
        }
 
332
}
 
333
 
 
334
static int motion_compensation(MSS12Context const *c,
 
335
                               int x, int y, int width, int height)
 
336
{
 
337
    if (x + c->mvX < 0 || x + c->mvX + width  > c->avctx->width  ||
 
338
        y + c->mvY < 0 || y + c->mvY + height > c->avctx->height ||
 
339
        !c->rgb_pic)
 
340
        return -1;
 
341
    else {
 
342
        uint8_t *dst     = c->pal_pic + x     + y * c->pal_stride;
 
343
        uint8_t *rgb_dst = c->rgb_pic + x * 3 + y * c->rgb_stride;
 
344
        uint8_t *src;
 
345
        uint8_t *rgb_src;
 
346
        int j;
 
347
        x += c->mvX;
 
348
        y += c->mvY;
 
349
        if (c->last_rgb_pic) {
 
350
            src     = c->last_pal_pic + x +     y * c->pal_stride;
 
351
            rgb_src = c->last_rgb_pic + x * 3 + y * c->rgb_stride;
 
352
        } else {
 
353
            src     = c->pal_pic + x     + y * c->pal_stride;
 
354
            rgb_src = c->rgb_pic + x * 3 + y * c->rgb_stride;
 
355
        }
 
356
        for (j = 0; j < height; j++) {
 
357
            memmove(dst, src, width);
 
358
            memmove(rgb_dst, rgb_src, width * 3);
 
359
            dst     += c->pal_stride;
 
360
            src     += c->pal_stride;
 
361
            rgb_dst += c->rgb_stride;
 
362
            rgb_src += c->rgb_stride;
 
363
        }
 
364
    }
 
365
    return 0;
 
366
}
 
367
 
 
368
static int decode_region_masked(MSS12Context const *c, ArithCoder *acoder,
 
369
                                uint8_t *dst, int stride, uint8_t *mask,
 
370
                                int mask_stride, int x, int y,
 
371
                                int width, int height,
 
372
                                PixContext *pctx)
 
373
{
 
374
    int i, j, p;
 
375
    uint8_t *rgb_dst = c->rgb_pic + x * 3 + y * c->rgb_stride;
 
376
 
 
377
    dst  += x + y * stride;
 
378
    mask += x + y * mask_stride;
 
379
 
 
380
    for (j = 0; j < height; j++) {
 
381
        for (i = 0; i < width; i++) {
 
382
            if (c->avctx->err_recognition & AV_EF_EXPLODE &&
 
383
                ( c->rgb_pic && mask[i] != 0x01 && mask[i] != 0x02 && mask[i] != 0x04 ||
 
384
                 !c->rgb_pic && mask[i] != 0x80 && mask[i] != 0xFF))
 
385
                return -1;
 
386
 
 
387
            if (mask[i] == 0x02) {
 
388
                copy_rectangles(c, x + i, y + j, 1, 1);
 
389
            } else if (mask[i] == 0x04) {
 
390
                if (motion_compensation(c, x + i, y + j, 1, 1))
 
391
                    return -1;
 
392
            } else if (mask[i] != 0x80) {
 
393
                if (!i && !j)
 
394
                    p = decode_pixel(acoder, pctx, NULL, 0, 0);
 
395
                else
 
396
                    p = decode_pixel_in_context(acoder, pctx, dst + i, stride,
 
397
                                                i, j, width - i - 1);
 
398
                dst[i] = p;
 
399
                if (c->rgb_pic)
 
400
                    AV_WB24(rgb_dst + i * 3, c->pal[p]);
 
401
            }
 
402
        }
 
403
        dst     += stride;
 
404
        mask    += mask_stride;
 
405
        rgb_dst += c->rgb_stride;
 
406
    }
 
407
 
 
408
    return 0;
 
409
}
 
410
 
 
411
static av_cold void slicecontext_init(SliceContext *sc,
 
412
                                      int version, int full_model_syms)
 
413
{
 
414
    model_init(&sc->intra_region, 2, THRESH_ADAPTIVE);
 
415
    model_init(&sc->inter_region, 2, THRESH_ADAPTIVE);
 
416
    model_init(&sc->split_mode,   3, THRESH_HIGH);
 
417
    model_init(&sc->edge_mode,    2, THRESH_HIGH);
 
418
    model_init(&sc->pivot,        3, THRESH_LOW);
 
419
 
 
420
    pixctx_init(&sc->intra_pix_ctx, 8, full_model_syms, 0);
 
421
 
 
422
    pixctx_init(&sc->inter_pix_ctx, version ? 3 : 2,
 
423
                full_model_syms, version ? 1 : 0);
 
424
}
 
425
 
 
426
void ff_mss12_slicecontext_reset(SliceContext *sc)
 
427
{
 
428
    model_reset(&sc->intra_region);
 
429
    model_reset(&sc->inter_region);
 
430
    model_reset(&sc->split_mode);
 
431
    model_reset(&sc->edge_mode);
 
432
    model_reset(&sc->pivot);
 
433
    pixctx_reset(&sc->intra_pix_ctx);
 
434
    pixctx_reset(&sc->inter_pix_ctx);
 
435
}
 
436
 
 
437
static int decode_pivot(SliceContext *sc, ArithCoder *acoder, int base)
 
438
{
 
439
    int val, inv;
 
440
 
 
441
    inv = acoder->get_model_sym(acoder, &sc->edge_mode);
 
442
    val = acoder->get_model_sym(acoder, &sc->pivot) + 1;
 
443
 
 
444
    if (val > 2) {
 
445
        if ((base + 1) / 2 - 2 <= 0)
 
446
            return -1;
 
447
 
 
448
        val = acoder->get_number(acoder, (base + 1) / 2 - 2) + 3;
 
449
    }
 
450
 
 
451
    if (val >= base)
 
452
        return -1;
 
453
 
 
454
    return inv ? base - val : val;
 
455
}
 
456
 
 
457
static int decode_region_intra(SliceContext *sc, ArithCoder *acoder,
 
458
                               int x, int y, int width, int height)
 
459
{
 
460
    MSS12Context const *c = sc->c;
 
461
    int mode;
 
462
 
 
463
    mode = acoder->get_model_sym(acoder, &sc->intra_region);
 
464
 
 
465
    if (!mode) {
 
466
        int i, j, pix, rgb_pix;
 
467
        int stride       = c->pal_stride;
 
468
        int rgb_stride   = c->rgb_stride;
 
469
        uint8_t *dst     = c->pal_pic + x     + y * stride;
 
470
        uint8_t *rgb_dst = c->rgb_pic + x * 3 + y * rgb_stride;
 
471
 
 
472
        pix     = decode_pixel(acoder, &sc->intra_pix_ctx, NULL, 0, 0);
 
473
        rgb_pix = c->pal[pix];
 
474
        for (i = 0; i < height; i++, dst += stride, rgb_dst += rgb_stride) {
 
475
            memset(dst, pix, width);
 
476
            if (c->rgb_pic)
 
477
                for (j = 0; j < width * 3; j += 3)
 
478
                    AV_WB24(rgb_dst + j, rgb_pix);
 
479
        }
 
480
    } else {
 
481
        return decode_region(acoder, c->pal_pic, c->rgb_pic,
 
482
                             x, y, width, height, c->pal_stride, c->rgb_stride,
 
483
                             &sc->intra_pix_ctx, &c->pal[0]);
 
484
    }
 
485
 
 
486
    return 0;
 
487
}
 
488
 
 
489
static int decode_region_inter(SliceContext *sc, ArithCoder *acoder,
 
490
                               int x, int y, int width, int height)
 
491
{
 
492
    MSS12Context const *c = sc->c;
 
493
    int mode;
 
494
 
 
495
    mode = acoder->get_model_sym(acoder, &sc->inter_region);
 
496
 
 
497
    if (!mode) {
 
498
        mode = decode_pixel(acoder, &sc->inter_pix_ctx, NULL, 0, 0);
 
499
 
 
500
        if (c->avctx->err_recognition & AV_EF_EXPLODE &&
 
501
            ( c->rgb_pic && mode != 0x01 && mode != 0x02 && mode != 0x04 ||
 
502
             !c->rgb_pic && mode != 0x80 && mode != 0xFF))
 
503
            return -1;
 
504
 
 
505
        if (mode == 0x02)
 
506
            copy_rectangles(c, x, y, width, height);
 
507
        else if (mode == 0x04)
 
508
            return motion_compensation(c, x, y, width, height);
 
509
        else if (mode != 0x80)
 
510
            return decode_region_intra(sc, acoder, x, y, width, height);
 
511
    } else {
 
512
        if (decode_region(acoder, c->mask, NULL,
 
513
                          x, y, width, height, c->mask_stride, 0,
 
514
                          &sc->inter_pix_ctx, &c->pal[0]) < 0)
 
515
            return -1;
 
516
        return decode_region_masked(c, acoder, c->pal_pic,
 
517
                                    c->pal_stride, c->mask,
 
518
                                    c->mask_stride,
 
519
                                    x, y, width, height,
 
520
                                    &sc->intra_pix_ctx);
 
521
    }
 
522
 
 
523
    return 0;
 
524
}
 
525
 
 
526
int ff_mss12_decode_rect(SliceContext *sc, ArithCoder *acoder,
 
527
                         int x, int y, int width, int height)
 
528
{
 
529
    int mode, pivot;
 
530
 
 
531
    mode = acoder->get_model_sym(acoder, &sc->split_mode);
 
532
 
 
533
    switch (mode) {
 
534
    case SPLIT_VERT:
 
535
        if ((pivot = decode_pivot(sc, acoder, height)) < 1)
 
536
            return -1;
 
537
        if (ff_mss12_decode_rect(sc, acoder, x, y, width, pivot))
 
538
            return -1;
 
539
        if (ff_mss12_decode_rect(sc, acoder, x, y + pivot, width, height - pivot))
 
540
            return -1;
 
541
        break;
 
542
    case SPLIT_HOR:
 
543
        if ((pivot = decode_pivot(sc, acoder, width)) < 1)
 
544
            return -1;
 
545
        if (ff_mss12_decode_rect(sc, acoder, x, y, pivot, height))
 
546
            return -1;
 
547
        if (ff_mss12_decode_rect(sc, acoder, x + pivot, y, width - pivot, height))
 
548
            return -1;
 
549
        break;
 
550
    case SPLIT_NONE:
 
551
        if (sc->c->keyframe)
 
552
            return decode_region_intra(sc, acoder, x, y, width, height);
 
553
        else
 
554
            return decode_region_inter(sc, acoder, x, y, width, height);
 
555
    default:
 
556
        return -1;
 
557
    }
 
558
 
 
559
    return 0;
 
560
}
 
561
 
 
562
av_cold int ff_mss12_decode_init(MSS12Context *c, int version,
 
563
                                 SliceContext* sc1, SliceContext *sc2)
 
564
{
 
565
    AVCodecContext *avctx = c->avctx;
 
566
    int i;
 
567
 
 
568
    if (avctx->extradata_size < 52 + 256 * 3) {
 
569
        av_log(avctx, AV_LOG_ERROR, "Insufficient extradata size %d\n",
 
570
               avctx->extradata_size);
 
571
        return AVERROR_INVALIDDATA;
 
572
    }
 
573
 
 
574
    if (AV_RB32(avctx->extradata) < avctx->extradata_size) {
 
575
        av_log(avctx, AV_LOG_ERROR,
 
576
               "Insufficient extradata size: expected %d got %d\n",
 
577
               AV_RB32(avctx->extradata),
 
578
               avctx->extradata_size);
 
579
        return AVERROR_INVALIDDATA;
 
580
    }
 
581
 
 
582
    avctx->coded_width  = AV_RB32(avctx->extradata + 20);
 
583
    avctx->coded_height = AV_RB32(avctx->extradata + 24);
 
584
    if (avctx->coded_width > 4096 || avctx->coded_height > 4096) {
 
585
        av_log(avctx, AV_LOG_ERROR, "Frame dimensions %dx%d too large",
 
586
               avctx->coded_width, avctx->coded_height);
 
587
        return AVERROR_INVALIDDATA;
 
588
    }
 
589
 
 
590
    av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d\n",
 
591
           AV_RB32(avctx->extradata + 4), AV_RB32(avctx->extradata + 8));
 
592
    if (version != AV_RB32(avctx->extradata + 4) > 1) {
 
593
        av_log(avctx, AV_LOG_ERROR,
 
594
               "Header version doesn't match codec tag\n");
 
595
        return -1;
 
596
    }
 
597
 
 
598
    c->free_colours = AV_RB32(avctx->extradata + 48);
 
599
    if ((unsigned)c->free_colours > 256) {
 
600
        av_log(avctx, AV_LOG_ERROR,
 
601
               "Incorrect number of changeable palette entries: %d\n",
 
602
               c->free_colours);
 
603
        return AVERROR_INVALIDDATA;
 
604
    }
 
605
    av_log(avctx, AV_LOG_DEBUG, "%d free colour(s)\n", c->free_colours);
 
606
 
 
607
    av_log(avctx, AV_LOG_DEBUG, "Display dimensions %dx%d\n",
 
608
           AV_RB32(avctx->extradata + 12), AV_RB32(avctx->extradata + 16));
 
609
    av_log(avctx, AV_LOG_DEBUG, "Coded dimensions %dx%d\n",
 
610
           avctx->coded_width, avctx->coded_height);
 
611
    av_log(avctx, AV_LOG_DEBUG, "%g frames per second\n",
 
612
           av_int2float(AV_RB32(avctx->extradata + 28)));
 
613
    av_log(avctx, AV_LOG_DEBUG, "Bitrate %d bps\n",
 
614
           AV_RB32(avctx->extradata + 32));
 
615
    av_log(avctx, AV_LOG_DEBUG, "Max. lead time %g ms\n",
 
616
           av_int2float(AV_RB32(avctx->extradata + 36)));
 
617
    av_log(avctx, AV_LOG_DEBUG, "Max. lag time %g ms\n",
 
618
           av_int2float(AV_RB32(avctx->extradata + 40)));
 
619
    av_log(avctx, AV_LOG_DEBUG, "Max. seek time %g ms\n",
 
620
           av_int2float(AV_RB32(avctx->extradata + 44)));
 
621
 
 
622
    if (version) {
 
623
        if (avctx->extradata_size < 60 + 256 * 3) {
 
624
            av_log(avctx, AV_LOG_ERROR,
 
625
                   "Insufficient extradata size %d for v2\n",
 
626
                   avctx->extradata_size);
 
627
            return AVERROR_INVALIDDATA;
 
628
        }
 
629
 
 
630
        c->slice_split = AV_RB32(avctx->extradata + 52);
 
631
        av_log(avctx, AV_LOG_DEBUG, "Slice split %d\n", c->slice_split);
 
632
 
 
633
        c->full_model_syms = AV_RB32(avctx->extradata + 56);
 
634
        if (c->full_model_syms < 2 || c->full_model_syms > 256) {
 
635
            av_log(avctx, AV_LOG_ERROR,
 
636
                   "Incorrect number of used colours %d\n",
 
637
                   c->full_model_syms);
 
638
            return AVERROR_INVALIDDATA;
 
639
        }
 
640
        av_log(avctx, AV_LOG_DEBUG, "Used colours %d\n",
 
641
               c->full_model_syms);
 
642
    } else {
 
643
        c->slice_split     = 0;
 
644
        c->full_model_syms = 256;
 
645
    }
 
646
 
 
647
    for (i = 0; i < 256; i++)
 
648
        c->pal[i] = AV_RB24(avctx->extradata + 52 +
 
649
                            (version ? 8 : 0) + i * 3);
 
650
 
 
651
    c->mask_stride = FFALIGN(avctx->width, 16);
 
652
    c->mask        = av_malloc(c->mask_stride * avctx->height);
 
653
    if (!c->mask) {
 
654
        av_log(avctx, AV_LOG_ERROR, "Cannot allocate mask plane\n");
 
655
        return AVERROR(ENOMEM);
 
656
    }
 
657
 
 
658
    sc1->c = c;
 
659
    slicecontext_init(sc1, version, c->full_model_syms);
 
660
    if (c->slice_split) {
 
661
        sc2->c = c;
 
662
        slicecontext_init(sc2, version, c->full_model_syms);
 
663
    }
 
664
    c->corrupted = 1;
 
665
 
 
666
    return 0;
 
667
}
 
668
 
 
669
av_cold int ff_mss12_decode_end(MSS12Context *c)
 
670
{
 
671
    av_freep(&c->mask);
 
672
 
 
673
    return 0;
 
674
}