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