FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/prosumer.c
Date: 2021-09-24 20:55:06
Exec Total Coverage
Lines: 0 158 0.0%
Branches: 0 82 0.0%

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