Coverage Report

Created: 2026-04-01 07:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/magicyuv.c
Line
Count
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
384M
#define CACHED_BITSTREAM_READER !ARCH_X86_32
26
27
#include "libavutil/mem.h"
28
#include "libavutil/pixdesc.h"
29
30
#include "avcodec.h"
31
#include "bytestream.h"
32
#include "codec_internal.h"
33
#include "decode.h"
34
#include "get_bits.h"
35
#include "lossless_videodsp.h"
36
#include "thread.h"
37
38
#define VLC_BITS 12
39
40
typedef struct Slice {
41
    uint32_t start;
42
    uint32_t size;
43
} Slice;
44
45
typedef enum Prediction {
46
    LEFT = 1,
47
    GRADIENT,
48
    MEDIAN,
49
} Prediction;
50
51
typedef struct HuffEntry {
52
    uint8_t  len;
53
    uint16_t sym;
54
} HuffEntry;
55
56
typedef struct MagicYUVContext {
57
    AVFrame          *p;
58
    int               max;
59
    int               bps;
60
    int               slice_height;
61
    int               nb_slices;
62
    int               planes;         // number of encoded planes in bitstream
63
    int               decorrelate;    // postprocessing work
64
    int               color_matrix;   // video color matrix
65
    int               flags;
66
    int               interlaced;     // video is interlaced
67
    const uint8_t    *buf;            // pointer to AVPacket->data
68
    int               hshift[4];
69
    int               vshift[4];
70
    Slice            *slices[4];      // slice bitstream positions for each plane
71
    unsigned int      slices_size[4]; // slice sizes for each plane
72
    VLC               vlc[4];         // VLC for each plane
73
    VLC_MULTI         multi[4];       // Buffer for joint VLC data
74
    int (*magy_decode_slice)(AVCodecContext *avctx, void *tdata,
75
                             int j, int threadnr);
76
    LLVidDSPContext   llviddsp;
77
    HuffEntry         he[1 << 14];
78
    uint8_t           len[1 << 14];
79
} MagicYUVContext;
80
81
static int huff_build(AVCodecContext *avctx,
82
                      const uint8_t len[], uint16_t codes_pos[33],
83
                      VLC *vlc, VLC_MULTI *multi, int nb_elems, void *logctx)
84
46.7k
{
85
46.7k
    MagicYUVContext *s = avctx->priv_data;
86
46.7k
    HuffEntry *he = s->he;
87
88
1.49M
    for (int i = 31; i > 0; i--)
89
1.44M
        codes_pos[i] += codes_pos[i + 1];
90
91
30.6M
    for (unsigned i = nb_elems; i-- > 0;)
92
30.5M
        he[--codes_pos[len[i]]] = (HuffEntry){ len[i], i };
93
94
46.7k
    ff_vlc_free(vlc);
95
46.7k
    ff_vlc_free_multi(multi);
96
46.7k
    return ff_vlc_init_multi_from_lengths(vlc, multi, FFMIN(he[0].len, VLC_BITS), nb_elems, nb_elems,
97
46.7k
                                    &he[0].len, sizeof(he[0]),
98
46.7k
                                    &he[0].sym, sizeof(he[0]), sizeof(he[0].sym),
99
46.7k
                                    0, 0, logctx);
100
46.7k
}
101
102
static void magicyuv_median_pred16(uint16_t *dst, const uint16_t *src1,
103
                                   const uint16_t *diff, intptr_t w,
104
                                   int *left, int *left_top, int max)
105
5.83M
{
106
5.83M
    int i;
107
5.83M
    uint16_t l, lt;
108
109
5.83M
    l  = *left;
110
5.83M
    lt = *left_top;
111
112
332M
    for (i = 0; i < w; i++) {
113
326M
        l      = mid_pred(l, src1[i], (l + src1[i] - lt)) + diff[i];
114
326M
        l     &= max;
115
326M
        lt     = src1[i];
116
326M
        dst[i] = l;
117
326M
    }
118
119
5.83M
    *left     = l;
120
5.83M
    *left_top = lt;
121
5.83M
}
122
123
191M
#define READ_PLANE(dst, plane, b, c) \
124
191M
{ \
125
191M
    x = 0; \
126
192M
    for (; CACHED_BITSTREAM_READER && x < width-c && get_bits_left(&gb) > 0;) {\
127
490k
        ret = get_vlc_multi(&gb, (uint8_t *)dst + x * b, multi, \
128
490k
                            vlc, vlc_bits, 3, b); \
129
490k
        if (ret <= 0) \
130
490k
            return AVERROR_INVALIDDATA; \
131
490k
        x += ret; \
132
489k
    } \
133
268M
    for (; x < width && get_bits_left(&gb) > 0; x++) \
134
191M
        dst[x] = get_vlc2(&gb, vlc, vlc_bits, 3); \
135
191M
    dst += stride; \
136
191M
}
137
138
static int magy_decode_slice10(AVCodecContext *avctx, void *tdata,
139
                               int j, int threadnr)
140
4.92k
{
141
4.92k
    const MagicYUVContext *s = avctx->priv_data;
142
4.92k
    int interlaced = s->interlaced;
143
4.92k
    const int bps = s->bps;
144
4.92k
    const int max = s->max - 1;
145
4.92k
    AVFrame *p = s->p;
146
4.92k
    int i, k, x;
147
4.92k
    GetBitContext gb;
148
4.92k
    uint16_t *dst;
149
150
13.7k
    for (i = 0; i < s->planes; i++) {
151
9.96k
        int left, lefttop, top;
152
9.96k
        int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]);
153
9.96k
        int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]);
154
9.96k
        int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]);
155
9.96k
        ptrdiff_t fake_stride = (p->linesize[i] / 2) * (1 + interlaced);
156
9.96k
        ptrdiff_t stride = p->linesize[i] / 2;
157
9.96k
        const VLC_MULTI_ELEM *const multi = s->multi[i].table;
158
9.96k
        const VLCElem *const vlc = s->vlc[i].table;
159
9.96k
        const int vlc_bits = s->vlc[i].bits;
160
9.96k
        int flags, pred;
161
9.96k
        int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start,
162
9.96k
                                 s->slices[i][j].size);
163
164
9.96k
        if (ret < 0)
165
0
            return ret;
166
167
9.96k
        flags = get_bits(&gb, 8);
168
9.96k
        pred  = get_bits(&gb, 8);
169
170
9.96k
        dst = (uint16_t *)p->data[i] + j * sheight * stride;
171
9.96k
        if (flags & 1) {
172
1.15k
            if (get_bits_left(&gb) < bps * width * height)
173
407
                return AVERROR_INVALIDDATA;
174
5.42k
            for (k = 0; k < height; k++) {
175
55.4k
                for (x = 0; x < width; x++)
176
50.7k
                    dst[x] = get_bits(&gb, bps);
177
178
4.67k
                dst += stride;
179
4.67k
            }
180
8.81k
        } else {
181
26.7M
            for (k = 0; k < height; k++)
182
26.7M
                READ_PLANE(dst, i, 2, 3)
183
8.81k
        }
184
185
8.87k
        switch (pred) {
186
2.76k
        case LEFT:
187
2.76k
            dst = (uint16_t *)p->data[i] + j * sheight * stride;
188
2.76k
            s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
189
2.76k
            dst += stride;
190
2.76k
            if (interlaced) {
191
711
                s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
192
711
                dst += stride;
193
711
            }
194
1.95M
            for (k = 1 + interlaced; k < height; k++) {
195
1.94M
                s->llviddsp.add_left_pred_int16(dst, dst, max, width, dst[-fake_stride]);
196
1.94M
                dst += stride;
197
1.94M
            }
198
2.76k
            break;
199
776
        case GRADIENT:
200
776
            dst = (uint16_t *)p->data[i] + j * sheight * stride;
201
776
            s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
202
776
            dst += stride;
203
776
            if (interlaced) {
204
240
                s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
205
240
                dst += stride;
206
240
            }
207
11.7M
            for (k = 1 + interlaced; k < height; k++) {
208
11.7M
                top = dst[-fake_stride];
209
11.7M
                left = top + dst[0];
210
11.7M
                dst[0] = left & max;
211
202M
                for (x = 1; x < width; x++) {
212
190M
                    top = dst[x - fake_stride];
213
190M
                    lefttop = dst[x - (fake_stride + 1)];
214
190M
                    left += top - lefttop + dst[x];
215
190M
                    dst[x] = left & max;
216
190M
                }
217
11.7M
                dst += stride;
218
11.7M
            }
219
776
            break;
220
771
        case MEDIAN:
221
771
            dst = (uint16_t *)p->data[i] + j * sheight * stride;
222
771
            s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
223
771
            dst += stride;
224
771
            if (interlaced) {
225
327
                s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0);
226
327
                dst += stride;
227
327
            }
228
771
            lefttop = left = dst[0];
229
5.83M
            for (k = 1 + interlaced; k < height; k++) {
230
5.83M
                magicyuv_median_pred16(dst, dst - fake_stride, dst, width, &left, &lefttop, max);
231
5.83M
                lefttop = left = dst[0];
232
5.83M
                dst += stride;
233
5.83M
            }
234
771
            break;
235
4.56k
        default:
236
4.56k
            avpriv_request_sample(avctx, "Unknown prediction: %d", pred);
237
8.87k
        }
238
8.87k
    }
239
240
3.83k
    if (s->decorrelate) {
241
1.21k
        int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height);
242
1.21k
        int width = avctx->coded_width;
243
1.21k
        uint16_t *r = (uint16_t *)p->data[0] + j * s->slice_height * p->linesize[0] / 2;
244
1.21k
        uint16_t *g = (uint16_t *)p->data[1] + j * s->slice_height * p->linesize[1] / 2;
245
1.21k
        uint16_t *b = (uint16_t *)p->data[2] + j * s->slice_height * p->linesize[2] / 2;
246
247
996k
        for (i = 0; i < height; i++) {
248
839M
            for (k = 0; k < width; k++) {
249
838M
                b[k] = (b[k] + g[k]) & max;
250
838M
                r[k] = (r[k] + g[k]) & max;
251
838M
            }
252
995k
            b += p->linesize[0] / 2;
253
995k
            g += p->linesize[1] / 2;
254
995k
            r += p->linesize[2] / 2;
255
995k
        }
256
1.21k
    }
257
258
3.83k
    return 0;
259
4.92k
}
260
261
static int magy_decode_slice(AVCodecContext *avctx, void *tdata,
262
                             int j, int threadnr)
263
15.9k
{
264
15.9k
    const MagicYUVContext *s = avctx->priv_data;
265
15.9k
    int interlaced = s->interlaced;
266
15.9k
    AVFrame *p = s->p;
267
15.9k
    int i, k, x, min_width;
268
15.9k
    GetBitContext gb;
269
15.9k
    uint8_t *dst;
270
271
42.2k
    for (i = 0; i < s->planes; i++) {
272
30.4k
        int left, lefttop, top;
273
30.4k
        int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]);
274
30.4k
        int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]);
275
30.4k
        int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]);
276
30.4k
        ptrdiff_t fake_stride = p->linesize[i] * (1 + interlaced);
277
30.4k
        ptrdiff_t stride = p->linesize[i];
278
30.4k
        const uint8_t *slice = s->buf + s->slices[i][j].start;
279
30.4k
        const VLC_MULTI_ELEM *const multi = s->multi[i].table;
280
30.4k
        const VLCElem *const vlc = s->vlc[i].table;
281
30.4k
        const int vlc_bits = s->vlc[i].bits;
282
30.4k
        int flags, pred;
283
284
30.4k
        flags = bytestream_get_byte(&slice);
285
30.4k
        pred  = bytestream_get_byte(&slice);
286
287
30.4k
        dst = p->data[i] + j * sheight * stride;
288
30.4k
        if (flags & 1) {
289
11.8k
            if (s->slices[i][j].size - 2 < width * height)
290
3.56k
                return AVERROR_INVALIDDATA;
291
1.19M
            for (k = 0; k < height; k++) {
292
1.18M
                bytestream_get_buffer(&slice, dst, width);
293
1.18M
                dst += stride;
294
1.18M
            }
295
18.5k
        } else {
296
18.5k
            int ret = init_get_bits8(&gb, slice, s->slices[i][j].size - 2);
297
298
18.5k
            if (ret < 0)
299
0
                return ret;
300
301
164M
            for (k = 0; k < height; k++)
302
164M
                READ_PLANE(dst, i, 1, 7)
303
18.5k
        }
304
305
26.3k
        switch (pred) {
306
1.27k
        case LEFT:
307
1.27k
            dst = p->data[i] + j * sheight * stride;
308
1.27k
            s->llviddsp.add_left_pred(dst, dst, width, 0);
309
1.27k
            dst += stride;
310
1.27k
            if (interlaced) {
311
444
                s->llviddsp.add_left_pred(dst, dst, width, 0);
312
444
                dst += stride;
313
444
            }
314
13.9M
            for (k = 1 + interlaced; k < height; k++) {
315
13.9M
                s->llviddsp.add_left_pred(dst, dst, width, dst[-fake_stride]);
316
13.9M
                dst += stride;
317
13.9M
            }
318
1.27k
            break;
319
7.38k
        case GRADIENT:
320
7.38k
            dst = p->data[i] + j * sheight * stride;
321
7.38k
            s->llviddsp.add_left_pred(dst, dst, width, 0);
322
7.38k
            dst += stride;
323
7.38k
            if (interlaced) {
324
491
                s->llviddsp.add_left_pred(dst, dst, width, 0);
325
491
                dst += stride;
326
491
            }
327
7.38k
            min_width = FFMIN(width, 32);
328
12.9M
            for (k = 1 + interlaced; k < height; k++) {
329
12.9M
                top = dst[-fake_stride];
330
12.9M
                left = top + dst[0];
331
12.9M
                dst[0] = left;
332
74.8M
                for (x = 1; x < min_width; x++) { /* dsp need aligned 32 */
333
61.9M
                    top = dst[x - fake_stride];
334
61.9M
                    lefttop = dst[x - (fake_stride + 1)];
335
61.9M
                    left += top - lefttop + dst[x];
336
61.9M
                    dst[x] = left;
337
61.9M
                }
338
12.9M
                if (width > 32)
339
1.93M
                    s->llviddsp.add_gradient_pred(dst + 32, fake_stride, width - 32);
340
12.9M
                dst += stride;
341
12.9M
            }
342
7.38k
            break;
343
775
        case MEDIAN:
344
775
            dst = p->data[i] + j * sheight * stride;
345
775
            s->llviddsp.add_left_pred(dst, dst, width, 0);
346
775
            dst += stride;
347
775
            if (interlaced) {
348
462
                s->llviddsp.add_left_pred(dst, dst, width, 0);
349
462
                dst += stride;
350
462
            }
351
775
            if (1 + interlaced < height)
352
538
                lefttop = left = dst[0];
353
11.3M
            for (k = 1 + interlaced; k < height; k++) {
354
11.3M
                s->llviddsp.add_median_pred(dst, dst - fake_stride,
355
11.3M
                                             dst, width, &left, &lefttop);
356
11.3M
                lefttop = left = dst[0];
357
11.3M
                dst += stride;
358
11.3M
            }
359
775
            break;
360
16.8k
        default:
361
16.8k
            avpriv_request_sample(avctx, "Unknown prediction: %d", pred);
362
26.3k
        }
363
26.3k
    }
364
365
11.8k
    if (s->decorrelate) {
366
4.03k
        int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height);
367
4.03k
        int width = avctx->coded_width;
368
4.03k
        uint8_t *b = p->data[0] + j * s->slice_height * p->linesize[0];
369
4.03k
        uint8_t *g = p->data[1] + j * s->slice_height * p->linesize[1];
370
4.03k
        uint8_t *r = p->data[2] + j * s->slice_height * p->linesize[2];
371
372
1.45M
        for (i = 0; i < height; i++) {
373
1.44M
            s->llviddsp.add_bytes(b, g, width);
374
1.44M
            s->llviddsp.add_bytes(r, g, width);
375
1.44M
            b += p->linesize[0];
376
1.44M
            g += p->linesize[1];
377
1.44M
            r += p->linesize[2];
378
1.44M
        }
379
4.03k
    }
380
381
11.8k
    return 0;
382
15.9k
}
383
384
static int build_huffman(AVCodecContext *avctx, const uint8_t *table,
385
                         int table_size, int max)
386
23.4k
{
387
23.4k
    MagicYUVContext *s = avctx->priv_data;
388
23.4k
    GetByteContext gb;
389
23.4k
    uint8_t *len = s->len;
390
23.4k
    uint16_t length_count[33] = { 0 };
391
23.4k
    int i = 0, j = 0, k;
392
393
23.4k
    bytestream2_init(&gb, table, table_size);
394
395
210k
    while (bytestream2_get_bytes_left(&gb) > 0) {
396
210k
        int b = bytestream2_peek_byteu(&gb) &  0x80;
397
210k
        int x = bytestream2_get_byteu(&gb)  & ~0x80;
398
210k
        int l = 1;
399
400
210k
        if (b) {
401
188k
            if (bytestream2_get_bytes_left(&gb) <= 0)
402
229
                break;
403
187k
            l += bytestream2_get_byteu(&gb);
404
187k
        }
405
210k
        k = j + l;
406
210k
        if (k > max || x == 0 || x > 32) {
407
1.82k
            av_log(avctx, AV_LOG_ERROR, "Invalid Huffman codes\n");
408
1.82k
            return AVERROR_INVALIDDATA;
409
1.82k
        }
410
411
208k
        length_count[x] += l;
412
31.6M
        for (; j < k; j++)
413
31.4M
            len[j] = x;
414
415
208k
        if (j == max) {
416
46.7k
            j = 0;
417
46.7k
            if (huff_build(avctx, len, length_count, &s->vlc[i], &s->multi[i], max, avctx)) {
418
663
                av_log(avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n");
419
663
                return AVERROR_INVALIDDATA;
420
663
            }
421
46.0k
            i++;
422
46.0k
            if (i == s->planes) {
423
20.4k
                break;
424
20.4k
            }
425
25.5k
            memset(length_count, 0, sizeof(length_count));
426
25.5k
        }
427
208k
    }
428
429
20.9k
    if (i != s->planes) {
430
505
        av_log(avctx, AV_LOG_ERROR, "Huffman tables too short\n");
431
505
        return AVERROR_INVALIDDATA;
432
505
    }
433
434
20.4k
    return 0;
435
20.9k
}
436
437
static int magy_decode_frame(AVCodecContext *avctx, AVFrame *p,
438
                             int *got_frame, AVPacket *avpkt)
439
67.9k
{
440
67.9k
    MagicYUVContext *s = avctx->priv_data;
441
67.9k
    GetByteContext gb;
442
67.9k
    uint32_t first_offset, offset, next_offset, header_size, slice_width;
443
67.9k
    int width, height, format, version, table_size;
444
67.9k
    int ret, i, j;
445
446
67.9k
    if (avpkt->size < 36)
447
22.5k
        return AVERROR_INVALIDDATA;
448
449
45.3k
    bytestream2_init(&gb, avpkt->data, avpkt->size);
450
45.3k
    if (bytestream2_get_le32u(&gb) != MKTAG('M', 'A', 'G', 'Y'))
451
5.62k
        return AVERROR_INVALIDDATA;
452
453
39.7k
    header_size = bytestream2_get_le32u(&gb);
454
39.7k
    if (header_size < 32 || header_size >= avpkt->size) {
455
3.10k
        av_log(avctx, AV_LOG_ERROR,
456
3.10k
               "header or packet too small %"PRIu32"\n", header_size);
457
3.10k
        return AVERROR_INVALIDDATA;
458
3.10k
    }
459
460
36.6k
    version = bytestream2_get_byteu(&gb);
461
36.6k
    if (version != 7) {
462
414
        avpriv_request_sample(avctx, "Version %d", version);
463
414
        return AVERROR_PATCHWELCOME;
464
414
    }
465
466
36.2k
    format = bytestream2_get_byteu(&gb);
467
36.2k
    switch (format) {
468
6.33k
    case 0x65:
469
6.33k
        avctx->pix_fmt = AV_PIX_FMT_GBRP;
470
6.33k
        break;
471
1.98k
    case 0x66:
472
1.98k
        avctx->pix_fmt = AV_PIX_FMT_GBRAP;
473
1.98k
        break;
474
2.93k
    case 0x67:
475
2.93k
        avctx->pix_fmt = AV_PIX_FMT_YUV444P;
476
2.93k
        break;
477
423
    case 0x68:
478
423
        avctx->pix_fmt = AV_PIX_FMT_YUV422P;
479
423
        break;
480
454
    case 0x69:
481
454
        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
482
454
        break;
483
355
    case 0x6a:
484
355
        avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
485
355
        break;
486
9.25k
    case 0x6b:
487
9.25k
        avctx->pix_fmt = AV_PIX_FMT_GRAY8;
488
9.25k
        break;
489
1.85k
    case 0x6c:
490
1.85k
        avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
491
1.85k
        break;
492
817
    case 0x76:
493
817
        avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
494
817
        break;
495
2.17k
    case 0x6d:
496
2.17k
        avctx->pix_fmt = AV_PIX_FMT_GBRP10;
497
2.17k
        break;
498
78
    case 0x6e:
499
78
        avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
500
78
        break;
501
4
    case 0x6f:
502
4
        avctx->pix_fmt = AV_PIX_FMT_GBRP12;
503
4
        break;
504
1.92k
    case 0x70:
505
1.92k
        avctx->pix_fmt = AV_PIX_FMT_GBRAP12;
506
1.92k
        break;
507
346
    case 0x71:
508
346
        avctx->pix_fmt = AV_PIX_FMT_GBRP14;
509
346
        break;
510
57
    case 0x72:
511
57
        avctx->pix_fmt = AV_PIX_FMT_GBRAP14;
512
57
        break;
513
6.09k
    case 0x73:
514
6.09k
        avctx->pix_fmt = AV_PIX_FMT_GRAY10;
515
6.09k
        break;
516
425
    case 0x7b:
517
425
        avctx->pix_fmt = AV_PIX_FMT_YUV420P10;
518
425
        break;
519
723
    default:
520
723
        avpriv_request_sample(avctx, "Format 0x%X", format);
521
723
        return AVERROR_PATCHWELCOME;
522
36.2k
    }
523
35.5k
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
524
35.5k
    av_assert1(desc);
525
35.5k
    int is_rgb = s->decorrelate = !!(desc->flags & AV_PIX_FMT_FLAG_RGB);
526
35.5k
    s->hshift[1] = s->hshift[2] = desc->log2_chroma_w;
527
35.5k
    s->vshift[1] = s->vshift[2] = desc->log2_chroma_h;
528
35.5k
    s->bps = desc->comp[0].depth;
529
35.5k
    s->max = 1 << s->bps;
530
35.5k
    s->magy_decode_slice = s->bps == 8 ? magy_decode_slice : magy_decode_slice10;
531
35.5k
    s->planes = av_pix_fmt_count_planes(avctx->pix_fmt);
532
533
35.5k
    bytestream2_skipu(&gb, 1);
534
35.5k
    s->color_matrix = bytestream2_get_byteu(&gb);
535
35.5k
    s->flags        = bytestream2_get_byteu(&gb);
536
35.5k
    s->interlaced   = !!(s->flags & 2);
537
35.5k
    bytestream2_skipu(&gb, 3);
538
539
35.5k
    width  = bytestream2_get_le32u(&gb);
540
35.5k
    height = bytestream2_get_le32u(&gb);
541
35.5k
    ret = ff_set_dimensions(avctx, width, height);
542
35.5k
    if (ret < 0)
543
4.75k
        return ret;
544
545
30.7k
    slice_width = bytestream2_get_le32u(&gb);
546
30.7k
    if (slice_width != avctx->coded_width) {
547
1.34k
        avpriv_request_sample(avctx, "Slice width %"PRIu32, slice_width);
548
1.34k
        return AVERROR_PATCHWELCOME;
549
1.34k
    }
550
29.4k
    s->slice_height = bytestream2_get_le32u(&gb);
551
29.4k
    if (s->slice_height <= 0 || s->slice_height > INT_MAX - avctx->coded_height) {
552
511
        av_log(avctx, AV_LOG_ERROR,
553
511
               "invalid slice height: %d\n", s->slice_height);
554
511
        return AVERROR_INVALIDDATA;
555
511
    }
556
557
28.9k
    bytestream2_skipu(&gb, 4);
558
559
28.9k
    s->nb_slices = (avctx->coded_height + s->slice_height - 1) / s->slice_height;
560
28.9k
    if (s->nb_slices > INT_MAX / FFMAX(sizeof(Slice), 4 * 5)) {
561
0
        av_log(avctx, AV_LOG_ERROR,
562
0
               "invalid number of slices: %d\n", s->nb_slices);
563
0
        return AVERROR_INVALIDDATA;
564
0
    }
565
566
28.9k
    if (s->interlaced) {
567
9.22k
        if ((s->slice_height >> s->vshift[1]) < 2) {
568
338
            av_log(avctx, AV_LOG_ERROR, "impossible slice height\n");
569
338
            return AVERROR_INVALIDDATA;
570
338
        }
571
8.88k
        if ((avctx->coded_height % s->slice_height) && ((avctx->coded_height % s->slice_height) >> s->vshift[1]) < 2) {
572
203
            av_log(avctx, AV_LOG_ERROR, "impossible height\n");
573
203
            return AVERROR_INVALIDDATA;
574
203
        }
575
8.88k
    }
576
577
28.3k
    if (bytestream2_get_bytes_left(&gb) <= s->nb_slices * s->planes * 5)
578
322
        return AVERROR_INVALIDDATA;
579
83.7k
    for (i = 0; i < s->planes; i++) {
580
58.6k
        av_fast_malloc(&s->slices[i], &s->slices_size[i], s->nb_slices * sizeof(Slice));
581
58.6k
        if (!s->slices[i])
582
0
            return AVERROR(ENOMEM);
583
584
58.6k
        offset = bytestream2_get_le32u(&gb);
585
58.6k
        if (offset >= avpkt->size - header_size)
586
1.74k
            return AVERROR_INVALIDDATA;
587
588
56.8k
        if (i == 0)
589
26.8k
            first_offset = offset;
590
591
57.6k
        for (j = 0; j < s->nb_slices - 1; j++) {
592
1.73k
            s->slices[i][j].start = offset + header_size;
593
594
1.73k
            next_offset = bytestream2_get_le32u(&gb);
595
1.73k
            if (next_offset <= offset || next_offset >= avpkt->size - header_size)
596
435
                return AVERROR_INVALIDDATA;
597
598
1.29k
            s->slices[i][j].size = next_offset - offset;
599
1.29k
            if (s->slices[i][j].size < 2)
600
578
                return AVERROR_INVALIDDATA;
601
720
            offset = next_offset;
602
720
        }
603
604
55.8k
        s->slices[i][j].start = offset + header_size;
605
55.8k
        s->slices[i][j].size  = avpkt->size - s->slices[i][j].start;
606
607
55.8k
        if (s->slices[i][j].size < 2)
608
212
            return AVERROR_INVALIDDATA;
609
55.8k
    }
610
611
25.0k
    if (bytestream2_get_byteu(&gb) != s->planes)
612
648
        return AVERROR_INVALIDDATA;
613
614
24.4k
    bytestream2_skipu(&gb, s->nb_slices * s->planes);
615
616
24.4k
    table_size = header_size + first_offset - bytestream2_tell(&gb);
617
24.4k
    if (table_size < 2)
618
966
        return AVERROR_INVALIDDATA;
619
620
23.4k
    ret = build_huffman(avctx, avpkt->data + bytestream2_tell(&gb),
621
23.4k
                        table_size, s->max);
622
23.4k
    if (ret < 0)
623
2.99k
        return ret;
624
625
20.4k
    if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
626
20
        return ret;
627
628
20.4k
    s->buf = avpkt->data;
629
20.4k
    s->p = p;
630
20.4k
    avctx->execute2(avctx, s->magy_decode_slice, NULL, NULL, s->nb_slices);
631
632
20.4k
    if (is_rgb) {
633
6.58k
        FFSWAP(uint8_t*, p->data[0], p->data[1]);
634
6.58k
        FFSWAP(int, p->linesize[0], p->linesize[1]);
635
13.8k
    } else {
636
13.8k
        switch (s->color_matrix) {
637
4.09k
        case 1:
638
4.09k
            p->colorspace = AVCOL_SPC_BT470BG;
639
4.09k
            break;
640
564
        case 2:
641
564
            p->colorspace = AVCOL_SPC_BT709;
642
564
            break;
643
13.8k
        }
644
13.8k
        p->color_range = (s->flags & 4) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
645
13.8k
    }
646
647
20.4k
    *got_frame = 1;
648
649
20.4k
    return avpkt->size;
650
20.4k
}
651
652
static av_cold int magy_decode_init(AVCodecContext *avctx)
653
2.82k
{
654
2.82k
    MagicYUVContext *s = avctx->priv_data;
655
2.82k
    ff_llviddsp_init(&s->llviddsp);
656
2.82k
    return 0;
657
2.82k
}
658
659
static av_cold int magy_decode_end(AVCodecContext *avctx)
660
2.82k
{
661
2.82k
    MagicYUVContext * const s = avctx->priv_data;
662
2.82k
    int i;
663
664
14.1k
    for (i = 0; i < FF_ARRAY_ELEMS(s->slices); i++) {
665
11.2k
        av_freep(&s->slices[i]);
666
11.2k
        s->slices_size[i] = 0;
667
11.2k
        ff_vlc_free(&s->vlc[i]);
668
11.2k
        ff_vlc_free_multi(&s->multi[i]);
669
11.2k
    }
670
671
2.82k
    return 0;
672
2.82k
}
673
674
const FFCodec ff_magicyuv_decoder = {
675
    .p.name           = "magicyuv",
676
    CODEC_LONG_NAME("MagicYUV video"),
677
    .p.type           = AVMEDIA_TYPE_VIDEO,
678
    .p.id             = AV_CODEC_ID_MAGICYUV,
679
    .priv_data_size   = sizeof(MagicYUVContext),
680
    .init             = magy_decode_init,
681
    .close            = magy_decode_end,
682
    FF_CODEC_DECODE_CB(magy_decode_frame),
683
    .p.capabilities   = AV_CODEC_CAP_DR1 |
684
                        AV_CODEC_CAP_FRAME_THREADS |
685
                        AV_CODEC_CAP_SLICE_THREADS,
686
};