]> git.sesse.net Git - ffmpeg/blob - libavcodec/gdv.c
avcodec: Constify AVCodecs
[ffmpeg] / libavcodec / gdv.c
1 /*
2  * Gremlin Digital Video (GDV) decoder
3  * Copyright (c) 2017 Konstantin Shishkov
4  * Copyright (c) 2017 Paul B Mahol
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 #include "libavutil/common.h"
24 #include "avcodec.h"
25 #include "bytestream.h"
26 #include "decode.h"
27 #include "internal.h"
28
29 typedef struct GDVContext {
30     AVCodecContext *avctx;
31
32     GetByteContext gb;
33     GetByteContext g2;
34     PutByteContext pb;
35
36     uint32_t pal[256];
37     uint8_t *frame;
38     unsigned frame_size;
39     unsigned scale_h, scale_v;
40 } GDVContext;
41
42 typedef struct Bits8 {
43     uint8_t queue;
44     uint8_t fill;
45 } Bits8;
46
47 typedef struct Bits32 {
48     uint32_t queue;
49     uint8_t  fill;
50 } Bits32;
51
52 #define PREAMBLE_SIZE 4096
53
54 static av_cold int gdv_decode_init(AVCodecContext *avctx)
55 {
56     GDVContext *gdv = avctx->priv_data;
57     int i, j, k;
58
59     avctx->pix_fmt  = AV_PIX_FMT_PAL8;
60     gdv->frame_size = avctx->width * avctx->height + PREAMBLE_SIZE;
61     gdv->frame = av_calloc(gdv->frame_size, 1);
62     if (!gdv->frame)
63         return AVERROR(ENOMEM);
64
65     for (i = 0; i < 2; i++) {
66         for (j = 0; j < 256; j++) {
67             for (k = 0; k < 8; k++) {
68                 gdv->frame[i * 2048 + j * 8 + k] = j;
69             }
70         }
71     }
72
73     return 0;
74 }
75
76 static void scaleup(uint8_t *dst, const uint8_t *src, int w)
77 {
78     int x;
79     for (x = 0; x < w - 7; x+=8) {
80         dst[x + 0] =
81         dst[x + 1] = src[(x>>1) + 0];
82         dst[x + 2] =
83         dst[x + 3] = src[(x>>1) + 1];
84         dst[x + 4] =
85         dst[x + 5] = src[(x>>1) + 2];
86         dst[x + 6] =
87         dst[x + 7] = src[(x>>1) + 3];
88     }
89     for (; x < w; x++) {
90         dst[x] = src[(x>>1)];
91     }
92 }
93
94 static void scaleup_rev(uint8_t *dst, const uint8_t *src, int w)
95 {
96     int x;
97
98     for (x = w - 1; (x+1) & 7; x--) {
99         dst[x] = src[(x>>1)];
100     }
101     for (x -= 7; x >= 0; x -= 8) {
102         dst[x + 6] =
103         dst[x + 7] = src[(x>>1) + 3];
104         dst[x + 4] =
105         dst[x + 5] = src[(x>>1) + 2];
106         dst[x + 2] =
107         dst[x + 3] = src[(x>>1) + 1];
108         dst[x + 0] =
109         dst[x + 1] = src[(x>>1) + 0];
110     }
111 }
112
113 static void scaledown(uint8_t *dst, const uint8_t *src, int w)
114 {
115     int x;
116     for (x = 0; x < w - 7; x+=8) {
117         dst[x + 0] = src[2*x + 0];
118         dst[x + 1] = src[2*x + 2];
119         dst[x + 2] = src[2*x + 4];
120         dst[x + 3] = src[2*x + 6];
121         dst[x + 4] = src[2*x + 8];
122         dst[x + 5] = src[2*x +10];
123         dst[x + 6] = src[2*x +12];
124         dst[x + 7] = src[2*x +14];
125     }
126     for (; x < w; x++) {
127         dst[x] = src[2*x];
128     }
129 }
130
131 static void rescale(GDVContext *gdv, uint8_t *dst, int w, int h, int scale_v, int scale_h)
132 {
133     int j, y;
134
135     if ((gdv->scale_v == scale_v) && (gdv->scale_h == scale_h)) {
136         return;
137     }
138
139     if (gdv->scale_v) {
140         for (j = 0; j < h; j++) {
141             int y = h - j - 1;
142             uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w;
143             uint8_t *src1 = dst + PREAMBLE_SIZE + (y>>!!gdv->scale_h) * (w>>1);
144
145             scaleup_rev(dst1, src1, w);
146         }
147     } else if (gdv->scale_h) {
148         for (j = 0; j < h; j++) {
149             int y = h - j - 1;
150             uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w;
151             uint8_t *src1 = dst + PREAMBLE_SIZE + (y>>1) * w;
152             memcpy(dst1, src1, w);
153         }
154     }
155
156     if (scale_h && scale_v) {
157         for (y = 0; y < (h>>1); y++) {
158             uint8_t *dst1 = dst + PREAMBLE_SIZE + y * (w>>1);
159             uint8_t *src1 = dst + PREAMBLE_SIZE + y*2 * w;
160             scaledown(dst1, src1, w>>1);
161         }
162     } else if (scale_h) {
163         for (y = 0; y < (h>>1); y++) {
164             uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w;
165             uint8_t *src1 = dst + PREAMBLE_SIZE + y*2 * w;
166             memcpy(dst1, src1, w);
167         }
168     } else if (scale_v) {
169         for (y = 0; y < h; y++) {
170             uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w;
171             scaledown(dst1, dst1, w>>1);
172         }
173     }
174
175     gdv->scale_v = scale_v;
176     gdv->scale_h = scale_h;
177 }
178
179 static int read_bits2(Bits8 *bits, GetByteContext *gb)
180 {
181     int res;
182
183     if (bits->fill == 0) {
184         bits->queue |= bytestream2_get_byte(gb);
185         bits->fill   = 8;
186     }
187     res = bits->queue >> 6;
188     bits->queue <<= 2;
189     bits->fill   -= 2;
190
191     return res;
192 }
193
194 static void fill_bits32(Bits32 *bits, GetByteContext *gb)
195 {
196     bits->queue = bytestream2_get_le32(gb);
197     bits->fill  = 32;
198 }
199
200 static int read_bits32(Bits32 *bits, GetByteContext *gb, int nbits)
201 {
202     int res = bits->queue & ((1 << nbits) - 1);
203
204     bits->queue >>= nbits;
205     bits->fill   -= nbits;
206     if (bits->fill <= 16) {
207         bits->queue |= bytestream2_get_le16(gb) << bits->fill;
208         bits->fill  += 16;
209     }
210
211     return res;
212 }
213
214 static void lz_copy(PutByteContext *pb, GetByteContext *g2, int offset, unsigned len)
215 {
216     int i;
217
218     if (offset == -1) {
219         int c;
220
221         bytestream2_seek(g2, bytestream2_tell_p(pb) - 1, SEEK_SET);
222         c = bytestream2_get_byte(g2);
223         for (i = 0; i < len; i++) {
224             bytestream2_put_byte(pb, c);
225         }
226     } else if (offset < 0) {
227         int start = bytestream2_tell_p(pb) - (-offset);
228
229         bytestream2_seek(g2, start, SEEK_SET);
230         for (i = 0; i < len; i++) {
231             bytestream2_put_byte(pb, bytestream2_get_byte(g2));
232         }
233     } else {
234         int start = bytestream2_tell_p(pb) + offset;
235
236         bytestream2_seek(g2, start, SEEK_SET);
237         for (i = 0; i < len; i++) {
238             bytestream2_put_byte(pb, bytestream2_get_byte(g2));
239         }
240     }
241 }
242
243 static int decompress_2(AVCodecContext *avctx)
244 {
245     GDVContext *gdv = avctx->priv_data;
246     GetByteContext *gb = &gdv->gb;
247     GetByteContext *g2 = &gdv->g2;
248     PutByteContext *pb = &gdv->pb;
249     Bits8 bits = { 0 };
250     int c, i;
251
252     bytestream2_init(g2, gdv->frame, gdv->frame_size);
253     bytestream2_skip_p(pb, PREAMBLE_SIZE);
254
255     for (c = 0; c < 256; c++) {
256         for (i = 0; i < 16; i++) {
257             gdv->frame[c * 16 + i] = c;
258         }
259     }
260
261     while (bytestream2_get_bytes_left_p(pb) > 0 && bytestream2_get_bytes_left(gb) > 0) {
262         int tag = read_bits2(&bits, gb);
263         if (tag == 0) {
264             bytestream2_put_byte(pb, bytestream2_get_byte(gb));
265         } else if (tag == 1) {
266             int b = bytestream2_get_byte(gb);
267             int len = (b & 0xF) + 3;
268             int top = (b >> 4) & 0xF;
269             int off = (bytestream2_get_byte(gb) << 4) + top - 4096;
270             lz_copy(pb, g2, off, len);
271         } else if (tag == 2) {
272             int len = (bytestream2_get_byte(gb)) + 2;
273             bytestream2_skip_p(pb, len);
274         } else {
275             break;
276         }
277     }
278
279     if (bytestream2_get_bytes_left_p(pb) > 0)
280         return AVERROR_INVALIDDATA;
281
282     return 0;
283 }
284
285 static int decompress_5(AVCodecContext *avctx, unsigned skip)
286 {
287     GDVContext *gdv = avctx->priv_data;
288     GetByteContext *gb = &gdv->gb;
289     GetByteContext *g2 = &gdv->g2;
290     PutByteContext *pb = &gdv->pb;
291     Bits8 bits = { 0 };
292
293     bytestream2_init(g2, gdv->frame, gdv->frame_size);
294     bytestream2_skip_p(pb, skip + PREAMBLE_SIZE);
295
296     while (bytestream2_get_bytes_left_p(pb) > 0 && bytestream2_get_bytes_left(gb) > 0) {
297         int tag = read_bits2(&bits, gb);
298         if (bytestream2_get_bytes_left(gb) < 1)
299             return AVERROR_INVALIDDATA;
300         if (tag == 0) {
301             bytestream2_put_byte(pb, bytestream2_get_byte(gb));
302         } else if (tag == 1) {
303             int b = bytestream2_get_byte(gb);
304             int len = (b & 0xF) + 3;
305             int top = b >> 4;
306             int off = (bytestream2_get_byte(gb) << 4) + top - 4096;
307             lz_copy(pb, g2, off, len);
308         } else if (tag == 2) {
309             int len;
310             int b = bytestream2_get_byte(gb);
311             if (b == 0) {
312                 return 0;
313             }
314             if (b != 0xFF) {
315                 len = b;
316             } else {
317                 len = bytestream2_get_le16(gb);
318             }
319             bytestream2_skip_p(pb, len + 1);
320         } else {
321             int b = bytestream2_get_byte(gb);
322             int len = (b & 0x3) + 2;
323             int off = -(b >> 2) - 1;
324             lz_copy(pb, g2, off, len);
325         }
326     }
327     if (bytestream2_get_bytes_left_p(pb) > 0)
328         return AVERROR_INVALIDDATA;
329     return 0;
330 }
331
332 static int decompress_68(AVCodecContext *avctx, unsigned skip, unsigned use8)
333 {
334     GDVContext *gdv = avctx->priv_data;
335     GetByteContext *gb = &gdv->gb;
336     GetByteContext *g2 = &gdv->g2;
337     PutByteContext *pb = &gdv->pb;
338     Bits32 bits;
339
340     bytestream2_init(g2, gdv->frame, gdv->frame_size);
341     bytestream2_skip_p(pb, skip + PREAMBLE_SIZE);
342     fill_bits32(&bits, gb);
343
344     while (bytestream2_get_bytes_left_p(pb) > 0 && bytestream2_get_bytes_left(gb) > 0) {
345         int tag = read_bits32(&bits, gb, 2);
346         if (tag == 0) {
347             int b = read_bits32(&bits, gb, 1);
348             if (b == 0) {
349                 bytestream2_put_byte(pb, bytestream2_get_byte(gb));
350             } else {
351                 int i, len = 2;
352                 int lbits = 0;
353                 while (1) {
354                     int val;
355
356                     lbits += 1;
357                     val = read_bits32(&bits, gb, lbits);
358                     len += val;
359                     if (val != ((1 << lbits) - 1)) {
360                         break;
361                     }
362                     if (lbits >= 16)
363                         return AVERROR_INVALIDDATA;
364                 }
365                 for (i = 0; i < len; i++) {
366                     bytestream2_put_byte(pb, bytestream2_get_byte(gb));
367                 }
368             }
369         } else if (tag == 1) {
370             int b = read_bits32(&bits, gb, 1);
371             int len;
372
373             if (b == 0) {
374                 len = (read_bits32(&bits, gb, 4)) + 2;
375             } else {
376                 int bb = bytestream2_get_byte(gb);
377                 if ((bb & 0x80) == 0) {
378                     len = bb + 18;
379                 } else {
380                     int top = (bb & 0x7F) << 8;
381                     len = top + bytestream2_get_byte(gb) + 146;
382                 }
383             }
384             bytestream2_skip_p(pb, len);
385         } else if (tag == 2) {
386             int i, subtag = read_bits32(&bits, gb, 2);
387
388             if (subtag != 3) {
389                 int top = (read_bits32(&bits, gb, 4)) << 8;
390                 int offs = top + bytestream2_get_byte(gb);
391                 if ((subtag != 0) || (offs <= 0xF80)) {
392                     int len = (subtag) + 3;
393                     lz_copy(pb, g2, (offs) - 4096, len);
394                 } else {
395                     int real_off, len, c1, c2;
396
397                     if (offs == 0xFFF) {
398                         return 0;
399                     }
400
401                     real_off = ((offs >> 4) & 0x7) + 1;
402                     len = ((offs & 0xF) + 2) * 2;
403                     c1 = gdv->frame[bytestream2_tell_p(pb) - real_off];
404                     c2 = gdv->frame[bytestream2_tell_p(pb) - real_off + 1];
405                     for (i = 0; i < len/2; i++) {
406                         bytestream2_put_byte(pb, c1);
407                         bytestream2_put_byte(pb, c2);
408                     }
409                 }
410             } else {
411                 int b = bytestream2_get_byte(gb);
412                 int off = ((b & 0x7F)) + 1;
413                 int len = ((b & 0x80) == 0) ? 2 : 3;
414
415                 lz_copy(pb, g2, -off, len);
416             }
417         } else {
418             int len;
419             int off;
420             if (use8) {
421                 int q, b = bytestream2_get_byte(gb);
422                 if ((b & 0xC0) == 0xC0) {
423                     len = ((b & 0x3F)) + 8;
424                     q = read_bits32(&bits, gb, 4);
425                     off = (q << 8) + (bytestream2_get_byte(gb)) + 1;
426                 } else {
427                     int ofs1;
428                     if ((b & 0x80) == 0) {
429                         len = ((b >> 4)) + 6;
430                         ofs1 = (b & 0xF);
431                     } else {
432                         len = ((b & 0x3F)) + 14;
433                         ofs1 = read_bits32(&bits, gb, 4);
434                     }
435                     off = (ofs1 << 8) + (bytestream2_get_byte(gb)) - 4096;
436                 }
437             } else {
438                 int ofs1, b = bytestream2_get_byte(gb);
439
440                 if ((b >> 4) == 0xF) {
441                     len = bytestream2_get_byte(gb) + 21;
442                 } else {
443                     len = (b >> 4) + 6;
444                 }
445                 ofs1 = (b & 0xF);
446                 off = (ofs1 << 8) + bytestream2_get_byte(gb) - 4096;
447             }
448             lz_copy(pb, g2, off, len);
449         }
450     }
451
452     if (bytestream2_get_bytes_left_p(pb) > 0)
453         return AVERROR_INVALIDDATA;
454
455     return 0;
456 }
457
458 static int gdv_decode_frame(AVCodecContext *avctx, void *data,
459                             int *got_frame, AVPacket *avpkt)
460 {
461     GDVContext *gdv = avctx->priv_data;
462     GetByteContext *gb = &gdv->gb;
463     PutByteContext *pb = &gdv->pb;
464     AVFrame *frame = data;
465     int ret, i;
466     int compression;
467     unsigned flags;
468     uint8_t *dst;
469
470     bytestream2_init(gb, avpkt->data, avpkt->size);
471     bytestream2_init_writer(pb, gdv->frame, gdv->frame_size);
472
473     flags = bytestream2_get_le32(gb);
474     compression = flags & 0xF;
475
476     if (compression == 4 || compression == 7 || compression > 8)
477         return AVERROR_INVALIDDATA;
478
479     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
480         return ret;
481     ff_copy_palette(gdv->pal, avpkt, avctx);
482
483     if (compression < 2 && bytestream2_get_bytes_left(gb) < 256*3)
484         return AVERROR_INVALIDDATA;
485     rescale(gdv, gdv->frame, avctx->width, avctx->height,
486             !!(flags & 0x10), !!(flags & 0x20));
487
488     switch (compression) {
489     case 1:
490         memset(gdv->frame + PREAMBLE_SIZE, 0, gdv->frame_size - PREAMBLE_SIZE);
491     case 0:
492         for (i = 0; i < 256; i++) {
493             unsigned r = bytestream2_get_byte(gb);
494             unsigned g = bytestream2_get_byte(gb);
495             unsigned b = bytestream2_get_byte(gb);
496             gdv->pal[i] = 0xFFU << 24 | r << 18 | g << 10 | b << 2;
497         }
498         break;
499     case 2:
500         ret = decompress_2(avctx);
501         break;
502     case 3:
503         break;
504     case 5:
505         ret = decompress_5(avctx, flags >> 8);
506         break;
507     case 6:
508         ret = decompress_68(avctx, flags >> 8, 0);
509         break;
510     case 8:
511         ret = decompress_68(avctx, flags >> 8, 1);
512         break;
513     default:
514         av_assert0(0);
515     }
516     if (ret < 0)
517         return ret;
518
519     memcpy(frame->data[1], gdv->pal, AVPALETTE_SIZE);
520     dst = frame->data[0];
521
522     if (!gdv->scale_v && !gdv->scale_h) {
523         int sidx = PREAMBLE_SIZE, didx = 0;
524         int y;
525
526         for (y = 0; y < avctx->height; y++) {
527             memcpy(dst + didx, gdv->frame + sidx, avctx->width);
528             sidx += avctx->width;
529             didx += frame->linesize[0];
530         }
531     } else {
532         int sidx = PREAMBLE_SIZE, didx = 0;
533         int y;
534
535         for (y = 0; y < avctx->height; y++) {
536             if (!gdv->scale_v) {
537                 memcpy(dst + didx, gdv->frame + sidx, avctx->width);
538             } else {
539                 uint8_t *dst2 = dst + didx;
540                 uint8_t *src2 = gdv->frame + sidx;
541
542                 scaleup(dst2, src2, avctx->width);
543             }
544             if (!gdv->scale_h || ((y & 1) == 1)) {
545                 sidx += !gdv->scale_v ? avctx->width : avctx->width/2;
546             }
547             didx += frame->linesize[0];
548         }
549     }
550
551     *got_frame = 1;
552
553     return avpkt->size;
554 }
555
556 static av_cold int gdv_decode_close(AVCodecContext *avctx)
557 {
558     GDVContext *gdv = avctx->priv_data;
559     av_freep(&gdv->frame);
560     return 0;
561 }
562
563 const AVCodec ff_gdv_decoder = {
564     .name           = "gdv",
565     .long_name      = NULL_IF_CONFIG_SMALL("Gremlin Digital Video"),
566     .type           = AVMEDIA_TYPE_VIDEO,
567     .id             = AV_CODEC_ID_GDV,
568     .priv_data_size = sizeof(GDVContext),
569     .init           = gdv_decode_init,
570     .close          = gdv_decode_close,
571     .decode         = gdv_decode_frame,
572     .capabilities   = AV_CODEC_CAP_DR1,
573     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
574 };