GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/magicyuv.c Lines: 244 469 52.0 %
Date: 2019-11-18 18:00:01 Branches: 139 346 40.2 %

Line Branch Exec Source
1
/*
2
 * MagicYUV decoder
3
 * Copyright (c) 2016 Paul B Mahol
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
#include <stdlib.h>
23
#include <string.h>
24
25
#include "libavutil/pixdesc.h"
26
#include "libavutil/qsort.h"
27
28
#include "avcodec.h"
29
#include "bytestream.h"
30
#include "get_bits.h"
31
#include "huffyuvdsp.h"
32
#include "internal.h"
33
#include "lossless_videodsp.h"
34
#include "thread.h"
35
36
typedef struct Slice {
37
    uint32_t start;
38
    uint32_t size;
39
} Slice;
40
41
typedef enum Prediction {
42
    LEFT = 1,
43
    GRADIENT,
44
    MEDIAN,
45
} Prediction;
46
47
typedef struct HuffEntry {
48
    uint16_t sym;
49
    uint8_t  len;
50
    uint32_t code;
51
} HuffEntry;
52
53
typedef struct MagicYUVContext {
54
    AVFrame          *p;
55
    int               max;
56
    int               bps;
57
    int               slice_height;
58
    int               nb_slices;
59
    int               planes;         // number of encoded planes in bitstream
60
    int               decorrelate;    // postprocessing work
61
    int               color_matrix;   // video color matrix
62
    int               flags;
63
    int               interlaced;     // video is interlaced
64
    uint8_t          *buf;            // pointer to AVPacket->data
65
    int               hshift[4];
66
    int               vshift[4];
67
    Slice            *slices[4];      // slice bitstream positions for each plane
68
    unsigned int      slices_size[4]; // slice sizes for each plane
69
    uint8_t           len[4][4096];   // table of code lengths for each plane
70
    VLC               vlc[4];         // VLC for each plane
71
    int (*huff_build)(VLC *vlc, uint8_t *len);
72
    int (*magy_decode_slice)(AVCodecContext *avctx, void *tdata,
73
                             int j, int threadnr);
74
    LLVidDSPContext   llviddsp;
75
} MagicYUVContext;
76
77
99168
static int huff_cmp_len(const void *a, const void *b)
78
{
79
99168
    const HuffEntry *aa = a, *bb = b;
80
99168
    return (aa->len - bb->len) * 256 + aa->sym - bb->sym;
81
}
82
83
static int huff_cmp_len10(const void *a, const void *b)
84
{
85
    const HuffEntry *aa = a, *bb = b;
86
    return (aa->len - bb->len) * 1024 + aa->sym - bb->sym;
87
}
88
89
static int huff_cmp_len12(const void *a, const void *b)
90
{
91
    const HuffEntry *aa = a, *bb = b;
92
    return (aa->len - bb->len) * 4096 + aa->sym - bb->sym;
93
}
94
95
static int huff_build10(VLC *vlc, uint8_t *len)
96
{
97
    HuffEntry he[1024];
98
    uint32_t codes[1024];
99
    uint8_t bits[1024];
100
    uint16_t syms[1024];
101
    uint32_t code;
102
    int i;
103
104
    for (i = 0; i < 1024; i++) {
105
        he[i].sym = 1023 - i;
106
        he[i].len = len[i];
107
        if (len[i] == 0 || len[i] > 32)
108
            return AVERROR_INVALIDDATA;
109
    }
110
    AV_QSORT(he, 1024, HuffEntry, huff_cmp_len10);
111
112
    code = 1;
113
    for (i = 1023; i >= 0; i--) {
114
        codes[i] = code >> (32 - he[i].len);
115
        bits[i]  = he[i].len;
116
        syms[i]  = he[i].sym;
117
        code += 0x80000000u >> (he[i].len - 1);
118
    }
119
120
    ff_free_vlc(vlc);
121
    return ff_init_vlc_sparse(vlc, FFMIN(he[1023].len, 12), 1024,
122
                              bits,  sizeof(*bits),  sizeof(*bits),
123
                              codes, sizeof(*codes), sizeof(*codes),
124
                              syms,  sizeof(*syms),  sizeof(*syms), 0);
125
}
126
127
static int huff_build12(VLC *vlc, uint8_t *len)
128
{
129
    HuffEntry he[4096];
130
    uint32_t codes[4096];
131
    uint8_t bits[4096];
132
    uint16_t syms[4096];
133
    uint32_t code;
134
    int i;
135
136
    for (i = 0; i < 4096; i++) {
137
        he[i].sym = 4095 - i;
138
        he[i].len = len[i];
139
        if (len[i] == 0 || len[i] > 32)
140
            return AVERROR_INVALIDDATA;
141
    }
142
    AV_QSORT(he, 4096, HuffEntry, huff_cmp_len12);
143
144
    code = 1;
145
    for (i = 4095; i >= 0; i--) {
146
        codes[i] = code >> (32 - he[i].len);
147
        bits[i]  = he[i].len;
148
        syms[i]  = he[i].sym;
149
        code += 0x80000000u >> (he[i].len - 1);
150
    }
151
152
    ff_free_vlc(vlc);
153
    return ff_init_vlc_sparse(vlc, FFMIN(he[4095].len, 14), 4096,
154
                              bits,  sizeof(*bits),  sizeof(*bits),
155
                              codes, sizeof(*codes), sizeof(*codes),
156
                              syms,  sizeof(*syms),  sizeof(*syms), 0);
157
}
158
159
42
static int huff_build(VLC *vlc, uint8_t *len)
160
{
161
    HuffEntry he[256];
162
    uint32_t codes[256];
163
    uint8_t bits[256];
164
    uint8_t syms[256];
165
    uint32_t code;
166
    int i;
167
168
10794
    for (i = 0; i < 256; i++) {
169
10752
        he[i].sym = 255 - i;
170
10752
        he[i].len = len[i];
171

10752
        if (len[i] == 0 || len[i] > 32)
172
            return AVERROR_INVALIDDATA;
173
    }
174











84296
    AV_QSORT(he, 256, HuffEntry, huff_cmp_len);
175
176
42
    code = 1;
177
10794
    for (i = 255; i >= 0; i--) {
178
10752
        codes[i] = code >> (32 - he[i].len);
179
10752
        bits[i]  = he[i].len;
180
10752
        syms[i]  = he[i].sym;
181
10752
        code += 0x80000000u >> (he[i].len - 1);
182
    }
183
184
42
    ff_free_vlc(vlc);
185
42
    return ff_init_vlc_sparse(vlc, FFMIN(he[255].len, 12), 256,
186
                              bits,  sizeof(*bits),  sizeof(*bits),
187
                              codes, sizeof(*codes), sizeof(*codes),
188
                              syms,  sizeof(*syms),  sizeof(*syms), 0);
189
}
190
191
static void magicyuv_median_pred16(uint16_t *dst, const uint16_t *src1,
192
                                   const uint16_t *diff, intptr_t w,
193
                                   int *left, int *left_top, int max)
194
{
195
    int i;
196
    uint16_t l, lt;
197
198
    l  = *left;
199
    lt = *left_top;
200
201
    for (i = 0; i < w; i++) {
202
        l      = mid_pred(l, src1[i], (l + src1[i] - lt)) + diff[i];
203
        l     &= max;
204
        lt     = src1[i];
205
        dst[i] = l;
206
    }
207
208
    *left     = l;
209
    *left_top = lt;
210
}
211
212
static int magy_decode_slice10(AVCodecContext *avctx, void *tdata,
213
                               int j, int threadnr)
214
{
215
    MagicYUVContext *s = avctx->priv_data;
216
    int interlaced = s->interlaced;
217
    const int bps = s->bps;
218
    const int max = s->max - 1;
219
    AVFrame *p = s->p;
220
    int i, k, x;
221
    GetBitContext gb;
222
    uint16_t *dst;
223
224
    for (i = 0; i < s->planes; i++) {
225
        int left, lefttop, top;
226
        int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]);
227
        int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]);
228
        int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]);
229
        ptrdiff_t fake_stride = (p->linesize[i] / 2) * (1 + interlaced);
230
        ptrdiff_t stride = p->linesize[i] / 2;
231
        int flags, pred;
232
        int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start,
233
                                 s->slices[i][j].size);
234
235
        if (ret < 0)
236
            return ret;
237
238
        flags = get_bits(&gb, 8);
239
        pred  = get_bits(&gb, 8);
240
241
        dst = (uint16_t *)p->data[i] + j * sheight * stride;
242
        if (flags & 1) {
243
            if (get_bits_left(&gb) < bps * width * height)
244
                return AVERROR_INVALIDDATA;
245
            for (k = 0; k < height; k++) {
246
                for (x = 0; x < width; x++)
247
                    dst[x] = get_bits(&gb, bps);
248
249
                dst += stride;
250
            }
251
        } else {
252
            for (k = 0; k < height; k++) {
253
                for (x = 0; x < width; x++) {
254
                    int pix;
255
                    if (get_bits_left(&gb) <= 0)
256
                        return AVERROR_INVALIDDATA;
257
258
                    pix = get_vlc2(&gb, s->vlc[i].table, s->vlc[i].bits, 3);
259
                    if (pix < 0)
260
                        return AVERROR_INVALIDDATA;
261
262
                    dst[x] = max - pix;
263
                }
264
                dst += stride;
265
            }
266
        }
267
268
        switch (pred) {
269
        case LEFT:
270
            dst = (uint16_t *)p->data[i] + j * sheight * stride;
271
            s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
272
            dst += stride;
273
            if (interlaced) {
274
                s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
275
                dst += stride;
276
            }
277
            for (k = 1 + interlaced; k < height; k++) {
278
                s->llviddsp.add_left_pred_int16(dst, dst, max, width, dst[-fake_stride]);
279
                dst += stride;
280
            }
281
            break;
282
        case GRADIENT:
283
            dst = (uint16_t *)p->data[i] + j * sheight * stride;
284
            s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
285
            dst += stride;
286
            if (interlaced) {
287
                s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
288
                dst += stride;
289
            }
290
            for (k = 1 + interlaced; k < height; k++) {
291
                top = dst[-fake_stride];
292
                left = top + dst[0];
293
                dst[0] = left & max;
294
                for (x = 1; x < width; x++) {
295
                    top = dst[x - fake_stride];
296
                    lefttop = dst[x - (fake_stride + 1)];
297
                    left += top - lefttop + dst[x];
298
                    dst[x] = left & max;
299
                }
300
                dst += stride;
301
            }
302
            break;
303
        case MEDIAN:
304
            dst = (uint16_t *)p->data[i] + j * sheight * stride;
305
            s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
306
            dst += stride;
307
            if (interlaced) {
308
                s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
309
                dst += stride;
310
            }
311
            lefttop = left = dst[0];
312
            for (k = 1 + interlaced; k < height; k++) {
313
                magicyuv_median_pred16(dst, dst - fake_stride, dst, width, &left, &lefttop, max);
314
                lefttop = left = dst[0];
315
                dst += stride;
316
            }
317
            break;
318
        default:
319
            avpriv_request_sample(avctx, "Unknown prediction: %d", pred);
320
        }
321
    }
322
323
    if (s->decorrelate) {
324
        int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height);
325
        int width = avctx->coded_width;
326
        uint16_t *r = (uint16_t *)p->data[0] + j * s->slice_height * p->linesize[0] / 2;
327
        uint16_t *g = (uint16_t *)p->data[1] + j * s->slice_height * p->linesize[1] / 2;
328
        uint16_t *b = (uint16_t *)p->data[2] + j * s->slice_height * p->linesize[2] / 2;
329
330
        for (i = 0; i < height; i++) {
331
            for (k = 0; k < width; k++) {
332
                b[k] = (b[k] + g[k]) & max;
333
                r[k] = (r[k] + g[k]) & max;
334
            }
335
            b += p->linesize[0] / 2;
336
            g += p->linesize[1] / 2;
337
            r += p->linesize[2] / 2;
338
        }
339
    }
340
341
    return 0;
342
}
343
344
126
static int magy_decode_slice(AVCodecContext *avctx, void *tdata,
345
                             int j, int threadnr)
346
{
347
126
    MagicYUVContext *s = avctx->priv_data;
348
126
    int interlaced = s->interlaced;
349
126
    AVFrame *p = s->p;
350
    int i, k, x, min_width;
351
    GetBitContext gb;
352
    uint8_t *dst;
353
354
504
    for (i = 0; i < s->planes; i++) {
355
        int left, lefttop, top;
356
378
        int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]);
357
378
        int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]);
358
378
        int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]);
359
378
        ptrdiff_t fake_stride = p->linesize[i] * (1 + interlaced);
360
378
        ptrdiff_t stride = p->linesize[i];
361
        int flags, pred;
362
378
        int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start,
363
378
                                 s->slices[i][j].size);
364
365
378
        if (ret < 0)
366
            return ret;
367
368
378
        flags = get_bits(&gb, 8);
369
378
        pred  = get_bits(&gb, 8);
370
371
378
        dst = p->data[i] + j * sheight * stride;
372
378
        if (flags & 1) {
373
            if (get_bits_left(&gb) < 8* width * height)
374
                return AVERROR_INVALIDDATA;
375
            for (k = 0; k < height; k++) {
376
                for (x = 0; x < width; x++)
377
                    dst[x] = get_bits(&gb, 8);
378
379
                dst += stride;
380
            }
381
        } else {
382
9658
            for (k = 0; k < height; k++) {
383
1794752
                for (x = 0; x < width; x++) {
384
                    int pix;
385
1785472
                    if (get_bits_left(&gb) <= 0)
386
                        return AVERROR_INVALIDDATA;
387
388
1785472
                    pix = get_vlc2(&gb, s->vlc[i].table, s->vlc[i].bits, 3);
389
1785472
                    if (pix < 0)
390
                        return AVERROR_INVALIDDATA;
391
392
1785472
                    dst[x] = 255 - pix;
393
                }
394
9280
                dst += stride;
395
            }
396
        }
397
398

378
        switch (pred) {
399
126
        case LEFT:
400
126
            dst = p->data[i] + j * sheight * stride;
401
126
            s->llviddsp.add_left_pred(dst, dst, width, 0);
402
126
            dst += stride;
403
126
            if (interlaced) {
404
72
                s->llviddsp.add_left_pred(dst, dst, width, 0);
405
72
                dst += stride;
406
            }
407
3176
            for (k = 1 + interlaced; k < height; k++) {
408
3050
                s->llviddsp.add_left_pred(dst, dst, width, dst[-fake_stride]);
409
3050
                dst += stride;
410
            }
411
126
            break;
412
90
        case GRADIENT:
413
90
            dst = p->data[i] + j * sheight * stride;
414
90
            s->llviddsp.add_left_pred(dst, dst, width, 0);
415
90
            dst += stride;
416
90
            if (interlaced) {
417
18
                s->llviddsp.add_left_pred(dst, dst, width, 0);
418
18
                dst += stride;
419
            }
420
90
            min_width = FFMIN(width, 32);
421
2302
            for (k = 1 + interlaced; k < height; k++) {
422
2212
                top = dst[-fake_stride];
423
2212
                left = top + dst[0];
424
2212
                dst[0] = left;
425
70784
                for (x = 1; x < min_width; x++) { /* dsp need aligned 32 */
426
68572
                    top = dst[x - fake_stride];
427
68572
                    lefttop = dst[x - (fake_stride + 1)];
428
68572
                    left += top - lefttop + dst[x];
429
68572
                    dst[x] = left;
430
                }
431
2212
                if (width > 32)
432
2212
                    s->llviddsp.add_gradient_pred(dst + 32, fake_stride, width - 32);
433
2212
                dst += stride;
434
            }
435
90
            break;
436
162
        case MEDIAN:
437
162
            dst = p->data[i] + j * sheight * stride;
438
162
            s->llviddsp.add_left_pred(dst, dst, width, 0);
439
162
            dst += stride;
440
162
            if (interlaced) {
441
54
                s->llviddsp.add_left_pred(dst, dst, width, 0);
442
54
                dst += stride;
443
            }
444
162
            lefttop = left = dst[0];
445
3658
            for (k = 1 + interlaced; k < height; k++) {
446
3496
                s->llviddsp.add_median_pred(dst, dst - fake_stride,
447
                                             dst, width, &left, &lefttop);
448
3496
                lefttop = left = dst[0];
449
3496
                dst += stride;
450
            }
451
162
            break;
452
        default:
453
            avpriv_request_sample(avctx, "Unknown prediction: %d", pred);
454
        }
455
    }
456
457
126
    if (s->decorrelate) {
458
36
        int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height);
459
36
        int width = avctx->coded_width;
460
36
        uint8_t *b = p->data[0] + j * s->slice_height * p->linesize[0];
461
36
        uint8_t *g = p->data[1] + j * s->slice_height * p->linesize[1];
462
36
        uint8_t *r = p->data[2] + j * s->slice_height * p->linesize[2];
463
464
964
        for (i = 0; i < height; i++) {
465
928
            s->llviddsp.add_bytes(b, g, width);
466
928
            s->llviddsp.add_bytes(r, g, width);
467
928
            b += p->linesize[0];
468
928
            g += p->linesize[1];
469
928
            r += p->linesize[2];
470
        }
471
    }
472
473
126
    return 0;
474
}
475
476
14
static int build_huffman(AVCodecContext *avctx, GetBitContext *gbit, int max)
477
{
478
14
    MagicYUVContext *s = avctx->priv_data;
479
14
    int i = 0, j = 0, k;
480
481
14
    memset(s->len, 0, sizeof(s->len));
482
1036
    while (get_bits_left(gbit) >= 8) {
483
1036
        int b = get_bits(gbit, 1);
484
1036
        int x = get_bits(gbit, 7);
485
1036
        int l = get_bitsz(gbit, b * 8) + 1;
486
487
11788
        for (k = 0; k < l; k++)
488
10752
            if (j + k < max)
489
10752
                s->len[i][j + k] = x;
490
491
1036
        j += l;
492
1036
        if (j == max) {
493
42
            j = 0;
494
42
            if (s->huff_build(&s->vlc[i], s->len[i])) {
495
                av_log(avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n");
496
                return AVERROR_INVALIDDATA;
497
            }
498
42
            i++;
499
42
            if (i == s->planes) {
500
14
                break;
501
            }
502
994
        } else if (j > max) {
503
            av_log(avctx, AV_LOG_ERROR, "Invalid Huffman codes\n");
504
            return AVERROR_INVALIDDATA;
505
        }
506
    }
507
508
14
    if (i != s->planes) {
509
        av_log(avctx, AV_LOG_ERROR, "Huffman tables too short\n");
510
        return AVERROR_INVALIDDATA;
511
    }
512
513
14
    return 0;
514
}
515
516
14
static int magy_decode_frame(AVCodecContext *avctx, void *data,
517
                             int *got_frame, AVPacket *avpkt)
518
{
519
14
    MagicYUVContext *s = avctx->priv_data;
520
14
    ThreadFrame frame = { .f = data };
521
14
    AVFrame *p = data;
522
    GetByteContext gbyte;
523
    GetBitContext gbit;
524
    uint32_t first_offset, offset, next_offset, header_size, slice_width;
525
    int width, height, format, version, table_size;
526
    int ret, i, j;
527
528
14
    bytestream2_init(&gbyte, avpkt->data, avpkt->size);
529
14
    if (bytestream2_get_le32(&gbyte) != MKTAG('M', 'A', 'G', 'Y'))
530
        return AVERROR_INVALIDDATA;
531
532
14
    header_size = bytestream2_get_le32(&gbyte);
533

14
    if (header_size < 32 || header_size >= avpkt->size) {
534
        av_log(avctx, AV_LOG_ERROR,
535
               "header or packet too small %"PRIu32"\n", header_size);
536
        return AVERROR_INVALIDDATA;
537
    }
538
539
14
    version = bytestream2_get_byte(&gbyte);
540
14
    if (version != 7) {
541
        avpriv_request_sample(avctx, "Version %d", version);
542
        return AVERROR_PATCHWELCOME;
543
    }
544
545
14
    s->hshift[1] =
546
14
    s->vshift[1] =
547
14
    s->hshift[2] =
548
14
    s->vshift[2] = 0;
549
14
    s->decorrelate = 0;
550
14
    s->bps = 8;
551
552
14
    format = bytestream2_get_byte(&gbyte);
553



14
    switch (format) {
554
2
    case 0x65:
555
2
        avctx->pix_fmt = AV_PIX_FMT_GBRP;
556
2
        s->decorrelate = 1;
557
2
        break;
558
2
    case 0x66:
559
2
        avctx->pix_fmt = AV_PIX_FMT_GBRAP;
560
2
        s->decorrelate = 1;
561
2
        break;
562
2
    case 0x67:
563
2
        avctx->pix_fmt = AV_PIX_FMT_YUV444P;
564
2
        break;
565
2
    case 0x68:
566
2
        avctx->pix_fmt = AV_PIX_FMT_YUV422P;
567
2
        s->hshift[1] =
568
2
        s->hshift[2] = 1;
569
2
        break;
570
2
    case 0x69:
571
2
        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
572
2
        s->hshift[1] =
573
2
        s->vshift[1] =
574
2
        s->hshift[2] =
575
2
        s->vshift[2] = 1;
576
2
        break;
577
2
    case 0x6a:
578
2
        avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
579
2
        break;
580
2
    case 0x6b:
581
2
        avctx->pix_fmt = AV_PIX_FMT_GRAY8;
582
2
        break;
583
    case 0x6c:
584
        avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
585
        s->hshift[1] =
586
        s->hshift[2] = 1;
587
        s->bps = 10;
588
        break;
589
    case 0x76:
590
        avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
591
        s->bps = 10;
592
        break;
593
    case 0x6d:
594
        avctx->pix_fmt = AV_PIX_FMT_GBRP10;
595
        s->decorrelate = 1;
596
        s->bps = 10;
597
        break;
598
    case 0x6e:
599
        avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
600
        s->decorrelate = 1;
601
        s->bps = 10;
602
        break;
603
    case 0x6f:
604
        avctx->pix_fmt = AV_PIX_FMT_GBRP12;
605
        s->decorrelate = 1;
606
        s->bps = 12;
607
        break;
608
    case 0x70:
609
        avctx->pix_fmt = AV_PIX_FMT_GBRAP12;
610
        s->decorrelate = 1;
611
        s->bps = 12;
612
        break;
613
    case 0x73:
614
        avctx->pix_fmt = AV_PIX_FMT_GRAY10;
615
        s->bps = 10;
616
        break;
617
    default:
618
        avpriv_request_sample(avctx, "Format 0x%X", format);
619
        return AVERROR_PATCHWELCOME;
620
    }
621
14
    s->max = 1 << s->bps;
622
14
    s->magy_decode_slice = s->bps == 8 ? magy_decode_slice : magy_decode_slice10;
623
14
    if ( s->bps == 8)
624
14
        s->huff_build = huff_build;
625
    else
626
        s->huff_build = s->bps == 10 ? huff_build10 : huff_build12;
627
14
    s->planes = av_pix_fmt_count_planes(avctx->pix_fmt);
628
629
14
    bytestream2_skip(&gbyte, 1);
630
14
    s->color_matrix = bytestream2_get_byte(&gbyte);
631
14
    s->flags        = bytestream2_get_byte(&gbyte);
632
14
    s->interlaced   = !!(s->flags & 2);
633
14
    bytestream2_skip(&gbyte, 3);
634
635
14
    width  = bytestream2_get_le32(&gbyte);
636
14
    height = bytestream2_get_le32(&gbyte);
637
14
    ret = ff_set_dimensions(avctx, width, height);
638
14
    if (ret < 0)
639
        return ret;
640
641
14
    slice_width = bytestream2_get_le32(&gbyte);
642
14
    if (slice_width != avctx->coded_width) {
643
        avpriv_request_sample(avctx, "Slice width %"PRIu32, slice_width);
644
        return AVERROR_PATCHWELCOME;
645
    }
646
14
    s->slice_height = bytestream2_get_le32(&gbyte);
647

14
    if (s->slice_height <= 0 || s->slice_height > INT_MAX - avctx->coded_height) {
648
        av_log(avctx, AV_LOG_ERROR,
649
               "invalid slice height: %d\n", s->slice_height);
650
        return AVERROR_INVALIDDATA;
651
    }
652
653
14
    bytestream2_skip(&gbyte, 4);
654
655
14
    s->nb_slices = (avctx->coded_height + s->slice_height - 1) / s->slice_height;
656
14
    if (s->nb_slices > INT_MAX / sizeof(Slice)) {
657
        av_log(avctx, AV_LOG_ERROR,
658
               "invalid number of slices: %d\n", s->nb_slices);
659
        return AVERROR_INVALIDDATA;
660
    }
661
662
56
    for (i = 0; i < s->planes; i++) {
663
42
        av_fast_malloc(&s->slices[i], &s->slices_size[i], s->nb_slices * sizeof(Slice));
664
42
        if (!s->slices[i])
665
            return AVERROR(ENOMEM);
666
667
42
        offset = bytestream2_get_le32(&gbyte);
668
42
        if (offset >= avpkt->size - header_size)
669
            return AVERROR_INVALIDDATA;
670
671
42
        if (i == 0)
672
14
            first_offset = offset;
673
674
378
        for (j = 0; j < s->nb_slices - 1; j++) {
675
336
            s->slices[i][j].start = offset + header_size;
676
677
336
            next_offset = bytestream2_get_le32(&gbyte);
678

336
            if (next_offset <= offset || next_offset >= avpkt->size - header_size)
679
                return AVERROR_INVALIDDATA;
680
681
336
            s->slices[i][j].size = next_offset - offset;
682
336
            offset = next_offset;
683
        }
684
685
42
        s->slices[i][j].start = offset + header_size;
686
42
        s->slices[i][j].size  = avpkt->size - s->slices[i][j].start;
687
    }
688
689
14
    if (bytestream2_get_byte(&gbyte) != s->planes)
690
        return AVERROR_INVALIDDATA;
691
692
14
    bytestream2_skip(&gbyte, s->nb_slices * s->planes);
693
694
14
    table_size = header_size + first_offset - bytestream2_tell(&gbyte);
695
14
    if (table_size < 2)
696
        return AVERROR_INVALIDDATA;
697
698
14
    ret = init_get_bits8(&gbit, avpkt->data + bytestream2_tell(&gbyte), table_size);
699
14
    if (ret < 0)
700
        return ret;
701
702
14
    ret = build_huffman(avctx, &gbit, s->max);
703
14
    if (ret < 0)
704
        return ret;
705
706
14
    p->pict_type = AV_PICTURE_TYPE_I;
707
14
    p->key_frame = 1;
708
709
14
    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
710
        return ret;
711
712
14
    s->buf = avpkt->data;
713
14
    s->p = p;
714
14
    avctx->execute2(avctx, s->magy_decode_slice, NULL, NULL, s->nb_slices);
715
716
14
    if (avctx->pix_fmt == AV_PIX_FMT_GBRP   ||
717
12
        avctx->pix_fmt == AV_PIX_FMT_GBRAP  ||
718
10
        avctx->pix_fmt == AV_PIX_FMT_GBRP10 ||
719
10
        avctx->pix_fmt == AV_PIX_FMT_GBRAP10||
720
10
        avctx->pix_fmt == AV_PIX_FMT_GBRAP12||
721
10
        avctx->pix_fmt == AV_PIX_FMT_GBRP12) {
722
4
        FFSWAP(uint8_t*, p->data[0], p->data[1]);
723
4
        FFSWAP(int, p->linesize[0], p->linesize[1]);
724
    } else {
725
10
        switch (s->color_matrix) {
726
        case 1:
727
            p->colorspace = AVCOL_SPC_BT470BG;
728
            break;
729
10
        case 2:
730
10
            p->colorspace = AVCOL_SPC_BT709;
731
10
            break;
732
        }
733
10
        p->color_range = (s->flags & 4) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
734
    }
735
736
14
    *got_frame = 1;
737
738
14
    return avpkt->size;
739
}
740
741
#if HAVE_THREADS
742
static int magy_init_thread_copy(AVCodecContext *avctx)
743
{
744
    MagicYUVContext *s = avctx->priv_data;
745
    int i;
746
747
    for (i = 0; i < FF_ARRAY_ELEMS(s->slices); i++) {
748
        s->slices[i] = NULL;
749
        s->slices_size[i] = 0;
750
    }
751
752
    return 0;
753
}
754
#endif
755
756
14
static av_cold int magy_decode_init(AVCodecContext *avctx)
757
{
758
14
    MagicYUVContext *s = avctx->priv_data;
759
14
    ff_llviddsp_init(&s->llviddsp);
760
14
    return 0;
761
}
762
763
14
static av_cold int magy_decode_end(AVCodecContext *avctx)
764
{
765
14
    MagicYUVContext * const s = avctx->priv_data;
766
    int i;
767
768
70
    for (i = 0; i < FF_ARRAY_ELEMS(s->slices); i++) {
769
56
        av_freep(&s->slices[i]);
770
56
        s->slices_size[i] = 0;
771
56
        ff_free_vlc(&s->vlc[i]);
772
    }
773
774
14
    return 0;
775
}
776
777
AVCodec ff_magicyuv_decoder = {
778
    .name             = "magicyuv",
779
    .long_name        = NULL_IF_CONFIG_SMALL("MagicYUV video"),
780
    .type             = AVMEDIA_TYPE_VIDEO,
781
    .id               = AV_CODEC_ID_MAGICYUV,
782
    .priv_data_size   = sizeof(MagicYUVContext),
783
    .init             = magy_decode_init,
784
    .init_thread_copy = ONLY_IF_THREADS_ENABLED(magy_init_thread_copy),
785
    .close            = magy_decode_end,
786
    .decode           = magy_decode_frame,
787
    .capabilities     = AV_CODEC_CAP_DR1 |
788
                        AV_CODEC_CAP_FRAME_THREADS |
789
                        AV_CODEC_CAP_SLICE_THREADS,
790
    .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE,
791
};