GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/magicyuv.c Lines: 241 426 56.6 %
Date: 2020-09-21 17:35:45 Branches: 140 240 58.3 %

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
#define CACHED_BITSTREAM_READER !ARCH_X86_32
26
27
#include "libavutil/pixdesc.h"
28
#include "libavutil/qsort.h"
29
30
#include "avcodec.h"
31
#include "bytestream.h"
32
#include "get_bits.h"
33
#include "huffyuvdsp.h"
34
#include "internal.h"
35
#include "lossless_videodsp.h"
36
#include "thread.h"
37
38
typedef struct Slice {
39
    uint32_t start;
40
    uint32_t size;
41
} Slice;
42
43
typedef enum Prediction {
44
    LEFT = 1,
45
    GRADIENT,
46
    MEDIAN,
47
} Prediction;
48
49
typedef struct HuffEntry {
50
    uint16_t sym;
51
    uint8_t  len;
52
    uint32_t code;
53
} HuffEntry;
54
55
typedef struct MagicYUVContext {
56
    AVFrame          *p;
57
    int               max;
58
    int               bps;
59
    int               slice_height;
60
    int               nb_slices;
61
    int               planes;         // number of encoded planes in bitstream
62
    int               decorrelate;    // postprocessing work
63
    int               color_matrix;   // video color matrix
64
    int               flags;
65
    int               interlaced;     // video is interlaced
66
    uint8_t          *buf;            // pointer to AVPacket->data
67
    int               hshift[4];
68
    int               vshift[4];
69
    Slice            *slices[4];      // slice bitstream positions for each plane
70
    unsigned int      slices_size[4]; // slice sizes for each plane
71
    VLC               vlc[4];         // VLC for each plane
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) * 4096 + bb->sym - aa->sym;
81
}
82
83
42
static int huff_build(HuffEntry he[], VLC *vlc, int nb_elems)
84
{
85
    uint32_t code;
86
    int i;
87
88











84296
    AV_QSORT(he, nb_elems, HuffEntry, huff_cmp_len);
89
90
42
    code = 1;
91
10794
    for (i = nb_elems - 1; i >= 0; i--) {
92
10752
        he[i].code = code >> (32 - he[i].len);
93
10752
        code += 0x80000000u >> (he[i].len - 1);
94
    }
95
96
42
    ff_free_vlc(vlc);
97
84
    return ff_init_vlc_sparse(vlc, FFMIN(he[nb_elems - 1].len, 12), nb_elems,
98
42
                              &he[0].len,  sizeof(he[0]), sizeof(he[0].len),
99
42
                              &he[0].code, sizeof(he[0]), sizeof(he[0].code),
100
42
                              &he[0].sym,  sizeof(he[0]), sizeof(he[0].sym),  0);
101
}
102
103
static void magicyuv_median_pred16(uint16_t *dst, const uint16_t *src1,
104
                                   const uint16_t *diff, intptr_t w,
105
                                   int *left, int *left_top, int max)
106
{
107
    int i;
108
    uint16_t l, lt;
109
110
    l  = *left;
111
    lt = *left_top;
112
113
    for (i = 0; i < w; i++) {
114
        l      = mid_pred(l, src1[i], (l + src1[i] - lt)) + diff[i];
115
        l     &= max;
116
        lt     = src1[i];
117
        dst[i] = l;
118
    }
119
120
    *left     = l;
121
    *left_top = lt;
122
}
123
124
static int magy_decode_slice10(AVCodecContext *avctx, void *tdata,
125
                               int j, int threadnr)
126
{
127
    MagicYUVContext *s = avctx->priv_data;
128
    int interlaced = s->interlaced;
129
    const int bps = s->bps;
130
    const int max = s->max - 1;
131
    AVFrame *p = s->p;
132
    int i, k, x;
133
    GetBitContext gb;
134
    uint16_t *dst;
135
136
    for (i = 0; i < s->planes; i++) {
137
        int left, lefttop, top;
138
        int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]);
139
        int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]);
140
        int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]);
141
        ptrdiff_t fake_stride = (p->linesize[i] / 2) * (1 + interlaced);
142
        ptrdiff_t stride = p->linesize[i] / 2;
143
        int flags, pred;
144
        int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start,
145
                                 s->slices[i][j].size);
146
147
        if (ret < 0)
148
            return ret;
149
150
        flags = get_bits(&gb, 8);
151
        pred  = get_bits(&gb, 8);
152
153
        dst = (uint16_t *)p->data[i] + j * sheight * stride;
154
        if (flags & 1) {
155
            if (get_bits_left(&gb) < bps * width * height)
156
                return AVERROR_INVALIDDATA;
157
            for (k = 0; k < height; k++) {
158
                for (x = 0; x < width; x++)
159
                    dst[x] = get_bits(&gb, bps);
160
161
                dst += stride;
162
            }
163
        } else {
164
            for (k = 0; k < height; k++) {
165
                for (x = 0; x < width; x++) {
166
                    int pix;
167
                    if (get_bits_left(&gb) <= 0)
168
                        return AVERROR_INVALIDDATA;
169
170
                    pix = get_vlc2(&gb, s->vlc[i].table, s->vlc[i].bits, 3);
171
                    if (pix < 0)
172
                        return AVERROR_INVALIDDATA;
173
174
                    dst[x] = pix;
175
                }
176
                dst += stride;
177
            }
178
        }
179
180
        switch (pred) {
181
        case LEFT:
182
            dst = (uint16_t *)p->data[i] + j * sheight * stride;
183
            s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
184
            dst += stride;
185
            if (interlaced) {
186
                s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
187
                dst += stride;
188
            }
189
            for (k = 1 + interlaced; k < height; k++) {
190
                s->llviddsp.add_left_pred_int16(dst, dst, max, width, dst[-fake_stride]);
191
                dst += stride;
192
            }
193
            break;
194
        case GRADIENT:
195
            dst = (uint16_t *)p->data[i] + j * sheight * stride;
196
            s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
197
            dst += stride;
198
            if (interlaced) {
199
                s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
200
                dst += stride;
201
            }
202
            for (k = 1 + interlaced; k < height; k++) {
203
                top = dst[-fake_stride];
204
                left = top + dst[0];
205
                dst[0] = left & max;
206
                for (x = 1; x < width; x++) {
207
                    top = dst[x - fake_stride];
208
                    lefttop = dst[x - (fake_stride + 1)];
209
                    left += top - lefttop + dst[x];
210
                    dst[x] = left & max;
211
                }
212
                dst += stride;
213
            }
214
            break;
215
        case MEDIAN:
216
            dst = (uint16_t *)p->data[i] + j * sheight * stride;
217
            s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
218
            dst += stride;
219
            if (interlaced) {
220
                s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
221
                dst += stride;
222
            }
223
            lefttop = left = dst[0];
224
            for (k = 1 + interlaced; k < height; k++) {
225
                magicyuv_median_pred16(dst, dst - fake_stride, dst, width, &left, &lefttop, max);
226
                lefttop = left = dst[0];
227
                dst += stride;
228
            }
229
            break;
230
        default:
231
            avpriv_request_sample(avctx, "Unknown prediction: %d", pred);
232
        }
233
    }
234
235
    if (s->decorrelate) {
236
        int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height);
237
        int width = avctx->coded_width;
238
        uint16_t *r = (uint16_t *)p->data[0] + j * s->slice_height * p->linesize[0] / 2;
239
        uint16_t *g = (uint16_t *)p->data[1] + j * s->slice_height * p->linesize[1] / 2;
240
        uint16_t *b = (uint16_t *)p->data[2] + j * s->slice_height * p->linesize[2] / 2;
241
242
        for (i = 0; i < height; i++) {
243
            for (k = 0; k < width; k++) {
244
                b[k] = (b[k] + g[k]) & max;
245
                r[k] = (r[k] + g[k]) & max;
246
            }
247
            b += p->linesize[0] / 2;
248
            g += p->linesize[1] / 2;
249
            r += p->linesize[2] / 2;
250
        }
251
    }
252
253
    return 0;
254
}
255
256
126
static int magy_decode_slice(AVCodecContext *avctx, void *tdata,
257
                             int j, int threadnr)
258
{
259
126
    MagicYUVContext *s = avctx->priv_data;
260
126
    int interlaced = s->interlaced;
261
126
    AVFrame *p = s->p;
262
    int i, k, x, min_width;
263
    GetBitContext gb;
264
    uint8_t *dst;
265
266
504
    for (i = 0; i < s->planes; i++) {
267
        int left, lefttop, top;
268
378
        int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]);
269
378
        int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]);
270
378
        int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]);
271
378
        ptrdiff_t fake_stride = p->linesize[i] * (1 + interlaced);
272
378
        ptrdiff_t stride = p->linesize[i];
273
        int flags, pred;
274
378
        int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start,
275
378
                                 s->slices[i][j].size);
276
277
378
        if (ret < 0)
278
            return ret;
279
280
378
        flags = get_bits(&gb, 8);
281
378
        pred  = get_bits(&gb, 8);
282
283
378
        dst = p->data[i] + j * sheight * stride;
284
378
        if (flags & 1) {
285
            if (get_bits_left(&gb) < 8* width * height)
286
                return AVERROR_INVALIDDATA;
287
            for (k = 0; k < height; k++) {
288
                for (x = 0; x < width; x++)
289
                    dst[x] = get_bits(&gb, 8);
290
291
                dst += stride;
292
            }
293
        } else {
294
9658
            for (k = 0; k < height; k++) {
295
1794752
                for (x = 0; x < width; x++) {
296
                    int pix;
297
1785472
                    if (get_bits_left(&gb) <= 0)
298
                        return AVERROR_INVALIDDATA;
299
300
1785472
                    pix = get_vlc2(&gb, s->vlc[i].table, s->vlc[i].bits, 3);
301
1785472
                    if (pix < 0)
302
                        return AVERROR_INVALIDDATA;
303
304
1785472
                    dst[x] = pix;
305
                }
306
9280
                dst += stride;
307
            }
308
        }
309
310

378
        switch (pred) {
311
126
        case LEFT:
312
126
            dst = p->data[i] + j * sheight * stride;
313
126
            s->llviddsp.add_left_pred(dst, dst, width, 0);
314
126
            dst += stride;
315
126
            if (interlaced) {
316
72
                s->llviddsp.add_left_pred(dst, dst, width, 0);
317
72
                dst += stride;
318
            }
319
3176
            for (k = 1 + interlaced; k < height; k++) {
320
3050
                s->llviddsp.add_left_pred(dst, dst, width, dst[-fake_stride]);
321
3050
                dst += stride;
322
            }
323
126
            break;
324
90
        case GRADIENT:
325
90
            dst = p->data[i] + j * sheight * stride;
326
90
            s->llviddsp.add_left_pred(dst, dst, width, 0);
327
90
            dst += stride;
328
90
            if (interlaced) {
329
18
                s->llviddsp.add_left_pred(dst, dst, width, 0);
330
18
                dst += stride;
331
            }
332
90
            min_width = FFMIN(width, 32);
333
2302
            for (k = 1 + interlaced; k < height; k++) {
334
2212
                top = dst[-fake_stride];
335
2212
                left = top + dst[0];
336
2212
                dst[0] = left;
337
70784
                for (x = 1; x < min_width; x++) { /* dsp need aligned 32 */
338
68572
                    top = dst[x - fake_stride];
339
68572
                    lefttop = dst[x - (fake_stride + 1)];
340
68572
                    left += top - lefttop + dst[x];
341
68572
                    dst[x] = left;
342
                }
343
2212
                if (width > 32)
344
2212
                    s->llviddsp.add_gradient_pred(dst + 32, fake_stride, width - 32);
345
2212
                dst += stride;
346
            }
347
90
            break;
348
162
        case MEDIAN:
349
162
            dst = p->data[i] + j * sheight * stride;
350
162
            s->llviddsp.add_left_pred(dst, dst, width, 0);
351
162
            dst += stride;
352
162
            if (interlaced) {
353
54
                s->llviddsp.add_left_pred(dst, dst, width, 0);
354
54
                dst += stride;
355
            }
356
162
            lefttop = left = dst[0];
357
3658
            for (k = 1 + interlaced; k < height; k++) {
358
3496
                s->llviddsp.add_median_pred(dst, dst - fake_stride,
359
                                             dst, width, &left, &lefttop);
360
3496
                lefttop = left = dst[0];
361
3496
                dst += stride;
362
            }
363
162
            break;
364
        default:
365
            avpriv_request_sample(avctx, "Unknown prediction: %d", pred);
366
        }
367
    }
368
369
126
    if (s->decorrelate) {
370
36
        int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height);
371
36
        int width = avctx->coded_width;
372
36
        uint8_t *b = p->data[0] + j * s->slice_height * p->linesize[0];
373
36
        uint8_t *g = p->data[1] + j * s->slice_height * p->linesize[1];
374
36
        uint8_t *r = p->data[2] + j * s->slice_height * p->linesize[2];
375
376
964
        for (i = 0; i < height; i++) {
377
928
            s->llviddsp.add_bytes(b, g, width);
378
928
            s->llviddsp.add_bytes(r, g, width);
379
928
            b += p->linesize[0];
380
928
            g += p->linesize[1];
381
928
            r += p->linesize[2];
382
        }
383
    }
384
385
126
    return 0;
386
}
387
388
14
static int build_huffman(AVCodecContext *avctx, GetBitContext *gbit, int max)
389
{
390
14
    MagicYUVContext *s = avctx->priv_data;
391
    HuffEntry he[4096];
392
14
    int i = 0, j = 0, k;
393
394
1036
    while (get_bits_left(gbit) >= 8) {
395
1036
        int b = get_bits(gbit, 1);
396
1036
        int x = get_bits(gbit, 7);
397
1036
        int l = get_bitsz(gbit, b * 8) + 1;
398
399
1036
        k = j + l;
400

1036
        if (k > max || x == 0 || x > 32) {
401
            av_log(avctx, AV_LOG_ERROR, "Invalid Huffman codes\n");
402
            return AVERROR_INVALIDDATA;
403
        }
404
405
11788
        for (; j < k; j++) {
406
10752
            he[j].sym = j;
407
10752
            he[j].len = x;
408
        }
409
410
1036
        if (j == max) {
411
42
            j = 0;
412
42
            if (huff_build(he, &s->vlc[i], max)) {
413
                av_log(avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n");
414
                return AVERROR_INVALIDDATA;
415
            }
416
42
            i++;
417
42
            if (i == s->planes) {
418
14
                break;
419
            }
420
        }
421
    }
422
423
14
    if (i != s->planes) {
424
        av_log(avctx, AV_LOG_ERROR, "Huffman tables too short\n");
425
        return AVERROR_INVALIDDATA;
426
    }
427
428
14
    return 0;
429
}
430
431
14
static int magy_decode_frame(AVCodecContext *avctx, void *data,
432
                             int *got_frame, AVPacket *avpkt)
433
{
434
14
    MagicYUVContext *s = avctx->priv_data;
435
14
    ThreadFrame frame = { .f = data };
436
14
    AVFrame *p = data;
437
    GetByteContext gbyte;
438
    GetBitContext gbit;
439
    uint32_t first_offset, offset, next_offset, header_size, slice_width;
440
    int width, height, format, version, table_size;
441
    int ret, i, j;
442
443
14
    bytestream2_init(&gbyte, avpkt->data, avpkt->size);
444
14
    if (bytestream2_get_le32(&gbyte) != MKTAG('M', 'A', 'G', 'Y'))
445
        return AVERROR_INVALIDDATA;
446
447
14
    header_size = bytestream2_get_le32(&gbyte);
448

14
    if (header_size < 32 || header_size >= avpkt->size) {
449
        av_log(avctx, AV_LOG_ERROR,
450
               "header or packet too small %"PRIu32"\n", header_size);
451
        return AVERROR_INVALIDDATA;
452
    }
453
454
14
    version = bytestream2_get_byte(&gbyte);
455
14
    if (version != 7) {
456
        avpriv_request_sample(avctx, "Version %d", version);
457
        return AVERROR_PATCHWELCOME;
458
    }
459
460
14
    s->hshift[1] =
461
14
    s->vshift[1] =
462
14
    s->hshift[2] =
463
14
    s->vshift[2] = 0;
464
14
    s->decorrelate = 0;
465
14
    s->bps = 8;
466
467
14
    format = bytestream2_get_byte(&gbyte);
468



14
    switch (format) {
469
2
    case 0x65:
470
2
        avctx->pix_fmt = AV_PIX_FMT_GBRP;
471
2
        s->decorrelate = 1;
472
2
        break;
473
2
    case 0x66:
474
2
        avctx->pix_fmt = AV_PIX_FMT_GBRAP;
475
2
        s->decorrelate = 1;
476
2
        break;
477
2
    case 0x67:
478
2
        avctx->pix_fmt = AV_PIX_FMT_YUV444P;
479
2
        break;
480
2
    case 0x68:
481
2
        avctx->pix_fmt = AV_PIX_FMT_YUV422P;
482
2
        s->hshift[1] =
483
2
        s->hshift[2] = 1;
484
2
        break;
485
2
    case 0x69:
486
2
        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
487
2
        s->hshift[1] =
488
2
        s->vshift[1] =
489
2
        s->hshift[2] =
490
2
        s->vshift[2] = 1;
491
2
        break;
492
2
    case 0x6a:
493
2
        avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
494
2
        break;
495
2
    case 0x6b:
496
2
        avctx->pix_fmt = AV_PIX_FMT_GRAY8;
497
2
        break;
498
    case 0x6c:
499
        avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
500
        s->hshift[1] =
501
        s->hshift[2] = 1;
502
        s->bps = 10;
503
        break;
504
    case 0x76:
505
        avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
506
        s->bps = 10;
507
        break;
508
    case 0x6d:
509
        avctx->pix_fmt = AV_PIX_FMT_GBRP10;
510
        s->decorrelate = 1;
511
        s->bps = 10;
512
        break;
513
    case 0x6e:
514
        avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
515
        s->decorrelate = 1;
516
        s->bps = 10;
517
        break;
518
    case 0x6f:
519
        avctx->pix_fmt = AV_PIX_FMT_GBRP12;
520
        s->decorrelate = 1;
521
        s->bps = 12;
522
        break;
523
    case 0x70:
524
        avctx->pix_fmt = AV_PIX_FMT_GBRAP12;
525
        s->decorrelate = 1;
526
        s->bps = 12;
527
        break;
528
    case 0x73:
529
        avctx->pix_fmt = AV_PIX_FMT_GRAY10;
530
        s->bps = 10;
531
        break;
532
    default:
533
        avpriv_request_sample(avctx, "Format 0x%X", format);
534
        return AVERROR_PATCHWELCOME;
535
    }
536
14
    s->max = 1 << s->bps;
537
14
    s->magy_decode_slice = s->bps == 8 ? magy_decode_slice : magy_decode_slice10;
538
14
    s->planes = av_pix_fmt_count_planes(avctx->pix_fmt);
539
540
14
    bytestream2_skip(&gbyte, 1);
541
14
    s->color_matrix = bytestream2_get_byte(&gbyte);
542
14
    s->flags        = bytestream2_get_byte(&gbyte);
543
14
    s->interlaced   = !!(s->flags & 2);
544
14
    bytestream2_skip(&gbyte, 3);
545
546
14
    width  = bytestream2_get_le32(&gbyte);
547
14
    height = bytestream2_get_le32(&gbyte);
548
14
    ret = ff_set_dimensions(avctx, width, height);
549
14
    if (ret < 0)
550
        return ret;
551
552
14
    slice_width = bytestream2_get_le32(&gbyte);
553
14
    if (slice_width != avctx->coded_width) {
554
        avpriv_request_sample(avctx, "Slice width %"PRIu32, slice_width);
555
        return AVERROR_PATCHWELCOME;
556
    }
557
14
    s->slice_height = bytestream2_get_le32(&gbyte);
558

14
    if (s->slice_height <= 0 || s->slice_height > INT_MAX - avctx->coded_height) {
559
        av_log(avctx, AV_LOG_ERROR,
560
               "invalid slice height: %d\n", s->slice_height);
561
        return AVERROR_INVALIDDATA;
562
    }
563
564
14
    bytestream2_skip(&gbyte, 4);
565
566
14
    s->nb_slices = (avctx->coded_height + s->slice_height - 1) / s->slice_height;
567
14
    if (s->nb_slices > INT_MAX / sizeof(Slice)) {
568
        av_log(avctx, AV_LOG_ERROR,
569
               "invalid number of slices: %d\n", s->nb_slices);
570
        return AVERROR_INVALIDDATA;
571
    }
572
573
14
    if (s->interlaced) {
574
6
        if ((s->slice_height >> s->vshift[1]) < 2) {
575
            av_log(avctx, AV_LOG_ERROR, "impossible slice height\n");
576
            return AVERROR_INVALIDDATA;
577
        }
578

6
        if ((avctx->coded_height % s->slice_height) && ((avctx->coded_height % s->slice_height) >> s->vshift[1]) < 2) {
579
            av_log(avctx, AV_LOG_ERROR, "impossible height\n");
580
            return AVERROR_INVALIDDATA;
581
        }
582
    }
583
584
56
    for (i = 0; i < s->planes; i++) {
585
42
        av_fast_malloc(&s->slices[i], &s->slices_size[i], s->nb_slices * sizeof(Slice));
586
42
        if (!s->slices[i])
587
            return AVERROR(ENOMEM);
588
589
42
        offset = bytestream2_get_le32(&gbyte);
590
42
        if (offset >= avpkt->size - header_size)
591
            return AVERROR_INVALIDDATA;
592
593
42
        if (i == 0)
594
14
            first_offset = offset;
595
596
378
        for (j = 0; j < s->nb_slices - 1; j++) {
597
336
            s->slices[i][j].start = offset + header_size;
598
599
336
            next_offset = bytestream2_get_le32(&gbyte);
600

336
            if (next_offset <= offset || next_offset >= avpkt->size - header_size)
601
                return AVERROR_INVALIDDATA;
602
603
336
            s->slices[i][j].size = next_offset - offset;
604
336
            offset = next_offset;
605
        }
606
607
42
        s->slices[i][j].start = offset + header_size;
608
42
        s->slices[i][j].size  = avpkt->size - s->slices[i][j].start;
609
    }
610
611
14
    if (bytestream2_get_byte(&gbyte) != s->planes)
612
        return AVERROR_INVALIDDATA;
613
614
14
    bytestream2_skip(&gbyte, s->nb_slices * s->planes);
615
616
14
    table_size = header_size + first_offset - bytestream2_tell(&gbyte);
617
14
    if (table_size < 2)
618
        return AVERROR_INVALIDDATA;
619
620
14
    ret = init_get_bits8(&gbit, avpkt->data + bytestream2_tell(&gbyte), table_size);
621
14
    if (ret < 0)
622
        return ret;
623
624
14
    ret = build_huffman(avctx, &gbit, s->max);
625
14
    if (ret < 0)
626
        return ret;
627
628
14
    p->pict_type = AV_PICTURE_TYPE_I;
629
14
    p->key_frame = 1;
630
631
14
    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
632
        return ret;
633
634
14
    s->buf = avpkt->data;
635
14
    s->p = p;
636
14
    avctx->execute2(avctx, s->magy_decode_slice, NULL, NULL, s->nb_slices);
637
638
14
    if (avctx->pix_fmt == AV_PIX_FMT_GBRP   ||
639
12
        avctx->pix_fmt == AV_PIX_FMT_GBRAP  ||
640
10
        avctx->pix_fmt == AV_PIX_FMT_GBRP10 ||
641
10
        avctx->pix_fmt == AV_PIX_FMT_GBRAP10||
642
10
        avctx->pix_fmt == AV_PIX_FMT_GBRAP12||
643
10
        avctx->pix_fmt == AV_PIX_FMT_GBRP12) {
644
4
        FFSWAP(uint8_t*, p->data[0], p->data[1]);
645
4
        FFSWAP(int, p->linesize[0], p->linesize[1]);
646
    } else {
647
10
        switch (s->color_matrix) {
648
        case 1:
649
            p->colorspace = AVCOL_SPC_BT470BG;
650
            break;
651
10
        case 2:
652
10
            p->colorspace = AVCOL_SPC_BT709;
653
10
            break;
654
        }
655
10
        p->color_range = (s->flags & 4) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
656
    }
657
658
14
    *got_frame = 1;
659
660
14
    return avpkt->size;
661
}
662
663
14
static av_cold int magy_decode_init(AVCodecContext *avctx)
664
{
665
14
    MagicYUVContext *s = avctx->priv_data;
666
14
    ff_llviddsp_init(&s->llviddsp);
667
14
    return 0;
668
}
669
670
14
static av_cold int magy_decode_end(AVCodecContext *avctx)
671
{
672
14
    MagicYUVContext * const s = avctx->priv_data;
673
    int i;
674
675
70
    for (i = 0; i < FF_ARRAY_ELEMS(s->slices); i++) {
676
56
        av_freep(&s->slices[i]);
677
56
        s->slices_size[i] = 0;
678
56
        ff_free_vlc(&s->vlc[i]);
679
    }
680
681
14
    return 0;
682
}
683
684
AVCodec ff_magicyuv_decoder = {
685
    .name             = "magicyuv",
686
    .long_name        = NULL_IF_CONFIG_SMALL("MagicYUV video"),
687
    .type             = AVMEDIA_TYPE_VIDEO,
688
    .id               = AV_CODEC_ID_MAGICYUV,
689
    .priv_data_size   = sizeof(MagicYUVContext),
690
    .init             = magy_decode_init,
691
    .close            = magy_decode_end,
692
    .decode           = magy_decode_frame,
693
    .capabilities     = AV_CODEC_CAP_DR1 |
694
                        AV_CODEC_CAP_FRAME_THREADS |
695
                        AV_CODEC_CAP_SLICE_THREADS,
696
    .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE,
697
};