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