(f)printf() is disallowed in libavcodec, compilation will fail now if its used, excep...
[ffmpeg.git] / libavcodec / truemotion1.c
1 /*
2  * Duck TrueMotion 1.0 Decoder
3  * Copyright (C) 2003 Alex Beregszaszi & Mike Melanson
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 /**
21  * @file truemotion1.c
22  * Duck TrueMotion v1 Video Decoder by 
23  * Alex Beregszaszi (alex@fsn.hu) and
24  * Mike Melanson (melanson@pcisys.net)
25  *
26  * The TrueMotion v1 decoder presently only decodes 16-bit TM1 data and
27  * outputs RGB555 data. 24-bit TM1 data is not supported yet.
28  */
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <unistd.h>
34
35 #include "common.h"
36 #include "avcodec.h"
37 #include "dsputil.h"
38
39 #define printf(...) {} //(f)printf() usage is forbidden in libavcodec, use av_log
40 #define fprintf(...) {} 
41
42 #include "truemotion1data.h"
43
44 #define LE_16(x)  ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0])
45
46 typedef struct TrueMotion1Context {
47     AVCodecContext *avctx;
48     AVFrame frame;
49     AVFrame prev_frame;
50
51     unsigned char *buf;
52     int size;
53
54     unsigned char *mb_change_bits;
55     int mb_change_bits_row_size;
56     unsigned char *index_stream;
57     int index_stream_size;
58
59     int flags;
60     int x, y, w, h;
61     
62     uint32_t y_predictor_table[1024];
63     uint32_t c_predictor_table[1024];
64     
65     int compression;
66     int block_type;
67     int block_width;
68     int block_height;
69
70     int16_t *ydt;
71     int16_t *cdt;
72     int16_t *fat_ydt;
73     int16_t *fat_cdt;
74     
75     int last_deltaset, last_vectable;
76
77     unsigned int *vert_pred;
78
79 } TrueMotion1Context;
80
81 #define FLAG_SPRITE         32
82 #define FLAG_KEYFRAME       16
83 #define FLAG_INTERFRAME      8
84 #define FLAG_INTERPOLATED    4
85
86 struct frame_header {
87     uint8_t header_size;
88     uint8_t compression;
89     uint8_t deltaset;
90     uint8_t vectable;
91     uint16_t ysize;
92     uint16_t xsize;
93     uint16_t checksum;
94     uint8_t version;
95     uint8_t header_type;
96     uint8_t flags;
97     uint8_t control;
98     uint16_t xoffset;
99     uint16_t yoffset;
100     uint16_t width;
101     uint16_t height;
102 };
103
104 #define ALGO_NOP        0
105 #define ALGO_RGB16V     1
106 #define ALGO_RGB16H     2
107 #define ALGO_RGB24H     3
108
109 /* these are the various block sizes that can occupy a 4x4 block */
110 #define BLOCK_2x2  0
111 #define BLOCK_2x4  1
112 #define BLOCK_4x2  2
113 #define BLOCK_4x4  3
114
115 typedef struct comp_types {
116     int algorithm;
117     int block_width;
118     int block_height;
119     int block_type;
120 } comp_types;
121
122 /* { valid for metatype }, algorithm, num of deltas, horiz res, vert res */
123 static comp_types compression_types[17] = {
124     { ALGO_NOP,    0, 0, 0 },
125
126     { ALGO_RGB16V, 4, 4, BLOCK_4x4 },
127     { ALGO_RGB16H, 4, 4, BLOCK_4x4 },
128     { ALGO_RGB16V, 4, 2, BLOCK_4x2 },
129     { ALGO_RGB16H, 4, 2, BLOCK_4x2 },
130
131     { ALGO_RGB16V, 2, 4, BLOCK_2x4 },
132     { ALGO_RGB16H, 2, 4, BLOCK_2x4 },
133     { ALGO_RGB16V, 2, 2, BLOCK_2x2 },
134     { ALGO_RGB16H, 2, 2, BLOCK_2x2 },
135
136     { ALGO_NOP,    4, 4, BLOCK_4x4 },
137     { ALGO_RGB24H, 4, 4, BLOCK_4x4 },
138     { ALGO_NOP,    4, 2, BLOCK_4x2 },
139     { ALGO_RGB24H, 4, 2, BLOCK_4x2 },
140
141     { ALGO_NOP,    2, 4, BLOCK_2x4 },
142     { ALGO_RGB24H, 2, 4, BLOCK_2x4 },
143     { ALGO_NOP,    2, 2, BLOCK_2x2 },
144     { ALGO_RGB24H, 2, 2, BLOCK_2x2 }
145 };
146
147 static void select_delta_tables(TrueMotion1Context *s, int delta_table_index)
148 {
149     int i;
150
151     if (delta_table_index > 3)
152         return;
153
154     s->ydt = ydts[delta_table_index];
155     s->cdt = cdts[delta_table_index];
156     s->fat_ydt = fat_ydts[delta_table_index];
157     s->fat_cdt = fat_cdts[delta_table_index];
158
159     /* Y skinny deltas need to be halved for some reason; maybe the
160      * skinny Y deltas should be modified */
161     for (i = 0; i < 8; i++)
162     {
163         /* drop the lsb before dividing by 2-- net effect: round down
164          * when dividing a negative number (e.g., -3/2 = -2, not -1) */
165         s->ydt[i] &= 0xFFFE;
166         s->ydt[i] /= 2;
167     }
168 }
169
170 #ifdef WORDS_BIGENDIAN
171 static int make_ydt_entry(int p2, int p1, int16_t *ydt)
172 #else
173 static int make_ydt_entry(int p1, int p2, int16_t *ydt)
174 #endif
175 {
176     int lo, hi;
177     
178     lo = ydt[p1];
179     lo += (lo << 5) + (lo << 10);
180     hi = ydt[p2];
181     hi += (hi << 5) + (hi << 10);
182     return ((lo + (hi << 16)) << 1);
183 }
184
185 #ifdef WORDS_BIGENDIAN
186 static int make_cdt_entry(int p2, int p1, int16_t *cdt)
187 #else
188 static int make_cdt_entry(int p1, int p2, int16_t *cdt)
189 #endif
190 {
191     int r, b, lo;
192     
193     b = cdt[p2];
194     r = cdt[p1] << 10;
195     lo = b + r;
196     return ((lo + (lo << 16)) << 1);
197 }
198
199 static void gen_vector_table(TrueMotion1Context *s, uint8_t *sel_vector_table)
200 {
201     int len, i, j;
202     unsigned char delta_pair;
203     
204     for (i = 0; i < 1024; i += 4)
205     {
206         len = *sel_vector_table++ / 2;
207         for (j = 0; j < len; j++)
208         {
209             delta_pair = *sel_vector_table++;
210             s->y_predictor_table[i+j] = 0xfffffffe & 
211                 make_ydt_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt);
212             s->c_predictor_table[i+j] = 0xfffffffe & 
213                 make_cdt_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt);
214         }
215         s->y_predictor_table[i+(j-1)] |= 1;
216         s->c_predictor_table[i+(j-1)] |= 1;
217     }
218 }
219
220 /* Returns the number of bytes consumed from the bytestream. Returns -1 if
221  * there was an error while decoding the header */ 
222 static int truemotion1_decode_header(TrueMotion1Context *s)
223 {
224     int i;
225     struct frame_header header;
226     uint8_t header_buffer[128];  /* logical maximum size of the header */
227     uint8_t *sel_vector_table;
228
229     /* There is 1 change bit per 4 pixels, so each change byte represents
230      * 32 pixels; divide width by 4 to obtain the number of change bits and
231      * then round up to the nearest byte. */
232     s->mb_change_bits_row_size = ((s->avctx->width >> 2) + 7) >> 3;
233
234     header.header_size = ((s->buf[0] >> 5) | (s->buf[0] << 3)) & 0x7f;
235     if (s->buf[0] < 0x10)
236     {
237         printf("invalid header size\n");
238         return -1;
239     }
240
241     /* unscramble the header bytes with a XOR operation */
242     memset(header_buffer, 0, 128);
243     for (i = 1; i < header.header_size; i++)
244     header_buffer[i - 1] = s->buf[i] ^ s->buf[i + 1];
245     header.compression = header_buffer[0];
246     header.deltaset = header_buffer[1];
247     header.vectable = header_buffer[2];
248     header.ysize = LE_16(&header_buffer[3]);
249     header.xsize = LE_16(&header_buffer[5]);
250     header.checksum = LE_16(&header_buffer[7]);
251     header.version = header_buffer[9];
252     header.header_type = header_buffer[10];
253     header.flags = header_buffer[11];
254     header.control = header_buffer[12];
255
256     /* Version 2 */
257     if (header.version >= 2)
258     {
259         if (header.header_type > 3)
260         {
261             av_log(s->avctx, AV_LOG_ERROR, "truemotion1: invalid header type\n");
262             return -1;
263         } else if ((header.header_type == 2) || (header.header_type == 3)) {
264             s->flags = header.flags;
265             if (!(s->flags & FLAG_INTERFRAME))
266                 s->flags |= FLAG_KEYFRAME;
267         } else
268             s->flags = FLAG_KEYFRAME;
269     } else /* Version 1 */
270         s->flags = FLAG_KEYFRAME;
271     
272     if (s->flags & FLAG_SPRITE) {
273         s->w = header.width;
274         s->h = header.height;
275         s->x = header.xoffset;
276         s->y = header.yoffset;
277     } else {
278         s->w = header.xsize;
279         s->h = header.ysize;
280         if (header.header_type < 2) {
281             if ((s->w < 213) && (s->h >= 176))
282                 s->flags |= FLAG_INTERPOLATED;
283         }
284     }
285
286     if (header.compression > 17) {
287         printf("invalid compression type (%d)\n", header.compression);
288         return -1;
289     }
290     
291     if ((header.deltaset != s->last_deltaset) || 
292         (header.vectable != s->last_vectable))
293         select_delta_tables(s, header.deltaset);
294
295     if ((header.compression & 1) && header.header_type)
296         sel_vector_table = pc_tbl2;
297     else {
298         if (header.vectable < 4)
299             sel_vector_table = tables[header.vectable - 1];
300         else {
301             printf("invalid vector table id (%d)\n", header.vectable);
302             return -1;
303         }
304     }
305
306     if ((header.deltaset != s->last_deltaset) || (header.vectable != s->last_vectable))
307     {
308         if (compression_types[header.compression].algorithm == ALGO_RGB24H)
309         {
310             printf("24bit compression not yet supported\n");
311         }
312         else
313             gen_vector_table(s, sel_vector_table);
314     }
315
316     /* set up pointers to the other key data chunks */
317     s->mb_change_bits = s->buf + header.header_size;
318     if (s->flags & FLAG_KEYFRAME) {
319         /* no change bits specified for a keyframe; only index bytes */
320         s->index_stream = s->mb_change_bits;
321     } else {
322         /* one change bit per 4x4 block */
323         s->index_stream = s->mb_change_bits + 
324             (s->mb_change_bits_row_size * (s->avctx->height >> 2));
325     }
326     s->index_stream_size = s->size - (s->index_stream - s->buf);
327
328     s->last_deltaset = header.deltaset;
329     s->last_vectable = header.vectable;
330     s->compression = header.compression;
331     s->block_width = compression_types[header.compression].block_width;
332     s->block_height = compression_types[header.compression].block_height;
333     s->block_type = compression_types[header.compression].block_type;
334
335     return header.header_size;    
336 }
337
338 static int truemotion1_decode_init(AVCodecContext *avctx)
339 {
340     TrueMotion1Context *s = (TrueMotion1Context *)avctx->priv_data;
341
342     s->avctx = avctx;
343
344     avctx->pix_fmt = PIX_FMT_RGB555;
345     avctx->has_b_frames = 0;
346     s->frame.data[0] = s->prev_frame.data[0] = NULL;
347
348     /* there is a vertical predictor for each pixel in a line; each vertical
349      * predictor is 0 to start with */
350     s->vert_pred = 
351         (unsigned int *)av_malloc(s->avctx->width * sizeof(unsigned short));
352
353     return 0;
354 }
355
356 #define GET_NEXT_INDEX() \
357 {\
358     if (index_stream_index >= s->index_stream_size) { \
359         printf (" help! truemotion1 decoder went out of bounds\n"); \
360         return; \
361     } \
362     index = s->index_stream[index_stream_index++] * 4; \
363 }
364
365 #define APPLY_C_PREDICTOR() \
366     predictor_pair = s->c_predictor_table[index]; \
367     horiz_pred += (predictor_pair >> 1); \
368     if (predictor_pair & 1) { \
369         GET_NEXT_INDEX() \
370         if (!index) { \
371             GET_NEXT_INDEX() \
372             predictor_pair = s->c_predictor_table[index]; \
373             horiz_pred += ((predictor_pair >> 1) * 5); \
374             if (predictor_pair & 1) \
375                 GET_NEXT_INDEX() \
376             else \
377                 index++; \
378         } \
379     } else \
380         index++;
381
382 #define APPLY_Y_PREDICTOR() \
383     predictor_pair = s->y_predictor_table[index]; \
384     horiz_pred += (predictor_pair >> 1); \
385     if (predictor_pair & 1) { \
386         GET_NEXT_INDEX() \
387         if (!index) { \
388             GET_NEXT_INDEX() \
389             predictor_pair = s->y_predictor_table[index]; \
390             horiz_pred += ((predictor_pair >> 1) * 5); \
391             if (predictor_pair & 1) \
392                 GET_NEXT_INDEX() \
393             else \
394                 index++; \
395         } \
396     } else \
397         index++;
398
399 #define OUTPUT_PIXEL_PAIR() \
400     *current_pixel_pair = *vert_pred + horiz_pred; \
401     *vert_pred++ = *current_pixel_pair++; \
402     prev_pixel_pair++;
403
404 static void truemotion1_decode_16bit(TrueMotion1Context *s)
405 {
406     int y;
407     int pixels_left;  /* remaining pixels on this line */
408     unsigned int predictor_pair;
409     unsigned int horiz_pred;
410     unsigned int *vert_pred;
411     unsigned int *current_pixel_pair;
412     unsigned int *prev_pixel_pair;
413     unsigned char *current_line = s->frame.data[0];
414     unsigned char *prev_line = s->prev_frame.data[0];
415     int keyframe = s->flags & FLAG_KEYFRAME;
416
417     /* these variables are for managing the stream of macroblock change bits */
418     unsigned char *mb_change_bits = s->mb_change_bits;
419     unsigned char mb_change_byte;
420     unsigned char mb_change_byte_mask;
421     int mb_change_index;
422
423     /* these variables are for managing the main index stream */
424     int index_stream_index = 0;  /* yes, the index into the index stream */
425     int index;
426
427     /* clean out the line buffer */
428     memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned short));
429
430     GET_NEXT_INDEX();
431
432     for (y = 0; y < s->avctx->height; y++) {
433
434         /* re-init variables for the next line iteration */
435         horiz_pred = 0;
436         current_pixel_pair = (unsigned int *)current_line;
437         prev_pixel_pair = (unsigned int *)prev_line;
438         vert_pred = s->vert_pred;
439         mb_change_index = 0;
440         mb_change_byte = mb_change_bits[mb_change_index++];
441         mb_change_byte_mask = 0x01;
442         pixels_left = s->avctx->width;
443
444         while (pixels_left > 0) {
445
446             if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
447
448                 switch (y & 3) {
449                 case 0:
450                     /* if macroblock width is 2, apply C-Y-C-Y; else 
451                      * apply C-Y-Y */
452                     if (s->block_width == 2) {
453                         APPLY_C_PREDICTOR();
454                         APPLY_Y_PREDICTOR();
455                         OUTPUT_PIXEL_PAIR();
456                         APPLY_C_PREDICTOR();
457                         APPLY_Y_PREDICTOR();
458                         OUTPUT_PIXEL_PAIR();
459                     } else {
460                         APPLY_C_PREDICTOR();
461                         APPLY_Y_PREDICTOR();
462                         OUTPUT_PIXEL_PAIR();
463                         APPLY_Y_PREDICTOR();
464                         OUTPUT_PIXEL_PAIR();
465                     }
466                     break;
467
468                 case 1:
469                 case 3:
470                     /* always apply 2 Y predictors on these iterations */
471                     APPLY_Y_PREDICTOR();
472                     OUTPUT_PIXEL_PAIR();
473                     APPLY_Y_PREDICTOR();
474                     OUTPUT_PIXEL_PAIR();
475                     break;
476
477                 case 2:
478                     /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y 
479                      * depending on the macroblock type */
480                     if (s->block_type == BLOCK_2x2) {
481                         APPLY_C_PREDICTOR();
482                         APPLY_Y_PREDICTOR();
483                         OUTPUT_PIXEL_PAIR();
484                         APPLY_C_PREDICTOR();
485                         APPLY_Y_PREDICTOR();
486                         OUTPUT_PIXEL_PAIR();
487                     } else if (s->block_type == BLOCK_4x2) {
488                         APPLY_C_PREDICTOR();
489                         APPLY_Y_PREDICTOR();
490                         OUTPUT_PIXEL_PAIR();
491                         APPLY_Y_PREDICTOR();
492                         OUTPUT_PIXEL_PAIR();
493                     } else {
494                         APPLY_Y_PREDICTOR();
495                         OUTPUT_PIXEL_PAIR();
496                         APPLY_Y_PREDICTOR();
497                         OUTPUT_PIXEL_PAIR();
498                     }
499                     break;
500                 }
501
502             } else {
503
504                 /* skip (copy) four pixels, but reassign the horizontal 
505                  * predictor */
506                 *current_pixel_pair = *prev_pixel_pair++;
507                 *vert_pred++ = *current_pixel_pair++;
508                 *current_pixel_pair = *prev_pixel_pair++;
509                 horiz_pred = *current_pixel_pair - *vert_pred;
510                 *vert_pred++ = *current_pixel_pair++;
511                 
512             }
513
514             if (!keyframe) {
515                 mb_change_byte_mask <<= 1;
516
517                 /* next byte */
518                 if (!mb_change_byte_mask) {
519                     mb_change_byte = mb_change_bits[mb_change_index++];
520                     mb_change_byte_mask = 0x01;
521                 }
522             }
523
524             pixels_left -= 4;
525         }
526
527         /* next change row */
528         if (((y + 1) & 3) == 0)
529             mb_change_bits += s->mb_change_bits_row_size;
530
531         current_line += s->frame.linesize[0];
532         prev_line += s->prev_frame.linesize[0];
533     }
534 }
535
536 static int truemotion1_decode_frame(AVCodecContext *avctx,
537                                     void *data, int *data_size,
538                                     uint8_t *buf, int buf_size)
539 {
540     TrueMotion1Context *s = (TrueMotion1Context *)avctx->priv_data;
541
542     s->buf = buf;
543     s->size = buf_size;
544
545     s->frame.reference = 1;
546     if (avctx->get_buffer(avctx, &s->frame) < 0) {
547         fprintf(stderr, "truemotion1: get_buffer() failed\n");
548         return -1;
549     }
550
551     /* no supplementary picture */
552     if (buf_size == 0)
553         return 0;
554
555     *data_size = 0;
556     
557     if (truemotion1_decode_header(s) == -1)
558         return -1;
559
560     /* check for a do-nothing frame and copy the previous frame */
561     if (compression_types[s->compression].algorithm == ALGO_NOP)
562     {
563         memcpy(s->frame.data[0], s->prev_frame.data[0],
564             s->frame.linesize[0] * s->avctx->height);
565     } else if (compression_types[s->compression].algorithm == ALGO_RGB24H) {
566         printf ("  24-bit Duck TrueMotion decoding not yet implemented\n");
567     } else {
568         truemotion1_decode_16bit(s);
569     }
570
571     if (s->prev_frame.data[0])
572         avctx->release_buffer(avctx, &s->prev_frame);
573
574     /* shuffle frames */
575     s->prev_frame = s->frame;
576
577     *data_size = sizeof(AVFrame);
578     *(AVFrame*)data = s->frame;
579
580     /* report that the buffer was completely consumed */
581     return buf_size;
582 }
583
584 static int truemotion1_decode_end(AVCodecContext *avctx)
585 {
586     TrueMotion1Context *s = (TrueMotion1Context *)avctx->priv_data;
587
588     /* release the last frame */
589     if (s->prev_frame.data[0])
590         avctx->release_buffer(avctx, &s->prev_frame);
591
592     av_free(s->vert_pred);
593
594     return 0;
595 }
596
597 AVCodec truemotion1_decoder = {
598     "truemotion1",
599     CODEC_TYPE_VIDEO,
600     CODEC_ID_TRUEMOTION1,
601     sizeof(TrueMotion1Context),
602     truemotion1_decode_init,
603     NULL,
604     truemotion1_decode_end,
605     truemotion1_decode_frame,
606     CODEC_CAP_DR1,
607 };