Get rid of unnecessary pointer casts.
[ffmpeg.git] / libavcodec / vmdav.c
1 /*
2  * Sierra VMD Audio & Video Decoders
3  * Copyright (C) 2004 the ffmpeg project
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
23 /**
24  * @file vmdvideo.c
25  * Sierra VMD audio & video decoders
26  * by Vladimir "VAG" Gneushev (vagsoft at mail.ru)
27  * for more information on the Sierra VMD format, visit:
28  *   http://www.pcisys.net/~melanson/codecs/
29  *
30  * The video decoder outputs PAL8 colorspace data. The decoder expects
31  * a 0x330-byte VMD file header to be transmitted via extradata during
32  * codec initialization. Each encoded frame that is sent to this decoder
33  * is expected to be prepended with the appropriate 16-byte frame
34  * information record from the VMD file.
35  *
36  * The audio decoder, like the video decoder, expects each encoded data
37  * chunk to be prepended with the appropriate 16-byte frame information
38  * record from the VMD file. It does not require the 0x330-byte VMD file
39  * header, but it does need the audio setup parameters passed in through
40  * normal libavcodec API means.
41  */
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
47
48 #include "common.h"
49 #include "avcodec.h"
50 #include "dsputil.h"
51
52 #define VMD_HEADER_SIZE 0x330
53 #define PALETTE_COUNT 256
54
55 /*
56  * Video Decoder
57  */
58
59 typedef struct VmdVideoContext {
60
61     AVCodecContext *avctx;
62     DSPContext dsp;
63     AVFrame frame;
64     AVFrame prev_frame;
65
66     unsigned char *buf;
67     int size;
68
69     unsigned char palette[PALETTE_COUNT * 4];
70     unsigned char *unpack_buffer;
71     int unpack_buffer_size;
72
73 } VmdVideoContext;
74
75 #define QUEUE_SIZE 0x1000
76 #define QUEUE_MASK 0x0FFF
77
78 static void lz_unpack(unsigned char *src, unsigned char *dest, int dest_len)
79 {
80     unsigned char *s;
81     unsigned char *d;
82     unsigned char *d_end;
83     unsigned char queue[QUEUE_SIZE];
84     unsigned int qpos;
85     unsigned int dataleft;
86     unsigned int chainofs;
87     unsigned int chainlen;
88     unsigned int speclen;
89     unsigned char tag;
90     unsigned int i, j;
91
92     s = src;
93     d = dest;
94     d_end = d + dest_len;
95     dataleft = AV_RL32(s);
96     s += 4;
97     memset(queue, 0x20, QUEUE_SIZE);
98     if (AV_RL32(s) == 0x56781234) {
99         s += 4;
100         qpos = 0x111;
101         speclen = 0xF + 3;
102     } else {
103         qpos = 0xFEE;
104         speclen = 100;  /* no speclen */
105     }
106
107     while (dataleft > 0) {
108         tag = *s++;
109         if ((tag == 0xFF) && (dataleft > 8)) {
110             if (d + 8 > d_end)
111                 return;
112             for (i = 0; i < 8; i++) {
113                 queue[qpos++] = *d++ = *s++;
114                 qpos &= QUEUE_MASK;
115             }
116             dataleft -= 8;
117         } else {
118             for (i = 0; i < 8; i++) {
119                 if (dataleft == 0)
120                     break;
121                 if (tag & 0x01) {
122                     if (d + 1 > d_end)
123                         return;
124                     queue[qpos++] = *d++ = *s++;
125                     qpos &= QUEUE_MASK;
126                     dataleft--;
127                 } else {
128                     chainofs = *s++;
129                     chainofs |= ((*s & 0xF0) << 4);
130                     chainlen = (*s++ & 0x0F) + 3;
131                     if (chainlen == speclen)
132                         chainlen = *s++ + 0xF + 3;
133                     if (d + chainlen > d_end)
134                         return;
135                     for (j = 0; j < chainlen; j++) {
136                         *d = queue[chainofs++ & QUEUE_MASK];
137                         queue[qpos++] = *d++;
138                         qpos &= QUEUE_MASK;
139                     }
140                     dataleft -= chainlen;
141                 }
142                 tag >>= 1;
143             }
144         }
145     }
146 }
147
148 static int rle_unpack(unsigned char *src, unsigned char *dest,
149     int src_len, int dest_len)
150 {
151     unsigned char *ps;
152     unsigned char *pd;
153     int i, l;
154     unsigned char *dest_end = dest + dest_len;
155
156     ps = src;
157     pd = dest;
158     if (src_len & 1)
159         *pd++ = *ps++;
160
161     src_len >>= 1;
162     i = 0;
163     do {
164         l = *ps++;
165         if (l & 0x80) {
166             l = (l & 0x7F) * 2;
167             if (pd + l > dest_end)
168                 return (ps - src);
169             memcpy(pd, ps, l);
170             ps += l;
171             pd += l;
172         } else {
173             if (pd + i > dest_end)
174                 return (ps - src);
175             for (i = 0; i < l; i++) {
176                 *pd++ = ps[0];
177                 *pd++ = ps[1];
178             }
179             ps += 2;
180         }
181         i += l;
182     } while (i < src_len);
183
184     return (ps - src);
185 }
186
187 static void vmd_decode(VmdVideoContext *s)
188 {
189     int i;
190     unsigned int *palette32;
191     unsigned char r, g, b;
192
193     /* point to the start of the encoded data */
194     unsigned char *p = s->buf + 16;
195
196     unsigned char *pb;
197     unsigned char meth;
198     unsigned char *dp;   /* pointer to current frame */
199     unsigned char *pp;   /* pointer to previous frame */
200     unsigned char len;
201     int ofs;
202
203     int frame_x, frame_y;
204     int frame_width, frame_height;
205     int dp_size;
206
207     frame_x = AV_RL16(&s->buf[6]);
208     frame_y = AV_RL16(&s->buf[8]);
209     frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
210     frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
211
212     /* if only a certain region will be updated, copy the entire previous
213      * frame before the decode */
214     if (frame_x || frame_y || (frame_width != s->avctx->width) ||
215         (frame_height != s->avctx->height)) {
216
217         memcpy(s->frame.data[0], s->prev_frame.data[0],
218             s->avctx->height * s->frame.linesize[0]);
219     }
220
221     /* check if there is a new palette */
222     if (s->buf[15] & 0x02) {
223         p += 2;
224         palette32 = (unsigned int *)s->palette;
225         for (i = 0; i < PALETTE_COUNT; i++) {
226             r = *p++ * 4;
227             g = *p++ * 4;
228             b = *p++ * 4;
229             palette32[i] = (r << 16) | (g << 8) | (b);
230         }
231         s->size -= (256 * 3 + 2);
232     }
233     if (s->size >= 0) {
234         /* originally UnpackFrame in VAG's code */
235         pb = p;
236         meth = *pb++;
237         if (meth & 0x80) {
238             lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size);
239             meth &= 0x7F;
240             pb = s->unpack_buffer;
241         }
242
243         dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
244         dp_size = s->frame.linesize[0] * s->avctx->height;
245         pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
246         switch (meth) {
247         case 1:
248             for (i = 0; i < frame_height; i++) {
249                 ofs = 0;
250                 do {
251                     len = *pb++;
252                     if (len & 0x80) {
253                         len = (len & 0x7F) + 1;
254                         if (ofs + len > frame_width)
255                             return;
256                         memcpy(&dp[ofs], pb, len);
257                         pb += len;
258                         ofs += len;
259                     } else {
260                         /* interframe pixel copy */
261                         if (ofs + len + 1 > frame_width)
262                             return;
263                         memcpy(&dp[ofs], &pp[ofs], len + 1);
264                         ofs += len + 1;
265                     }
266                 } while (ofs < frame_width);
267                 if (ofs > frame_width) {
268                     av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
269                         ofs, frame_width);
270                     break;
271                 }
272                 dp += s->frame.linesize[0];
273                 pp += s->prev_frame.linesize[0];
274             }
275             break;
276
277         case 2:
278             for (i = 0; i < frame_height; i++) {
279                 memcpy(dp, pb, frame_width);
280                 pb += frame_width;
281                 dp += s->frame.linesize[0];
282                 pp += s->prev_frame.linesize[0];
283             }
284             break;
285
286         case 3:
287             for (i = 0; i < frame_height; i++) {
288                 ofs = 0;
289                 do {
290                     len = *pb++;
291                     if (len & 0x80) {
292                         len = (len & 0x7F) + 1;
293                         if (*pb++ == 0xFF)
294                             len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
295                         else
296                             memcpy(&dp[ofs], pb, len);
297                         pb += len;
298                         ofs += len;
299                     } else {
300                         /* interframe pixel copy */
301                         if (ofs + len + 1 > frame_width)
302                             return;
303                         memcpy(&dp[ofs], &pp[ofs], len + 1);
304                         ofs += len + 1;
305                     }
306                 } while (ofs < frame_width);
307                 if (ofs > frame_width) {
308                     av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
309                         ofs, frame_width);
310                 }
311                 dp += s->frame.linesize[0];
312                 pp += s->prev_frame.linesize[0];
313             }
314             break;
315         }
316     }
317 }
318
319 static int vmdvideo_decode_init(AVCodecContext *avctx)
320 {
321     VmdVideoContext *s = avctx->priv_data;
322     int i;
323     unsigned int *palette32;
324     int palette_index = 0;
325     unsigned char r, g, b;
326     unsigned char *vmd_header;
327     unsigned char *raw_palette;
328
329     s->avctx = avctx;
330     avctx->pix_fmt = PIX_FMT_PAL8;
331     dsputil_init(&s->dsp, avctx);
332
333     /* make sure the VMD header made it */
334     if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
335         av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
336             VMD_HEADER_SIZE);
337         return -1;
338     }
339     vmd_header = (unsigned char *)avctx->extradata;
340
341     s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
342     s->unpack_buffer = av_malloc(s->unpack_buffer_size);
343     if (!s->unpack_buffer)
344         return -1;
345
346     /* load up the initial palette */
347     raw_palette = &vmd_header[28];
348     palette32 = (unsigned int *)s->palette;
349     for (i = 0; i < PALETTE_COUNT; i++) {
350         r = raw_palette[palette_index++] * 4;
351         g = raw_palette[palette_index++] * 4;
352         b = raw_palette[palette_index++] * 4;
353         palette32[i] = (r << 16) | (g << 8) | (b);
354     }
355
356     s->frame.data[0] = s->prev_frame.data[0] = NULL;
357
358     return 0;
359 }
360
361 static int vmdvideo_decode_frame(AVCodecContext *avctx,
362                                  void *data, int *data_size,
363                                  uint8_t *buf, int buf_size)
364 {
365     VmdVideoContext *s = avctx->priv_data;
366
367     s->buf = buf;
368     s->size = buf_size;
369
370     if (buf_size < 16)
371         return buf_size;
372
373     s->frame.reference = 1;
374     if (avctx->get_buffer(avctx, &s->frame)) {
375         av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
376         return -1;
377     }
378
379     vmd_decode(s);
380
381     /* make the palette available on the way out */
382     memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
383
384     if (s->prev_frame.data[0])
385         avctx->release_buffer(avctx, &s->prev_frame);
386
387     /* shuffle frames */
388     s->prev_frame = s->frame;
389
390     *data_size = sizeof(AVFrame);
391     *(AVFrame*)data = s->frame;
392
393     /* report that the buffer was completely consumed */
394     return buf_size;
395 }
396
397 static int vmdvideo_decode_end(AVCodecContext *avctx)
398 {
399     VmdVideoContext *s = avctx->priv_data;
400
401     if (s->prev_frame.data[0])
402         avctx->release_buffer(avctx, &s->prev_frame);
403     av_free(s->unpack_buffer);
404
405     return 0;
406 }
407
408
409 /*
410  * Audio Decoder
411  */
412
413 typedef struct VmdAudioContext {
414     AVCodecContext *avctx;
415     int channels;
416     int bits;
417     int block_align;
418     int predictors[2];
419 } VmdAudioContext;
420
421 static uint16_t vmdaudio_table[128] = {
422     0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
423     0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
424     0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
425     0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
426     0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
427     0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
428     0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
429     0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
430     0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
431     0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
432     0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
433     0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
434     0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
435 };
436
437 static int vmdaudio_decode_init(AVCodecContext *avctx)
438 {
439     VmdAudioContext *s = avctx->priv_data;
440
441     s->avctx = avctx;
442     s->channels = avctx->channels;
443     s->bits = avctx->bits_per_sample;
444     s->block_align = avctx->block_align;
445
446     av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n",
447             s->channels, s->bits, s->block_align, avctx->sample_rate);
448
449     return 0;
450 }
451
452 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
453     uint8_t *buf, int stereo)
454 {
455     int i;
456     int chan = 0;
457     int16_t *out = (int16_t*)data;
458
459     for(i = 0; i < s->block_align; i++) {
460         if(buf[i] & 0x80)
461             s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
462         else
463             s->predictors[chan] += vmdaudio_table[buf[i]];
464         s->predictors[chan] = av_clip(s->predictors[chan], -32768, 32767);
465         out[i] = s->predictors[chan];
466         chan ^= stereo;
467     }
468 }
469
470 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
471     uint8_t *buf, int silence)
472 {
473     int bytes_decoded = 0;
474     int i;
475
476 //    if (silence)
477 //        av_log(s->avctx, AV_LOG_INFO, "silent block!\n");
478     if (s->channels == 2) {
479
480         /* stereo handling */
481         if (silence) {
482             memset(data, 0, s->block_align * 2);
483         } else {
484             if (s->bits == 16)
485                 vmdaudio_decode_audio(s, data, buf, 1);
486             else {
487                 /* copy the data but convert it to signed */
488                 for (i = 0; i < s->block_align; i++){
489                     *data++ = buf[i] + 0x80;
490                     *data++ = buf[i] + 0x80;
491                 }
492             }
493         }
494     } else {
495         bytes_decoded = s->block_align * 2;
496
497         /* mono handling */
498         if (silence) {
499             memset(data, 0, s->block_align * 2);
500         } else {
501             if (s->bits == 16) {
502                 vmdaudio_decode_audio(s, data, buf, 0);
503             } else {
504                 /* copy the data but convert it to signed */
505                 for (i = 0; i < s->block_align; i++){
506                     *data++ = buf[i] + 0x80;
507                     *data++ = buf[i] + 0x80;
508                 }
509             }
510         }
511     }
512
513     return s->block_align * 2;
514 }
515
516 static int vmdaudio_decode_frame(AVCodecContext *avctx,
517                                  void *data, int *data_size,
518                                  uint8_t *buf, int buf_size)
519 {
520     VmdAudioContext *s = avctx->priv_data;
521     unsigned char *output_samples = (unsigned char *)data;
522
523     /* point to the start of the encoded data */
524     unsigned char *p = buf + 16;
525
526     if (buf_size < 16)
527         return buf_size;
528
529     if (buf[6] == 1) {
530         /* the chunk contains audio */
531         *data_size = vmdaudio_loadsound(s, output_samples, p, 0);
532     } else if (buf[6] == 2) {
533         /* the chunk may contain audio */
534         p += 4;
535         *data_size = vmdaudio_loadsound(s, output_samples, p, (buf_size == 16));
536         output_samples += (s->block_align * s->bits / 8);
537     } else if (buf[6] == 3) {
538         /* silent chunk */
539         *data_size = vmdaudio_loadsound(s, output_samples, p, 1);
540     }
541
542     return buf_size;
543 }
544
545
546 /*
547  * Public Data Structures
548  */
549
550 AVCodec vmdvideo_decoder = {
551     "vmdvideo",
552     CODEC_TYPE_VIDEO,
553     CODEC_ID_VMDVIDEO,
554     sizeof(VmdVideoContext),
555     vmdvideo_decode_init,
556     NULL,
557     vmdvideo_decode_end,
558     vmdvideo_decode_frame,
559     CODEC_CAP_DR1,
560 };
561
562 AVCodec vmdaudio_decoder = {
563     "vmdaudio",
564     CODEC_TYPE_AUDIO,
565     CODEC_ID_VMDAUDIO,
566     sizeof(VmdAudioContext),
567     vmdaudio_decode_init,
568     NULL,
569     NULL,
570     vmdaudio_decode_frame,
571 };