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