1 /*
2  * Escape 124 Video Decoder
3  * Copyright (C) 2008 Eli Friedman (eli.friedman@gmail.com)
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 <inttypes.h>
23 #include <stdlib.h>
24 #include <SDL2/SDL.h>
25 
26 #include "../tiny_codec.h"
27 #define BITSTREAM_READER_LE
28 #include "../internal/get_bits.h"
29 
30 typedef union MacroBlock
31 {
32     uint16_t pixels[4];
33     uint32_t pixels32[2];
34 } MacroBlock;
35 
36 typedef union SuperBlock
37 {
38     uint16_t pixels[64];
39     uint32_t pixels32[32];
40 } SuperBlock;
41 
42 typedef struct CodeBook
43 {
44     unsigned depth;
45     unsigned size;
46     MacroBlock *blocks;
47 } CodeBook;
48 
49 
50 typedef struct Escape124Context
51 {
52     unsigned num_superblocks;
53     uint32_t line_bytes;
54     uint8_t *buff1;
55     uint8_t *buff2;
56     CodeBook codebooks[3];
57 } Escape124Context;
58 
59 /**
60  * Initialize the decoder
61  * @param avctx decoder context
62  * @return 0 success, negative on error
63  */
escape124_free_data(void * data)64 static void escape124_free_data(void *data)
65 {
66     if(data)
67     {
68         unsigned i;
69         Escape124Context *s = (Escape124Context*)data;
70         for (i = 0; i < 3; i++)
71         {
72             free(s->codebooks[i].blocks);
73         }
74         free(s->buff1);
75         free(s->buff2);
76         free(s);
77     }
78 }
79 
unpack_codebook(GetBitContext * gb,unsigned depth,unsigned size)80 static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth, unsigned size)
81 {
82     unsigned i, j;
83     CodeBook cb = { 0 };
84 
85     if (size >= INT_MAX / 34 || get_bits_left(gb) < size * 34)
86         return cb;
87 
88     if (size >= INT_MAX / sizeof(MacroBlock))
89         return cb;
90 
91     cb.blocks = malloc(size ? size * sizeof(MacroBlock) : 1);
92     if (!cb.blocks)
93         return cb;
94 
95     cb.depth = depth;
96     cb.size = size;
97     for (i = 0; i < size; i++)
98     {
99         unsigned mask_bits = get_bits(gb, 4);
100         unsigned color0 = get_bits(gb, 15);
101         unsigned color1 = get_bits(gb, 15);
102 
103         for (j = 0; j < 4; j++)
104         {
105             if (mask_bits & (1 << j))
106                 cb.blocks[i].pixels[j] = color1;
107             else
108                 cb.blocks[i].pixels[j] = color0;
109         }
110     }
111     return cb;
112 }
113 
decode_skip_count(GetBitContext * gb)114 static unsigned decode_skip_count(GetBitContext* gb)
115 {
116     unsigned value;
117     // This function reads a maximum of 23 bits,
118     // which is within the padding space
119     if (get_bits_left(gb) < 1)
120         return -1;
121     value = get_bits1(gb);
122     if (!value)
123         return value;
124 
125     value += get_bits(gb, 3);
126     if (value != (1 + ((1 << 3) - 1)))
127         return value;
128 
129     value += get_bits(gb, 7);
130     if (value != (1 + ((1 << 3) - 1)) + ((1 << 7) - 1))
131         return value;
132 
133     return value + get_bits(gb, 12);
134 }
135 
decode_macroblock(struct tiny_codec_s * avctx,GetBitContext * gb,unsigned * codebook_index,int superblock_index)136 static MacroBlock decode_macroblock(struct tiny_codec_s *avctx, GetBitContext *gb, unsigned *codebook_index, int superblock_index)
137 {
138     // This function reads a maximum of 22 bits; the callers
139     // guard this function appropriately
140     unsigned block_index, depth;
141     int value = get_bits1(gb);
142     if (value)
143     {
144         static const int8_t transitions[3][2] = { {2, 1}, {0, 2}, {1, 0} };
145         value = get_bits1(gb);
146         *codebook_index = transitions[*codebook_index][value];
147     }
148     Escape124Context *s = (Escape124Context*)avctx->video.priv_data;
149     depth = s->codebooks[*codebook_index].depth;
150 
151     // depth = 0 means that this shouldn't read any bits;
152     // in theory, this is the same as get_bits(gb, 0), but
153     // that doesn't actually work.
154     block_index = get_bitsz(gb, depth);
155 
156     if (*codebook_index == 1)
157     {
158         block_index += superblock_index << s->codebooks[1].depth;
159     }
160 
161     // This condition can occur with invalid bitstreams and
162     // *codebook_index == 2
163     if (block_index >= s->codebooks[*codebook_index].size)
164         return (MacroBlock) { { 0 } };
165 
166     return s->codebooks[*codebook_index].blocks[block_index];
167 }
168 
insert_mb_into_sb(SuperBlock * sb,MacroBlock mb,unsigned index)169 static void insert_mb_into_sb(SuperBlock* sb, MacroBlock mb, unsigned index)
170 {
171    // Formula: ((index / 4) * 16 + (index % 4) * 2) / 2
172    uint32_t *dst = sb->pixels32 + index + (index & -4);
173 
174    // This technically violates C99 aliasing rules, but it should be safe.
175    dst[0] = mb.pixels32[0];
176    dst[4] = mb.pixels32[1];
177 }
178 
copy_superblock(uint16_t * dest,unsigned dest_stride,uint16_t * src,unsigned src_stride)179 static void copy_superblock(uint16_t* dest, unsigned dest_stride,
180                             uint16_t* src, unsigned src_stride)
181 {
182     unsigned y;
183     if (src)
184         for (y = 0; y < 8; y++)
185             memcpy(dest + y * dest_stride, src + y * src_stride,
186                    sizeof(uint16_t) * 8);
187     else
188         for (y = 0; y < 8; y++)
189             memset(dest + y * dest_stride, 0, sizeof(uint16_t) * 8);
190 }
191 
192 static const uint16_t mask_matrix[] = {0x1,   0x2,   0x10,   0x20,
193                                        0x4,   0x8,   0x40,   0x80,
194                                        0x100, 0x200, 0x1000, 0x2000,
195                                        0x400, 0x800, 0x4000, 0x8000};
196 
escape124_decode_frame(struct tiny_codec_s * avctx,struct AVPacket * avpkt)197 static int escape124_decode_frame(struct tiny_codec_s *avctx, struct AVPacket *avpkt)
198 {
199     Escape124Context *s = (Escape124Context*)avctx->video.priv_data;
200 
201     GetBitContext gb;
202     unsigned frame_flags, frame_size;
203     unsigned i;
204 
205     unsigned superblock_index, cb_index = 1,
206              superblock_col_index = 0,
207              superblocks_per_row = avctx->video.width / 8, skip = -1;
208 
209     uint16_t* old_frame_data, *new_frame_data;
210     unsigned old_stride, new_stride;
211 
212     int ret;
213 
214     if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
215         return ret;
216 
217     // This call also guards the potential depth reads for the
218     // codebook unpacking.
219     if (get_bits_left(&gb) < 64)
220         return -1;
221 
222     frame_flags = get_bits_long(&gb, 32);
223     frame_size  = get_bits_long(&gb, 32);
224 
225     // Leave last frame unchanged
226     // FIXME: Is this necessary?  I haven't seen it in any real samples
227     if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000))
228     {
229         //av_log(avctx, AV_LOG_DEBUG, "Skipping frame\n");
230         return frame_size;
231     }
232 
233     for (i = 0; i < 3; i++)
234     {
235         if (frame_flags & (1 << (17 + i)))
236         {
237             unsigned cb_depth, cb_size;
238             if (i == 2)
239             {
240                 // This codebook can be cut off at places other than
241                 // powers of 2, leaving some of the entries undefined.
242                 cb_size = get_bits_long(&gb, 20);
243                 if (!cb_size)
244                 {
245                     //av_log(avctx, AV_LOG_ERROR, "Invalid codebook size 0.\n");
246                     return -1;
247                 }
248                 cb_depth = av_log2(cb_size - 1) + 1;
249             }
250             else
251             {
252                 cb_depth = get_bits(&gb, 4);
253                 if (i == 0)
254                 {
255                     // This is the most basic codebook: pow(2,depth) entries
256                     // for a depth-length key
257                     cb_size = 1 << cb_depth;
258                 }
259                 else
260                 {
261                     // This codebook varies per superblock
262                     // FIXME: I don't think this handles integer overflow
263                     // properly
264                     cb_size = s->num_superblocks << cb_depth;
265                 }
266             }
267             if (s->num_superblocks >= INT_MAX >> cb_depth)
268             {
269                 //av_log(avctx, AV_LOG_ERROR, "Depth or num_superblocks are too large\n");
270                 return -1;
271             }
272 
273             free(s->codebooks[i].blocks);
274             s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size);
275             if (!s->codebooks[i].blocks)
276                 return -1;
277         }
278     }
279 
280     new_frame_data = (uint16_t*)s->buff1;
281     new_stride = s->line_bytes / 2;
282     old_frame_data = (uint16_t*)s->buff2;
283     old_stride = s->line_bytes / 2;
284     //memcpy(old_frame_data, new_frame_data, s->line_bytes * avctx->video.height);
285 
286     for (superblock_index = 0; superblock_index < s->num_superblocks; superblock_index++)
287     {
288         MacroBlock mb;
289         SuperBlock sb;
290         unsigned multi_mask = 0;
291 
292         if (skip == -1)
293         {
294             // Note that this call will make us skip the rest of the blocks
295             // if the frame prematurely ends
296             skip = decode_skip_count(&gb);
297         }
298 
299         if (skip)
300         {
301             copy_superblock(new_frame_data, new_stride,
302                             old_frame_data, old_stride);
303         }
304         else
305         {
306             copy_superblock(sb.pixels, 8,
307                             old_frame_data, old_stride);
308 
309             while (get_bits_left(&gb) >= 1 && !get_bits1(&gb))
310             {
311                 unsigned mask;
312                 mb = decode_macroblock(avctx, &gb, &cb_index, superblock_index);
313                 mask = get_bits(&gb, 16);
314                 multi_mask |= mask;
315                 for (i = 0; i < 16; i++)
316                 {
317                     if (mask & mask_matrix[i])
318                     {
319                         insert_mb_into_sb(&sb, mb, i);
320                     }
321                 }
322             }
323 
324             if (!get_bits1(&gb))
325             {
326                 unsigned inv_mask = get_bits(&gb, 4);
327                 for (i = 0; i < 4; i++)
328                 {
329                     if (inv_mask & (1 << i))
330                     {
331                         multi_mask ^= 0xF << i*4;
332                     }
333                     else
334                     {
335                         multi_mask ^= get_bits(&gb, 4) << i*4;
336                     }
337                 }
338 
339                 for (i = 0; i < 16; i++)
340                 {
341                     if (multi_mask & mask_matrix[i])
342                     {
343                         mb = decode_macroblock(avctx, &gb, &cb_index, superblock_index);
344                         insert_mb_into_sb(&sb, mb, i);
345                     }
346                 }
347             }
348             else if (frame_flags & (1 << 16))
349             {
350                 while (get_bits_left(&gb) >= 1 && !get_bits1(&gb))
351                 {
352                     mb = decode_macroblock(avctx, &gb, &cb_index, superblock_index);
353                     insert_mb_into_sb(&sb, mb, get_bits(&gb, 4));
354                 }
355             }
356 
357             copy_superblock(new_frame_data, new_stride, sb.pixels, 8);
358         }
359 
360         superblock_col_index++;
361         new_frame_data += 8;
362         if (old_frame_data)
363             old_frame_data += 8;
364         if (superblock_col_index == superblocks_per_row)
365         {
366             new_frame_data += new_stride * 8 - superblocks_per_row * 8;
367             if (old_frame_data)
368                 old_frame_data += old_stride * 8 - superblocks_per_row * 8;
369             superblock_col_index = 0;
370         }
371         skip--;
372     }
373 
374     if(avctx->video.rgba)
375     {
376         uint8_t *rgba = avctx->video.rgba;
377         for(i = 0; i < avctx->video.height; ++i)
378         {
379             uint16_t *px = (uint16_t*)s->buff1 + i * new_stride;
380             for(int j = 0; j < avctx->video.width; ++j, ++px)
381             {
382                 *rgba++ = ((*px) & 0x7C00) >> (10 - 3);
383                 *rgba++ = ((*px) & 0x03E0) >> (5 - 3);
384                 *rgba++ = ((*px) & 0x001F) << 3 ;
385                 *rgba++ = 0xFF;
386             }
387         }
388     }
389     FFSWAP(uint8_t*, s->buff1, s->buff2);
390 
391     return frame_size;
392 }
393 
escape124_decode_init(struct tiny_codec_s * avctx)394 void escape124_decode_init(struct tiny_codec_s *avctx)
395 {
396     avctx->video.decode = escape124_decode_frame;
397     if(!avctx->video.priv_data)
398     {
399         Escape124Context *s = (Escape124Context*)malloc(sizeof(Escape124Context));
400         avctx->video.priv_data = s;
401         avctx->video.free_data = escape124_free_data;
402         s->num_superblocks = ((unsigned)avctx->video.width / 8) *
403                              ((unsigned)avctx->video.height / 8);
404         s->line_bytes = avctx->video.width * 2;
405         s->buff1 = (uint8_t*)calloc(1, s->line_bytes * avctx->video.height);
406         s->buff2 = (uint8_t*)calloc(1, s->line_bytes * avctx->video.height);
407         for(int i = 0; i < 3; i++)
408         {
409             s->codebooks[i].blocks = NULL;
410         }
411     }
412 }
413