]> git.sesse.net Git - ffmpeg/blob - libavcodec/prosumer.c
avcodec/gdv: Combine first and 3rd case in rescale()
[ffmpeg] / 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 *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)
61             return 0;
62         if (((b & 0xFF00u) != 0x8000u) || (b & 0xFFu)) {
63             if ((b & 0xFF00u) != 0x8000u) {
64                 bytestream2_put_le16(pb, b);
65             } else if (b & 0xFFu) {
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                 c = (((c >> 8) & 0xFFu) | (c & 0xFF00)) & 0xF00F;
73                 fill = lut[2 * idx + 1];
74                 if ((c & 0xFF00u) == 0x1000) {
75                     bytestream2_put_le16(pb, fill);
76                     c &= 0xFFFF00FFu;
77                 } else {
78                     bytestream2_put_le32(pb, fill);
79                     c &= 0xFFFF00FFu;
80                 }
81             }
82             while (c) {
83                 a <<= 4;
84                 cnt--;
85                 if (!cnt) {
86                     if (bytestream2_get_bytes_left(gb) <= 0) {
87                         if (!a)
88                             return 0;
89                         cnt = 4;
90                     } else {
91                         pos = bytestream2_tell(gb) ^ 2;
92                         bytestream2_seek(gb, pos, SEEK_SET);
93                         AV_WN16(&a, bytestream2_peek_le16(gb));
94                         pos = pos ^ 2;
95                         bytestream2_seek(gb, pos, SEEK_SET);
96                         bytestream2_skip(gb, 2);
97                         cnt = 4;
98                     }
99                 }
100                 c--;
101             }
102             idx = a >> 20;
103             b = lut[2 * idx];
104             continue;
105         }
106         idx = 2;
107         while (idx) {
108             a <<= 4;
109             cnt--;
110             if (cnt) {
111                 idx--;
112                 continue;
113             }
114             if (bytestream2_get_bytes_left(gb) <= 0) {
115                 if (a) {
116                     cnt = 4;
117                     idx--;
118                     continue;
119                 }
120                 return 0;
121             }
122             pos = bytestream2_tell(gb) ^ 2;
123             bytestream2_seek(gb, pos, SEEK_SET);
124             AV_WN16(&a, bytestream2_peek_le16(gb));
125             pos = pos ^ 2;
126             bytestream2_seek(gb, pos, SEEK_SET);
127             bytestream2_skip(gb, 2);
128             cnt = 4;
129             idx--;
130         }
131         b = PAIR(4, a) >> 16;
132     }
133
134     return 0;
135 }
136
137 static void vertical_predict(uint32_t *dst, int offset, const uint32_t *src, int stride, int height)
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) + (0x3F3F3F3F & 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     vertical_predict((uint32_t *)s->decbuffer, 0, (uint32_t *)s->initial_line, s->stride, 1);
167     vertical_predict((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         const 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 };
280
281 static void fill_elements(uint32_t idx, uint32_t shift, uint32_t *e0, uint32_t *e1)
282 {
283     uint32_t b, h = idx << (32 - shift);
284
285     for (int j = 0; j < 2; j++) {
286         for (int i = 0; i < 43; i++) {
287             b = 4 * TB(i);
288             if (shift >= b && ((h & (0xFFF00000u << (12 - b))) >> 20) == table[2 * i + 1]) {
289                 if (table[2 * i] >> 8 == 0x80u) {
290                     return;
291                 } else {
292                     *e0 = (*e0 & 0xFFFFFFu) | (((12 + b - shift)  | (0x40u<<j)) << 22);
293                     if (j == 0) {
294                         *e1 = table[2 * i];
295                         shift -= b;
296                         h <<= b;
297                     } else {
298                         *e1 |= (unsigned)table[2 * i] << 16;
299                     }
300                     break;
301                 }
302             }
303         }
304     }
305 }
306
307 static void fill_lut(uint32_t *lut)
308 {
309     for (int i = 1; i < FF_ARRAY_ELEMS(table); i += 2) {
310         uint32_t a = table[i];
311         uint32_t b = TB(i>>1);
312         uint32_t c, d;
313
314         c = (b << 16) | table[i-1];
315         d = 4 * (3 - b);
316         if (d <= 0) {
317             lut[2 * a] = c;
318             lut[2 * a + 1] = 0;
319         } else {
320             for (int j = 0; j < 1 << d; j++) {
321                 uint32_t f = 0xFFFFFFFFu;
322                 c &= 0xFFFFFFu;
323                 if ((c & 0xFF00u) != 0x8000u)
324                     fill_elements(j, d, &c, &f);
325                 lut[2 * a + 2 * j] = c;
326                 lut[2 * a + 2 * j + 1] = f;
327             }
328         }
329     }
330
331     for (int i = 0; i < 32; i += 2) {
332         lut[i  ] = 0x68000;
333         lut[i+1] = 0;
334     }
335 }
336
337 static av_cold int decode_init(AVCodecContext *avctx)
338 {
339     ProSumerContext *s = avctx->priv_data;
340
341     s->stride = 3LL * FFALIGN(avctx->width, 8) >> 1;
342     s->size = avctx->height * s->stride;
343
344     avctx->pix_fmt = AV_PIX_FMT_YUV411P;
345
346     s->initial_line = av_malloc(s->stride);
347     s->decbuffer = av_malloc(s->size);
348     if (!s->initial_line || !s->decbuffer)
349         return AVERROR(ENOMEM);
350     memset(s->initial_line, 0x80u, s->stride);
351
352     fill_lut(s->lut);
353
354     return 0;
355 }
356
357 static av_cold int decode_close(AVCodecContext *avctx)
358 {
359     ProSumerContext *s = avctx->priv_data;
360
361     av_freep(&s->initial_line);
362     av_freep(&s->decbuffer);
363
364     return 0;
365 }
366
367 AVCodec ff_prosumer_decoder = {
368     .name           = "prosumer",
369     .long_name      = NULL_IF_CONFIG_SMALL("Brooktree ProSumer Video"),
370     .type           = AVMEDIA_TYPE_VIDEO,
371     .id             = AV_CODEC_ID_PROSUMER,
372     .priv_data_size = sizeof(ProSumerContext),
373     .init           = decode_init,
374     .decode         = decode_frame,
375     .close          = decode_close,
376     .capabilities   = AV_CODEC_CAP_DR1,
377     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
378                       FF_CODEC_CAP_INIT_CLEANUP,
379 };