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