Mercurial > libavcodec.hg
annotate tmv.c @ 12411:7c9d711a4201 libavcodec
msmpeg4v1: fix undefined behaviour in msmpeg4_decode_picture_header()
Because the order of evaluation of subexpressions is undefined, two
get_bits() calls may not be part of the same expression. In this
specific case, using get_bits_long() is simpler.
This fixes msmpeg4v1 decoding with armcc.
author | mru |
---|---|
date | Tue, 24 Aug 2010 15:40:57 +0000 |
parents | 9dda7c2700ad |
children |
rev | line source |
---|---|
9616 | 1 /* |
2 * 8088flex TMV video decoder | |
3 * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu> | |
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 * 8088flex TMV video decoder | |
11644
7dd2a45249a9
Remove explicit filename from Doxygen @file commands.
diego
parents:
11560
diff
changeset
|
24 * @file |
9616 | 25 * @author Daniel Verkamp |
26 * @sa http://www.oldskool.org/pc/8088_Corruption | |
27 */ | |
28 | |
29 #include "avcodec.h" | |
30 | |
31 #include "cga_data.h" | |
32 | |
33 typedef struct TMVContext { | |
34 AVFrame pic; | |
35 } TMVContext; | |
36 | |
37 static int tmv_decode_frame(AVCodecContext *avctx, void *data, | |
38 int *data_size, AVPacket *avpkt) | |
39 { | |
40 TMVContext *tmv = avctx->priv_data; | |
41 const uint8_t *src = avpkt->data; | |
12184
9dda7c2700ad
8088flex TMV video decoder now uses ff_draw_pc_font()
pross
parents:
11644
diff
changeset
|
42 uint8_t *dst; |
9616 | 43 unsigned char_cols = avctx->width >> 3; |
44 unsigned char_rows = avctx->height >> 3; | |
12184
9dda7c2700ad
8088flex TMV video decoder now uses ff_draw_pc_font()
pross
parents:
11644
diff
changeset
|
45 unsigned x, y, fg, bg, c; |
9616 | 46 |
47 if (tmv->pic.data[0]) | |
48 avctx->release_buffer(avctx, &tmv->pic); | |
49 | |
50 if (avctx->get_buffer(avctx, &tmv->pic) < 0) { | |
51 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
52 return -1; | |
53 } | |
54 | |
9663
041c635d0f69
Make TMV decoder check packet sizes before reading from it.
vitor
parents:
9616
diff
changeset
|
55 if (avpkt->size < 2*char_rows*char_cols) { |
041c635d0f69
Make TMV decoder check packet sizes before reading from it.
vitor
parents:
9616
diff
changeset
|
56 av_log(avctx, AV_LOG_ERROR, |
041c635d0f69
Make TMV decoder check packet sizes before reading from it.
vitor
parents:
9616
diff
changeset
|
57 "Input buffer too small, truncated sample?\n"); |
041c635d0f69
Make TMV decoder check packet sizes before reading from it.
vitor
parents:
9616
diff
changeset
|
58 *data_size = 0; |
041c635d0f69
Make TMV decoder check packet sizes before reading from it.
vitor
parents:
9616
diff
changeset
|
59 return -1; |
041c635d0f69
Make TMV decoder check packet sizes before reading from it.
vitor
parents:
9616
diff
changeset
|
60 } |
041c635d0f69
Make TMV decoder check packet sizes before reading from it.
vitor
parents:
9616
diff
changeset
|
61 |
9616 | 62 tmv->pic.pict_type = FF_I_TYPE; |
63 tmv->pic.key_frame = 1; | |
64 dst = tmv->pic.data[0]; | |
65 | |
66 tmv->pic.palette_has_changed = 1; | |
67 memcpy(tmv->pic.data[1], ff_cga_palette, 16 * 4); | |
68 | |
69 for (y = 0; y < char_rows; y++) { | |
70 for (x = 0; x < char_cols; x++) { | |
12184
9dda7c2700ad
8088flex TMV video decoder now uses ff_draw_pc_font()
pross
parents:
11644
diff
changeset
|
71 c = *src++; |
9616 | 72 bg = *src >> 4; |
73 fg = *src++ & 0xF; | |
12184
9dda7c2700ad
8088flex TMV video decoder now uses ff_draw_pc_font()
pross
parents:
11644
diff
changeset
|
74 ff_draw_pc_font(dst + x * 8, tmv->pic.linesize[0], |
9dda7c2700ad
8088flex TMV video decoder now uses ff_draw_pc_font()
pross
parents:
11644
diff
changeset
|
75 ff_cga_font, 8, c, fg, bg); |
9616 | 76 } |
77 dst += tmv->pic.linesize[0] * 8; | |
78 } | |
79 | |
80 *data_size = sizeof(AVFrame); | |
81 *(AVFrame *)data = tmv->pic; | |
82 return avpkt->size; | |
83 } | |
84 | |
85 static av_cold int tmv_decode_close(AVCodecContext *avctx) | |
86 { | |
87 TMVContext *tmv = avctx->priv_data; | |
88 | |
89 if (tmv->pic.data[0]) | |
90 avctx->release_buffer(avctx, &tmv->pic); | |
91 | |
92 return 0; | |
93 } | |
94 | |
95 AVCodec tmv_decoder = { | |
96 .name = "tmv", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
9813
diff
changeset
|
97 .type = AVMEDIA_TYPE_VIDEO, |
9616 | 98 .id = CODEC_ID_TMV, |
99 .priv_data_size = sizeof(TMVContext), | |
100 .close = tmv_decode_close, | |
101 .decode = tmv_decode_frame, | |
9813 | 102 .capabilities = CODEC_CAP_DR1, |
9616 | 103 .long_name = NULL_IF_CONFIG_SMALL("8088flex TMV"), |
104 }; |