Coverage Report

Created: 2026-07-25 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/prosumer.c
Line
Count
Source
1
/*
2
 * Brooktree ProSumer Video decoder
3
 * Copyright (c) 2018 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 <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
25
26
#include "libavutil/internal.h"
27
#include "libavutil/intreadwrite.h"
28
#include "libavutil/mem.h"
29
30
#include "avcodec.h"
31
#include "bytestream.h"
32
#include "codec_internal.h"
33
#include "decode.h"
34
35
typedef struct ProSumerContext {
36
    GetByteContext gb;
37
    PutByteContext pb;
38
39
    unsigned stride;
40
    unsigned size;
41
    uint32_t lut[0x2000];
42
    uint8_t *initial_line;
43
    uint8_t *decbuffer;
44
} ProSumerContext;
45
46
2.26M
#define PAIR(high, low) (((uint64_t)(high) << 32) | low)
47
48
static int decompress(GetByteContext *gb, int size, PutByteContext *pb, const uint32_t *lut)
49
132k
{
50
132k
    int pos, idx, cnt, fill;
51
132k
    uint32_t a, b, c;
52
53
132k
    bytestream2_skip(gb, 32);
54
132k
    cnt = 4;
55
132k
    a = bytestream2_get_le32(gb);
56
132k
    idx = a >> 20;
57
132k
    b = lut[2 * idx];
58
59
8.29M
    while (1) {
60
8.29M
        if (bytestream2_get_bytes_left_p(pb) <= 0 || bytestream2_get_eof(pb))
61
2.91k
            return 0;
62
8.29M
        if ((b & 0xFF00u) != 0x8000u || (b & 0xFFu)) {
63
6.02M
            if ((b & 0xFF00u) != 0x8000u) {
64
4.19M
                bytestream2_put_le16(pb, b);
65
4.19M
            } else {
66
1.82M
                idx = 0;
67
63.2M
                for (int i = 0; i < (b & 0xFFu); i++)
68
61.4M
                    bytestream2_put_le32(pb, 0);
69
1.82M
            }
70
6.02M
            c = b >> 16;
71
6.02M
            if (c & 0xFF00u) {
72
59.2k
                fill = lut[2 * idx + 1];
73
59.2k
                if ((c & 0xF000u) == 0x1000) {
74
22.3k
                    bytestream2_put_le16(pb, fill);
75
36.8k
                } else {
76
36.8k
                    bytestream2_put_le32(pb, fill);
77
36.8k
                }
78
59.2k
                c = (c >> 8) & 0x0Fu;
79
59.2k
            }
80
22.2M
            while (c) {
81
16.3M
                a <<= 4;
82
16.3M
                cnt--;
83
16.3M
                if (!cnt) {
84
4.15M
                    if (bytestream2_get_bytes_left(gb) <= 0) {
85
129k
                        if (!a)
86
126k
                            return 0;
87
4.02M
                    } else {
88
4.02M
                        pos = bytestream2_tell(gb);
89
4.02M
                        bytestream2_seek(gb, pos ^ 2, SEEK_SET);
90
4.02M
                        AV_WN16(&a, bytestream2_peek_le16(gb));
91
4.02M
                        bytestream2_seek(gb, pos + 2, SEEK_SET);
92
4.02M
                    }
93
4.02M
                    cnt = 4;
94
4.02M
                }
95
16.2M
                c--;
96
16.2M
            }
97
5.89M
            idx = a >> 20;
98
5.89M
            b = lut[2 * idx];
99
5.89M
            if (!b)
100
1.77k
                return AVERROR_INVALIDDATA;
101
5.89M
            continue;
102
5.89M
        }
103
2.27M
        idx = 2;
104
6.81M
        while (idx) {
105
4.54M
            a <<= 4;
106
4.54M
            cnt--;
107
4.54M
            if (cnt) {
108
3.46M
                idx--;
109
3.46M
                continue;
110
3.46M
            }
111
1.07M
            if (bytestream2_get_bytes_left(gb) <= 0) {
112
2.39k
                if (a) {
113
870
                    cnt = 4;
114
870
                    idx--;
115
870
                    continue;
116
870
                }
117
1.52k
                return 0;
118
2.39k
            }
119
1.07M
            pos = bytestream2_tell(gb);
120
1.07M
            bytestream2_seek(gb, pos ^ 2, SEEK_SET);
121
1.07M
            AV_WN16(&a, bytestream2_peek_le16(gb));
122
1.07M
            bytestream2_seek(gb, pos + 2, SEEK_SET);
123
1.07M
            cnt = 4;
124
1.07M
            idx--;
125
1.07M
        }
126
2.26M
        b = PAIR(4, a) >> 16;
127
2.26M
    }
128
129
0
    return 0;
130
132k
}
131
132
static void vertical_predict(uint32_t *dst, int offset, const uint32_t *src, int stride, int height)
133
231k
{
134
231k
    dst += offset >> 2;
135
136
46.7M
    for (int i = 0; i < height; i++) {
137
747M
        for (int j = 0; j < stride >> 2; j++) {
138
700M
            dst[j] = (((src[j] >> 3) + (0x3F3F3F3F & dst[j])) << 3) & 0xFCFCFCFC;
139
700M
        }
140
141
46.5M
        dst += stride >> 2;
142
46.5M
        src += stride >> 2;
143
46.5M
    }
144
231k
}
145
146
static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
147
                        int *got_frame, AVPacket *avpkt)
148
304k
{
149
304k
    ProSumerContext *s = avctx->priv_data;
150
304k
    int ret;
151
152
304k
    if (avpkt->size <= 32)
153
172k
        return AVERROR_INVALIDDATA;
154
155
132k
    bytestream2_init(&s->gb, avpkt->data, avpkt->size);
156
132k
    bytestream2_init_writer(&s->pb, s->decbuffer, s->size);
157
132k
    ret = decompress(&s->gb, AV_RL32(avpkt->data + 28) >> 1, &s->pb, s->lut);
158
132k
    if (ret < 0)
159
1.77k
        return ret;
160
130k
    if (bytestream2_get_bytes_left_p(&s->pb) > s->size * (int64_t)avctx->discard_damaged_percentage / 100)
161
14.6k
        return AVERROR_INVALIDDATA;
162
163
115k
    av_assert0(s->size >= bytestream2_get_bytes_left_p(&s->pb));
164
115k
    memset(s->decbuffer + bytestream2_tell_p(&s->pb), 0, bytestream2_get_bytes_left_p(&s->pb));
165
166
115k
    vertical_predict((uint32_t *)s->decbuffer, 0, (uint32_t *)s->initial_line, s->stride, 1);
167
115k
    vertical_predict((uint32_t *)s->decbuffer, s->stride, (uint32_t *)s->decbuffer, s->stride, avctx->height - 1);
168
169
115k
    ret = ff_get_buffer(avctx, frame, 0);
170
115k
    if (ret < 0)
171
1.57k
        return ret;
172
173
5.52M
    for (int i = avctx->height - 1; i >= 0 ; i--) {
174
5.41M
        uint8_t *y = &frame->data[0][i * frame->linesize[0]];
175
5.41M
        uint8_t *u = &frame->data[1][i * frame->linesize[1]];
176
5.41M
        uint8_t *v = &frame->data[2][i * frame->linesize[2]];
177
5.41M
        const uint8_t *src = s->decbuffer + (avctx->height - 1 - i) * s->stride;
178
179
106M
        for (int j = 0; j < avctx->width; j += 8) {
180
100M
            *(u++) = *src++;
181
100M
            *(y++) = *src++;
182
100M
            *(v++) = *src++;
183
100M
            *(y++) = *src++;
184
185
100M
            *(u++) = *src++;
186
100M
            *(y++) = *src++;
187
100M
            *(v++) = *src++;
188
100M
            *(y++) = *src++;
189
190
100M
            *(y++) = *src++;
191
100M
            *(y++) = *src++;
192
100M
            *(y++) = *src++;
193
100M
            *(y++) = *src++;
194
100M
        }
195
5.41M
    }
196
197
114k
    *got_frame = 1;
198
199
114k
    return avpkt->size;
200
115k
}
201
202
107M
#define TB(i) (1 + ((i) > 10) + ((i) > 49))
203
static const uint16_t table[] = {
204
    0x0000, 0x100, 0x0101, 0x200, 0x0202, 0x300, 0xFFFF, 0x400, 0xFEFE, 0x500,
205
    0x0001, 0x700, 0x0100, 0x800, 0x00FF, 0x900, 0xFF00, 0xA00, 0x8001, 0x600,
206
    0x8002, 0xB00, 0xFCFC, 0x010, 0x0404, 0x030, 0x0002, 0xD30, 0xFEFC, 0x020,
207
    0xFCFE, 0x040, 0xFEFF, 0xD20, 0x0808, 0x060, 0xFFFE, 0x050, 0x0402, 0xC00,
208
    0x0204, 0xC10, 0xF8F8, 0xC30, 0x0201, 0xC40, 0x0102, 0xC60, 0x0804, 0xF30,
209
    0x0408, 0xE00, 0xF8FC, 0xE10, 0xFCF8, 0xC70, 0x00FE, 0xD00, 0xFE00, 0xD40,
210
    0xFF01, 0xD50, 0x01FF, 0xD60, 0x0200, 0xD70, 0xFCFF, 0xE20, 0x0104, 0xE30,
211
    0xF0F0, 0xE50, 0x0401, 0xE70, 0x02FE, 0xF00, 0xFE02, 0xF10, 0xFE01, 0xF20,
212
    0x01FE, 0xF40, 0xFF02, 0xF50, 0x02FF, 0xF60, 0x8003, 0xC20, 0x8004, 0x070,
213
    0x8005, 0xD10, 0x8006, 0xC50, 0x8007, 0xE60, 0x8008, 0xE40, 0x8009, 0xF70,
214
    0xFC02, 0x080, 0xFE04, 0x081, 0xFC00, 0x082, 0x02FC, 0x083, 0x1010, 0x084,
215
    0x00FC, 0x085, 0x0004, 0x086, 0x0400, 0x087, 0xFFFC, 0x088, 0x1008, 0x089,
216
    0x0810, 0x08A, 0x0802, 0x08B, 0x0208, 0x08C, 0xFEF8, 0x08D, 0xFC01, 0x08E,
217
    0x04FF, 0x08F, 0xF8FE, 0x090, 0xFC04, 0x091, 0x04FC, 0x092, 0xFF04, 0x093,
218
    0x01FC, 0x094, 0xF0F8, 0x095, 0xF8F0, 0x096, 0x04FE, 0x097, 0xF0FC, 0x098,
219
    0x0008, 0x099, 0x08FE, 0x09A, 0x01F8, 0x09B, 0x0800, 0x09C, 0x08FC, 0x09D,
220
    0xFE08, 0x09E, 0xFC08, 0x09F, 0xF800, 0x0A0, 0x0108, 0x0A1, 0xF802, 0x0A2,
221
    0x0801, 0x0A3, 0x00F8, 0x0A4, 0xF804, 0x0A5, 0xF8FF, 0x0A6, 0xFFF8, 0x0A7,
222
    0x04F8, 0x0A8, 0x02F8, 0x0A9, 0x1004, 0x0AA, 0x08F8, 0x0AB, 0xF808, 0x0AC,
223
    0x0410, 0x0AD, 0xFF08, 0x0AE, 0x08FF, 0x0AF, 0xFCF0, 0x0B0, 0xF801, 0x0B1,
224
    0xE0F0, 0x0B2, 0xF3F3, 0x0B3, 0xF0E0, 0x0B4, 0xFAFA, 0x0B5, 0xF7F7, 0x0B6,
225
    0xFEF0, 0x0B7, 0xF0FE, 0x0B8, 0xE9E9, 0x0B9, 0xF9F9, 0x0BA, 0x2020, 0x0BB,
226
    0xE0E0, 0x0BC, 0x02F0, 0x0BD, 0x04F0, 0x0BE, 0x2010, 0x0BF, 0xECEC, 0x0C0,
227
    0xEFEF, 0x0C1, 0x1020, 0x0C2, 0xF5F5, 0x0C3, 0xF4F4, 0x0C4, 0xEDED, 0x0C5,
228
    0xEAEA, 0x0C6, 0xFBFB, 0x0C7, 0x1002, 0x0C8, 0xF2F2, 0x0C9, 0xF6F6, 0x0CA,
229
    0xF1F1, 0x0CB, 0xFDFD, 0x0CC, 0x0210, 0x0CD, 0x10FF, 0x0CE, 0xFDFE, 0x0CF,
230
    0x10F8, 0x0D0, 0x1000, 0x0D1, 0xF001, 0x0D2, 0x1001, 0x0D3, 0x0010, 0x0D4,
231
    0x10FE, 0x0D5, 0xEBEB, 0x0D6, 0xFE10, 0x0D7, 0x0110, 0x0D8, 0xF000, 0x0D9,
232
    0x08F0, 0x0DA, 0x01F0, 0x0DB, 0x0303, 0x0DC, 0x00F0, 0x0DD, 0xF002, 0x0DE,
233
    0x10FC, 0x0DF, 0xFC10, 0x0E0, 0xF0FF, 0x0E1, 0xEEEE, 0x0E2, 0xF004, 0x0E3,
234
    0xFFF0, 0x0E4, 0xF7F8, 0x0E5, 0xF3F2, 0x0E6, 0xF9FA, 0x0E7, 0x0820, 0x0E8,
235
    0x0302, 0x0E9, 0xE0F8, 0x0EA, 0x0505, 0x0EB, 0x2008, 0x0EC, 0xE8E8, 0x0ED,
236
    0x0403, 0x0EE, 0xFBFC, 0x0EF, 0xFCFD, 0x0F0, 0xFBFA, 0x0F1, 0x0203, 0x0F2,
237
    0xFCFB, 0x0F3, 0x0304, 0x0F4, 0xF810, 0x0F5, 0xFF10, 0x0F6, 0xF008, 0x0F7,
238
    0xFEFD, 0x0F8, 0xF7F6, 0x0F9, 0xF2F1, 0x0FA, 0xF3F4, 0x0FB, 0xEDEC, 0x0FC,
239
    0xF4F1, 0x0FD, 0xF5F6, 0x0FE, 0xF0F1, 0x0FF, 0xF9F8, 0xC80, 0x10F0, 0xC81,
240
    0xF2F3, 0xC82, 0xF7F9, 0xC83, 0xF6F5, 0xC84, 0xF0EF, 0xC85, 0xF4F5, 0xC86,
241
    0xF6F7, 0xC87, 0xFAF9, 0xC88, 0x0405, 0xC89, 0xF8F9, 0xC8A, 0xFAFB, 0xC8B,
242
    0xF1F0, 0xC8C, 0xF4F3, 0xC8D, 0xF1F2, 0xC8E, 0xF8E0, 0xC8F, 0xF8F7, 0xC90,
243
    0xFDFC, 0xC91, 0xF8FA, 0xC92, 0xFAF6, 0xC93, 0xEEEF, 0xC94, 0xF5F7, 0xC95,
244
    0xFDFB, 0xC96, 0xF4F6, 0xC97, 0xFCFA, 0xC98, 0xECED, 0xC99, 0xF0F3, 0xC9A,
245
    0xF3F1, 0xC9B, 0xECEB, 0xC9C, 0xEDEE, 0xC9D, 0xF9F7, 0xC9E, 0x0420, 0xC9F,
246
    0xEBEA, 0xCA0, 0xF0F4, 0xCA1, 0xF3F5, 0xCA2, 0xFAF7, 0xCA3, 0x0301, 0xCA4,
247
    0xF3F7, 0xCA5, 0xF7F3, 0xCA6, 0xEFF0, 0xCA7, 0xF9F6, 0xCA8, 0xEFEE, 0xCA9,
248
    0xF4F7, 0xCAA, 0x0504, 0xCAB, 0xF5F4, 0xCAC, 0xF1F3, 0xCAD, 0xEBEE, 0xCAE,
249
    0xF2F5, 0xCAF, 0xF3EF, 0xCB0, 0xF5F1, 0xCB1, 0xF9F3, 0xCB2, 0xEDF0, 0xCB3,
250
    0xEEF1, 0xCB4, 0xF6F9, 0xCB5, 0xF8FB, 0xCB6, 0xF010, 0xCB7, 0xF2F6, 0xCB8,
251
    0xF4ED, 0xCB9, 0xF7FB, 0xCBA, 0xF8F3, 0xCBB, 0xEDEB, 0xCBC, 0xF0F2, 0xCBD,
252
    0xF2F9, 0xCBE, 0xF8F1, 0xCBF, 0xFAFC, 0xCC0, 0xFBF8, 0xCC1, 0xF6F0, 0xCC2,
253
    0xFAF8, 0xCC3, 0x0103, 0xCC4, 0xF3F6, 0xCC5, 0xF4F9, 0xCC6, 0xF7F2, 0xCC7,
254
    0x2004, 0xCC8, 0xF2F0, 0xCC9, 0xF4F2, 0xCCA, 0xEEED, 0xCCB, 0xFCE0, 0xCCC,
255
    0xEAE9, 0xCCD, 0xEAEB, 0xCCE, 0xF6F4, 0xCCF, 0xFFFD, 0xCD0, 0xE9EA, 0xCD1,
256
    0xF1F4, 0xCD2, 0xF6EF, 0xCD3, 0xF6F8, 0xCD4, 0xF8F6, 0xCD5, 0xEFF2, 0xCD6,
257
    0xEFF1, 0xCD7, 0xF7F1, 0xCD8, 0xFBFD, 0xCD9, 0xFEF6, 0xCDA, 0xFFF7, 0xCDB,
258
    0x0605, 0xCDC, 0xF0F5, 0xCDD, 0xF0FA, 0xCDE, 0xF1F9, 0xCDF, 0xF2FC, 0xCE0,
259
    0xF7EE, 0xCE1, 0xF7F5, 0xCE2, 0xF9FC, 0xCE3, 0xFAF5, 0xCE4, 0xFBF1, 0xCE5,
260
    0xF1EF, 0xCE6, 0xF1FA, 0xCE7, 0xF4F8, 0xCE8, 0xF7F0, 0xCE9, 0xF7F4, 0xCEA,
261
    0xF7FC, 0xCEB, 0xF9FB, 0xCEC, 0xFAF1, 0xCED, 0xFBF9, 0xCEE, 0xFDFF, 0xCEF,
262
    0xE0FC, 0xCF0, 0xEBEC, 0xCF1, 0xEDEF, 0xCF2, 0xEFED, 0xCF3, 0xF1F6, 0xCF4,
263
    0xF2F7, 0xCF5, 0xF3EE, 0xCF6, 0xF3F8, 0xCF7, 0xF5F2, 0xCF8, 0xF8F2, 0xCF9,
264
    0xF9F1, 0xCFA, 0xF9F2, 0xCFB, 0xFBEF, 0xCFC, 0x00FD, 0xCFD, 0xECEE, 0xCFE,
265
    0xF2EF, 0xCFF, 0xF2F8, 0xD80, 0xF5F0, 0xD81, 0xF6F2, 0xD82, 0xFCF7, 0xD83,
266
    0xFCF9, 0xD84, 0x0506, 0xD85, 0xEEEC, 0xD86, 0xF0F6, 0xD87, 0xF2F4, 0xD88,
267
    0xF6F1, 0xD89, 0xF8F5, 0xD8A, 0xF9F4, 0xD8B, 0xFBF7, 0xD8C, 0x0503, 0xD8D,
268
    0xEFEC, 0xD8E, 0xF3F0, 0xD8F, 0xF4F0, 0xD90, 0xF5F3, 0xD91, 0xF6F3, 0xD92,
269
    0xF7FA, 0xD93, 0x800A, 0xD94, 0x800B, 0xD95, 0x800C, 0xD96, 0x800D, 0xD97,
270
    0x800E, 0xD98, 0x800F, 0xD99, 0x8010, 0xD9A, 0x8011, 0xD9B, 0x8012, 0xD9C,
271
    0x8013, 0xD9D, 0x8014, 0xD9E, 0x8015, 0xD9F, 0x8016, 0xDA0, 0x8017, 0xDA1,
272
    0x8018, 0xDA2, 0x8019, 0xDA3, 0x801A, 0xDA4, 0x801B, 0xDA5, 0x801C, 0xDA6,
273
    0x801D, 0xDA7, 0x801E, 0xDA8, 0x801F, 0xDA9, 0x8020, 0xDAA, 0x8021, 0xDAB,
274
    0x8022, 0xDAC, 0x8023, 0xDAD, 0x8024, 0xDAE, 0x8025, 0xDAF, 0x8026, 0xDB0,
275
    0x8027, 0xDB1, 0x8028, 0xDB2, 0x8029, 0xDB3, 0x802A, 0xDB4, 0x802B, 0xDB5,
276
    0x802C, 0xDB6, 0x802D, 0xDB7, 0x802E, 0xDB8, 0x802F, 0xDB9, 0x80FF, 0xDBA,
277
};
278
279
static void fill_elements(uint32_t idx, uint32_t shift, uint32_t *e0, uint32_t *e1)
280
2.54M
{
281
2.54M
    uint32_t b, h = idx << (32 - shift);
282
283
6.86M
    for (int j = 0; j < 2; j++) {
284
108M
        for (int i = 0; i < 43; i++) {
285
106M
            b = 4 * TB(i);
286
106M
            if (shift >= b && ((h & (0xFFF00000u << (12 - b))) >> 20) == table[2 * i + 1]) {
287
2.81M
                if (table[2 * i] >> 8 == 0x80u) {
288
465k
                    return;
289
2.35M
                } else {
290
2.35M
                    *e0 = (*e0 & 0xFFFFFFu) | (((12 + b - shift)  | (0x40u<<j)) << 22);
291
2.35M
                    if (j == 0) {
292
1.69M
                        *e1 = table[2 * i];
293
1.69M
                        shift -= b;
294
1.69M
                        h <<= b;
295
1.69M
                    } else {
296
659k
                        *e1 |= (unsigned)table[2 * i] << 16;
297
659k
                    }
298
2.35M
                    break;
299
2.35M
                }
300
2.81M
            }
301
106M
        }
302
4.77M
    }
303
2.54M
}
304
305
static void fill_lut(uint32_t *lut)
306
905
{
307
331k
    for (int i = 1; i < FF_ARRAY_ELEMS(table); i += 2) {
308
330k
        uint32_t a = table[i];
309
330k
        uint32_t b = TB(i>>1);
310
330k
        uint32_t c, d;
311
312
330k
        c = (b << 16) | table[i-1];
313
330k
        d = 4 * (3 - b);
314
330k
        if (d <= 0) {
315
285k
            lut[2 * a] = c;
316
285k
            lut[2 * a + 1] = 0;
317
285k
        } else {
318
3.15M
            for (int j = 0; j < 1 << d; j++) {
319
3.11M
                uint32_t f = 0xFFFFFFFFu;
320
3.11M
                c &= 0xFFFFFFu;
321
3.11M
                if ((c & 0xFF00u) != 0x8000u)
322
2.54M
                    fill_elements(j, d, &c, &f);
323
3.11M
                lut[2 * a + 2 * j] = c;
324
3.11M
                lut[2 * a + 2 * j + 1] = f;
325
3.11M
            }
326
45.2k
        }
327
330k
    }
328
329
15.3k
    for (int i = 0; i < 32; i += 2) {
330
14.4k
        lut[i  ] = 0x68000;
331
14.4k
        lut[i+1] = 0;
332
14.4k
    }
333
905
}
334
335
static av_cold int decode_init(AVCodecContext *avctx)
336
905
{
337
905
    ProSumerContext *s = avctx->priv_data;
338
339
905
    s->stride = 3LL * FFALIGN(avctx->width, 8) >> 1;
340
905
    s->size = avctx->height * s->stride;
341
342
905
    avctx->pix_fmt = AV_PIX_FMT_YUV411P;
343
344
905
    s->initial_line = av_malloc(s->stride);
345
905
    s->decbuffer = av_malloc(s->size);
346
905
    if (!s->initial_line || !s->decbuffer)
347
0
        return AVERROR(ENOMEM);
348
905
    memset(s->initial_line, 0x80u, s->stride);
349
350
905
    fill_lut(s->lut);
351
352
905
    return 0;
353
905
}
354
355
static av_cold int decode_close(AVCodecContext *avctx)
356
905
{
357
905
    ProSumerContext *s = avctx->priv_data;
358
359
905
    av_freep(&s->initial_line);
360
905
    av_freep(&s->decbuffer);
361
362
905
    return 0;
363
905
}
364
365
const FFCodec ff_prosumer_decoder = {
366
    .p.name         = "prosumer",
367
    CODEC_LONG_NAME("Brooktree ProSumer Video"),
368
    .p.type         = AVMEDIA_TYPE_VIDEO,
369
    .p.id           = AV_CODEC_ID_PROSUMER,
370
    .priv_data_size = sizeof(ProSumerContext),
371
    .init           = decode_init,
372
    FF_CODEC_DECODE_CB(decode_frame),
373
    .close          = decode_close,
374
    .p.capabilities = AV_CODEC_CAP_DR1,
375
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
376
};