1 /*
2  * Infinity IMM4 decoder
3  *
4  * Copyright (c) 2018 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 <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "libavutil/mem_internal.h"
28 #include "libavutil/thread.h"
29 
30 #include "avcodec.h"
31 #include "bswapdsp.h"
32 #include "copy_block.h"
33 #include "get_bits.h"
34 #include "idctdsp.h"
35 #include "internal.h"
36 
37 #define CBPLO_VLC_BITS   6
38 #define CBPHI_VLC_BITS   6
39 #define BLKTYPE_VLC_BITS 9
40 #define BLOCK_VLC_BITS  12
41 
42 typedef struct IMM4Context {
43     BswapDSPContext bdsp;
44     GetBitContext  gb;
45 
46     AVFrame *prev_frame;
47     uint8_t *bitstream;
48     int bitstream_size;
49 
50     int factor;
51     unsigned lo;
52     unsigned hi;
53 
54     ScanTable intra_scantable;
55     DECLARE_ALIGNED(32, int16_t, block)[6][64];
56     IDCTDSPContext idsp;
57 } IMM4Context;
58 
59 static const uint8_t intra_cb[] = {
60     24, 18, 12
61 };
62 
63 static const uint8_t inter_cb[] = {
64     30, 20, 15
65 };
66 
67 static const uint8_t cbplo[][2] = {
68     {    0,-6 }, { 0x01, 6 }, { 0x02, 6 }, { 0x03, 6 }, { 0x00, 4 },
69     { 0x01, 3 }, { 0x02, 3 }, { 0x03, 3 }, { 0x00, 1 },
70 };
71 
72 static const uint8_t cbphi_bits[] = {
73     4, 5, 5, 4, 5, 4, 6, 4, 5, 6, 4, 4, 4, 4, 4, 2
74 };
75 
76 static const uint8_t cbphi_codes[] = {
77     3, 5, 4, 9, 3, 7, 2, 11, 2, 3, 5, 10, 4, 8, 6, 3
78 };
79 
80 static const uint8_t blktype[][2] = {
81     {    0,-8 }, { 0x34, 9 }, {    0,-9 }, { 0x14, 9 }, {    0,-9 },
82     { 0x23, 8 }, { 0x13, 8 }, { 0x32, 8 }, { 0x33, 7 }, { 0x22, 7 },
83     { 0x12, 7 }, { 0x21, 7 }, { 0x11, 7 }, { 0x04, 6 }, { 0x30, 6 },
84     { 0x03, 5 }, { 0x20, 4 }, { 0x10, 4 }, { 0x02, 3 }, { 0x01, 3 },
85     { 0x00, 1 },
86 };
87 
88 static const uint16_t block_symbols[] = {
89          0, 0x4082, 0x4003, 0x000B, 0x000A, 0x4E01, 0x4D81, 0x4D01, 0x4C81,
90     0x0482, 0x0402, 0x0382, 0x0302, 0x0282, 0x0183, 0x0103, 0x0084, 0x000C,
91     0x0085, 0x0B81, 0x0C01, 0x4E81, 0x4F01, 0x4F81, 0x5001, 0x0086, 0x0104,
92     0x0203, 0x0283, 0x0303, 0x0502, 0x0C81, 0x0D01, 0x5081, 0x5101, 0x5181,
93     0x5201, 0x5281, 0x5301, 0x5381, 0x5401, 0x0000, 0x0009, 0x0008, 0x4C01,
94     0x4B81, 0x4B01, 0x4A81, 0x4A01, 0x4981, 0x4901, 0x4881, 0x4002, 0x0B01,
95     0x0A81, 0x0A01, 0x0981, 0x0901, 0x0881, 0x0801, 0x0781, 0x0202, 0x0182,
96     0x0007, 0x0006, 0x4801, 0x4781, 0x4701, 0x4681, 0x4601, 0x4581, 0x4501,
97     0x4481, 0x0701, 0x0681, 0x0102, 0x0083, 0x0005, 0x4401, 0x4381, 0x4301,
98     0x4281, 0x0601, 0x0581, 0x0501, 0x0004, 0x4201, 0x4181, 0x4101, 0x4081,
99     0x0481, 0x0401, 0x0381, 0x0301, 0x0082, 0x0003, 0x0281, 0x0201, 0x0181,
100     0x4001, 0x0001, 0x0081, 0x0101, 0x0002,
101 };
102 
103 static const uint8_t block_bits[] = {
104     -9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11,
105     11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
106     12, 12, 12,  7, 10, 10,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
107      9,  9,  9,  9,  9,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
108      8,  8,  7,  7,  7,  7,  7,  7,  7,  7,  6,  6,  6,  6,  6,  6,  6,  6,  6,
109      6,  5,  5,  5,  4,  2,  3,  4,  4,
110 };
111 
112 static VLC cbplo_tab;
113 static VLC cbphi_tab;
114 static VLC blktype_tab;
115 static VLC block_tab;
116 
get_cbphi(GetBitContext * gb,int x)117 static int get_cbphi(GetBitContext *gb, int x)
118 {
119     int value;
120 
121     value = get_vlc2(gb, cbphi_tab.table, CBPHI_VLC_BITS, 1);
122     if (value < 0)
123         return AVERROR_INVALIDDATA;
124 
125     return x ? value : 15 - value;
126 }
127 
decode_block(AVCodecContext * avctx,GetBitContext * gb,int block,int factor,int flag,int offset,int flag2)128 static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
129                         int block, int factor, int flag, int offset, int flag2)
130 {
131     IMM4Context *s = avctx->priv_data;
132     const uint8_t *scantable = s->intra_scantable.permutated;
133     int i, last, len, factor2;
134 
135     for (i = !flag; i < 64; i++) {
136         int value;
137 
138         value = get_vlc2(gb, block_tab.table, BLOCK_VLC_BITS, 1);
139         if (value < 0)
140             return AVERROR_INVALIDDATA;
141         if (value == 0) {
142             last = get_bits1(gb);
143             len = get_bits(gb, 6);
144             factor2 = get_sbits(gb, 8);
145         } else {
146             factor2 = value & 0x7F;
147             last = (value >> 14) & 1;
148             len = (value >> 7) & 0x3F;
149             if (get_bits1(gb))
150                 factor2 = -factor2;
151         }
152         i += len;
153         if (i >= 64)
154             break;
155         s->block[block][scantable[i]] = offset * (factor2 < 0 ? -1 : 1) + factor * factor2;
156         if (last)
157             break;
158     }
159 
160     if (s->hi == 2 && flag2 && block < 4) {
161         if (flag)
162             s->block[block][scantable[0]]  *= 2;
163         s->block[block][scantable[1]]  *= 2;
164         s->block[block][scantable[8]]  *= 2;
165         s->block[block][scantable[16]] *= 2;
166     }
167 
168     return 0;
169 }
170 
decode_blocks(AVCodecContext * avctx,GetBitContext * gb,unsigned cbp,int flag,int offset,unsigned flag2)171 static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
172                          unsigned cbp, int flag, int offset, unsigned flag2)
173 {
174     IMM4Context *s = avctx->priv_data;
175     const uint8_t *scantable = s->intra_scantable.permutated;
176     int ret, i;
177 
178     memset(s->block, 0, sizeof(s->block));
179 
180     for (i = 0; i < 6; i++) {
181         if (!flag) {
182             int x = get_bits(gb, 8);
183 
184             if (x == 255)
185                 x = 128;
186             x *= 8;
187 
188             s->block[i][scantable[0]] = x;
189         }
190 
191         if (cbp & (1 << (5 - i))) {
192             ret = decode_block(avctx, gb, i, s->factor, flag, offset, flag2);
193             if (ret < 0)
194                 return ret;
195         }
196     }
197 
198     return 0;
199 }
200 
decode_intra(AVCodecContext * avctx,GetBitContext * gb,AVFrame * frame)201 static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame)
202 {
203     IMM4Context *s = avctx->priv_data;
204     int ret, x, y, offset = 0;
205 
206     if (s->hi == 0) {
207         if (s->lo > 2)
208             return AVERROR_INVALIDDATA;
209         s->factor = intra_cb[s->lo];
210     } else {
211         s->factor = s->lo * 2;
212     }
213 
214     if (s->hi) {
215         offset = s->factor;
216         offset >>= 1;
217         if (!(offset & 1))
218             offset--;
219     }
220 
221     for (y = 0; y < avctx->height; y += 16) {
222         for (x = 0; x < avctx->width; x += 16) {
223             unsigned flag, cbphi, cbplo;
224 
225             cbplo = get_vlc2(gb, cbplo_tab.table, CBPLO_VLC_BITS, 1);
226             flag = get_bits1(gb);
227 
228             cbphi = get_cbphi(gb, 1);
229 
230             ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag);
231             if (ret < 0)
232                 return ret;
233 
234             s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
235                              frame->linesize[0], s->block[0]);
236             s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
237                              frame->linesize[0], s->block[1]);
238             s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
239                              frame->linesize[0], s->block[2]);
240             s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
241                              frame->linesize[0], s->block[3]);
242             s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
243                              frame->linesize[1], s->block[4]);
244             s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
245                              frame->linesize[2], s->block[5]);
246         }
247     }
248 
249     return 0;
250 }
251 
decode_inter(AVCodecContext * avctx,GetBitContext * gb,AVFrame * frame,AVFrame * prev)252 static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
253                         AVFrame *frame, AVFrame *prev)
254 {
255     IMM4Context *s = avctx->priv_data;
256     int ret, x, y, offset = 0;
257 
258     if (s->hi == 0) {
259         if (s->lo > 2)
260             return AVERROR_INVALIDDATA;
261         s->factor = inter_cb[s->lo];
262     } else {
263         s->factor = s->lo * 2;
264     }
265 
266     if (s->hi) {
267         offset = s->factor;
268         offset >>= 1;
269         if (!(offset & 1))
270             offset--;
271     }
272 
273     for (y = 0; y < avctx->height; y += 16) {
274         for (x = 0; x < avctx->width; x += 16) {
275             int reverse, intra_block, value;
276             unsigned cbphi, cbplo, flag2 = 0;
277 
278             if (get_bits1(gb)) {
279                 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
280                              prev->data[0] + y * prev->linesize[0] + x,
281                              frame->linesize[0], prev->linesize[0], 16);
282                 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
283                             prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
284                             frame->linesize[1], prev->linesize[1], 8);
285                 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
286                             prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
287                             frame->linesize[2], prev->linesize[2], 8);
288                 continue;
289             }
290 
291             value = get_vlc2(gb, blktype_tab.table, BLKTYPE_VLC_BITS, 1);
292             if (value < 0)
293                 return AVERROR_INVALIDDATA;
294 
295             intra_block = value & 0x07;
296             reverse = intra_block == 3;
297             if (reverse)
298                 flag2 = get_bits1(gb);
299 
300             cbplo = value >> 4;
301             cbphi = get_cbphi(gb, reverse);
302             if (intra_block) {
303                 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag2);
304                 if (ret < 0)
305                     return ret;
306 
307                 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
308                                  frame->linesize[0], s->block[0]);
309                 s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
310                                  frame->linesize[0], s->block[1]);
311                 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
312                                  frame->linesize[0], s->block[2]);
313                 s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
314                                  frame->linesize[0], s->block[3]);
315                 s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
316                                  frame->linesize[1], s->block[4]);
317                 s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
318                                  frame->linesize[2], s->block[5]);
319             } else {
320                 flag2 = get_bits1(gb);
321                 skip_bits1(gb);
322                 ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1, offset, flag2);
323                 if (ret < 0)
324                     return ret;
325 
326                 copy_block16(frame->data[0] + y * frame->linesize[0] + x,
327                              prev->data[0] + y * prev->linesize[0] + x,
328                              frame->linesize[0], prev->linesize[0], 16);
329                 copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
330                             prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
331                             frame->linesize[1], prev->linesize[1], 8);
332                 copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
333                             prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
334                             frame->linesize[2], prev->linesize[2], 8);
335 
336                 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x,
337                                  frame->linesize[0], s->block[0]);
338                 s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x + 8,
339                                  frame->linesize[0], s->block[1]);
340                 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x,
341                                  frame->linesize[0], s->block[2]);
342                 s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
343                                  frame->linesize[0], s->block[3]);
344                 s->idsp.idct_add(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
345                                  frame->linesize[1], s->block[4]);
346                 s->idsp.idct_add(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
347                                  frame->linesize[2], s->block[5]);
348             }
349         }
350     }
351 
352     return 0;
353 }
354 
decode_frame(AVCodecContext * avctx,void * data,int * got_frame,AVPacket * avpkt)355 static int decode_frame(AVCodecContext *avctx, void *data,
356                         int *got_frame, AVPacket *avpkt)
357 {
358     IMM4Context *s = avctx->priv_data;
359     GetBitContext *gb = &s->gb;
360     AVFrame *frame = data;
361     int width, height;
362     unsigned type;
363     int ret, scaled;
364 
365     if (avpkt->size <= 32)
366         return AVERROR_INVALIDDATA;
367 
368     av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
369                           FFALIGN(avpkt->size, 4));
370     if (!s->bitstream)
371         return AVERROR(ENOMEM);
372 
373     s->bdsp.bswap_buf((uint32_t *)s->bitstream,
374                       (uint32_t *)avpkt->data,
375                       (avpkt->size + 3) >> 2);
376 
377     if ((ret = init_get_bits8(gb, s->bitstream, FFALIGN(avpkt->size, 4))) < 0)
378         return ret;
379 
380     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
381     avctx->color_range = AVCOL_RANGE_JPEG;
382 
383     width = avctx->width;
384     height = avctx->height;
385 
386     scaled = avpkt->data[8];
387     if (scaled < 2) {
388         int mode = avpkt->data[10];
389 
390         switch (mode) {
391         case 1:
392             width = 352;
393             height = 240;
394             break;
395         case 2:
396             width = 704;
397             height = 240;
398             break;
399         case 4:
400             width = 480;
401             height = 704;
402             break;
403         case 17:
404             width = 352;
405             height = 288;
406             break;
407         case 18:
408             width = 704;
409             height = 288;
410             break;
411         default:
412             width = 704;
413             height = 576;
414             break;
415         }
416     }
417 
418     skip_bits_long(gb, 24 * 8);
419     type = get_bits_long(gb, 32);
420     s->hi = get_bits(gb, 16);
421     s->lo = get_bits(gb, 16);
422 
423     switch (type) {
424     case 0x19781977:
425         frame->key_frame = 1;
426         frame->pict_type = AV_PICTURE_TYPE_I;
427         break;
428     case 0x12250926:
429         frame->key_frame = 0;
430         frame->pict_type = AV_PICTURE_TYPE_P;
431         break;
432     default:
433         avpriv_request_sample(avctx, "type %X", type);
434         return AVERROR_PATCHWELCOME;
435     }
436 
437     if (avctx->width  != width ||
438         avctx->height != height) {
439         if (!frame->key_frame) {
440             av_log(avctx, AV_LOG_ERROR, "Frame size change is unsupported.\n");
441             return AVERROR_INVALIDDATA;
442         }
443         av_frame_unref(s->prev_frame);
444     }
445 
446     ret = ff_set_dimensions(avctx, width, height);
447     if (ret < 0)
448         return ret;
449 
450     if ((ret = ff_get_buffer(avctx, frame, frame->key_frame ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
451         return ret;
452 
453     if (frame->key_frame) {
454         ret = decode_intra(avctx, gb, frame);
455         if (ret < 0)
456             return ret;
457 
458         av_frame_unref(s->prev_frame);
459         if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
460             return ret;
461     } else {
462         if (!s->prev_frame->data[0]) {
463             av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
464             return AVERROR_INVALIDDATA;
465         }
466 
467         ret = decode_inter(avctx, gb, frame, s->prev_frame);
468         if (ret < 0)
469             return ret;
470     }
471 
472     *got_frame = 1;
473 
474     return avpkt->size;
475 }
476 
imm4_init_static_data(void)477 static av_cold void imm4_init_static_data(void)
478 {
479     INIT_VLC_STATIC_FROM_LENGTHS(&cbplo_tab, CBPLO_VLC_BITS, FF_ARRAY_ELEMS(cbplo),
480                                  &cbplo[0][1], 2, &cbplo[0][0], 2, 1,
481                                  0, 0, 1 << CBPLO_VLC_BITS);
482 
483     INIT_VLC_SPARSE_STATIC(&cbphi_tab, CBPHI_VLC_BITS, FF_ARRAY_ELEMS(cbphi_bits),
484                            cbphi_bits, 1, 1, cbphi_codes, 1, 1, NULL, 0, 0, 64);
485 
486     INIT_VLC_STATIC_FROM_LENGTHS(&blktype_tab, BLKTYPE_VLC_BITS, FF_ARRAY_ELEMS(blktype),
487                                  &blktype[0][1], 2, &blktype[0][0], 2, 1,
488                                  0, 0, 1 << BLKTYPE_VLC_BITS);
489 
490     INIT_VLC_STATIC_FROM_LENGTHS(&block_tab, BLOCK_VLC_BITS, FF_ARRAY_ELEMS(block_bits),
491                                  block_bits, 1, block_symbols, 2, 2,
492                                  0, 0, 1 << BLOCK_VLC_BITS);
493 }
494 
decode_init(AVCodecContext * avctx)495 static av_cold int decode_init(AVCodecContext *avctx)
496 {
497     static AVOnce init_static_once = AV_ONCE_INIT;
498     IMM4Context *s = avctx->priv_data;
499     uint8_t table[64];
500 
501     for (int i = 0; i < 64; i++)
502         table[i] = i;
503 
504     ff_bswapdsp_init(&s->bdsp);
505     ff_idctdsp_init(&s->idsp, avctx);
506     ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, table);
507 
508     s->prev_frame = av_frame_alloc();
509     if (!s->prev_frame)
510         return AVERROR(ENOMEM);
511 
512     ff_thread_once(&init_static_once, imm4_init_static_data);
513 
514     return 0;
515 }
516 
decode_flush(AVCodecContext * avctx)517 static void decode_flush(AVCodecContext *avctx)
518 {
519     IMM4Context *s = avctx->priv_data;
520 
521     av_frame_unref(s->prev_frame);
522 }
523 
decode_close(AVCodecContext * avctx)524 static av_cold int decode_close(AVCodecContext *avctx)
525 {
526     IMM4Context *s = avctx->priv_data;
527 
528     av_frame_free(&s->prev_frame);
529     av_freep(&s->bitstream);
530     s->bitstream_size = 0;
531 
532     return 0;
533 }
534 
535 AVCodec ff_imm4_decoder = {
536     .name             = "imm4",
537     .long_name        = NULL_IF_CONFIG_SMALL("Infinity IMM4"),
538     .type             = AVMEDIA_TYPE_VIDEO,
539     .id               = AV_CODEC_ID_IMM4,
540     .priv_data_size   = sizeof(IMM4Context),
541     .init             = decode_init,
542     .close            = decode_close,
543     .decode           = decode_frame,
544     .flush            = decode_flush,
545     .capabilities     = AV_CODEC_CAP_DR1,
546     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
547                         FF_CODEC_CAP_INIT_CLEANUP,
548 };
549