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