comparison escape124.c @ 6556:8300baeb2b5f libavcodec

Remove flexible array member from Escape 124 Patch by Eli Friedman (eli friedman gmail com)
author superdump
date Tue, 01 Apr 2008 01:28:26 +0000
parents 3de38485c56d
children a4104482ceef
comparison
equal deleted inserted replaced
6555:77bb7984b15e 6556:8300baeb2b5f
35 } SuperBlock; 35 } SuperBlock;
36 36
37 typedef struct CodeBook { 37 typedef struct CodeBook {
38 unsigned depth; 38 unsigned depth;
39 unsigned size; 39 unsigned size;
40 MacroBlock blocks[0]; 40 MacroBlock* blocks;
41 } CodeBook; 41 } CodeBook;
42 42
43 typedef struct Escape124Context { 43 typedef struct Escape124Context {
44 AVFrame frame; 44 AVFrame frame;
45 45
46 unsigned num_superblocks; 46 unsigned num_superblocks;
47 47
48 CodeBook* codebooks[3]; 48 CodeBook codebooks[3];
49 } Escape124Context; 49 } Escape124Context;
50 50
51 static int can_safely_read(GetBitContext* gb, int bits) { 51 static int can_safely_read(GetBitContext* gb, int bits) {
52 return get_bits_count(gb) + bits <= gb->size_in_bits; 52 return get_bits_count(gb) + bits <= gb->size_in_bits;
53 } 53 }
73 { 73 {
74 unsigned i; 74 unsigned i;
75 Escape124Context *s = avctx->priv_data; 75 Escape124Context *s = avctx->priv_data;
76 76
77 for (i = 0; i < 3; i++) 77 for (i = 0; i < 3; i++)
78 av_free(s->codebooks[i]); 78 av_free(s->codebooks[i].blocks);
79 79
80 if (s->frame.data[0]) 80 if (s->frame.data[0])
81 avctx->release_buffer(avctx, &s->frame); 81 avctx->release_buffer(avctx, &s->frame);
82 82
83 return 0; 83 return 0;
84 } 84 }
85 85
86 static CodeBook* unpack_codebook(GetBitContext* gb, unsigned depth, 86 static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth,
87 unsigned size) 87 unsigned size)
88 { 88 {
89 unsigned i, j; 89 unsigned i, j;
90 CodeBook* cb; 90 CodeBook cb = { 0 };
91 91
92 if (!can_safely_read(gb, size * 34)) 92 if (!can_safely_read(gb, size * 34))
93 return NULL; 93 return cb;
94 94
95 if (size >= (INT_MAX - sizeof(CodeBook)) / sizeof(MacroBlock)) 95 if (size >= INT_MAX / sizeof(MacroBlock))
96 return NULL; 96 return cb;
97 cb = av_malloc(size * sizeof(MacroBlock) + sizeof(CodeBook)); 97 cb.blocks = av_malloc(size ? size * sizeof(MacroBlock) : 1);
98 if (!cb) 98 if (!cb.blocks)
99 return NULL; 99 return cb;
100 100
101 cb->depth = depth; 101 cb.depth = depth;
102 cb->size = size; 102 cb.size = size;
103 for (i = 0; i < size; i++) { 103 for (i = 0; i < size; i++) {
104 unsigned mask_bits = get_bits(gb, 4); 104 unsigned mask_bits = get_bits(gb, 4);
105 unsigned color0 = get_bits(gb, 15); 105 unsigned color0 = get_bits(gb, 15);
106 unsigned color1 = get_bits(gb, 15); 106 unsigned color1 = get_bits(gb, 15);
107 107
108 for (j = 0; j < 4; j++) { 108 for (j = 0; j < 4; j++) {
109 if (mask_bits & (1 << j)) 109 if (mask_bits & (1 << j))
110 cb->blocks[i].pixels[j] = color1; 110 cb.blocks[i].pixels[j] = color1;
111 else 111 else
112 cb->blocks[i].pixels[j] = color0; 112 cb.blocks[i].pixels[j] = color0;
113 } 113 }
114 } 114 }
115 return cb; 115 return cb;
116 } 116 }
117 117
147 if (get_bits1(gb)) { 147 if (get_bits1(gb)) {
148 static const char transitions[3][2] = { {2, 1}, {0, 2}, {1, 0} }; 148 static const char transitions[3][2] = { {2, 1}, {0, 2}, {1, 0} };
149 *codebook_index = transitions[*codebook_index][get_bits1(gb)]; 149 *codebook_index = transitions[*codebook_index][get_bits1(gb)];
150 } 150 }
151 151
152 depth = s->codebooks[*codebook_index]->depth; 152 depth = s->codebooks[*codebook_index].depth;
153 153
154 // depth = 0 means that this shouldn't read any bits; 154 // depth = 0 means that this shouldn't read any bits;
155 // in theory, this is the same as get_bits(gb, 0), but 155 // in theory, this is the same as get_bits(gb, 0), but
156 // that doesn't actually work. 156 // that doesn't actually work.
157 block_index = depth ? get_bits(gb, depth) : 0; 157 block_index = depth ? get_bits(gb, depth) : 0;
158 158
159 if (*codebook_index == 1) { 159 if (*codebook_index == 1) {
160 block_index += superblock_index << s->codebooks[1]->depth; 160 block_index += superblock_index << s->codebooks[1].depth;
161 } 161 }
162 162
163 // This condition can occur with invalid bitstreams and 163 // This condition can occur with invalid bitstreams and
164 // *codebook_index == 2 164 // *codebook_index == 2
165 if (block_index >= s->codebooks[*codebook_index]->size) 165 if (block_index >= s->codebooks[*codebook_index].size)
166 return (MacroBlock) { { 0 } }; 166 return (MacroBlock) { { 0 } };
167 167
168 return s->codebooks[*codebook_index]->blocks[block_index]; 168 return s->codebooks[*codebook_index].blocks[block_index];
169 } 169 }
170 170
171 static void insert_mb_into_sb(SuperBlock* sb, MacroBlock mb, unsigned index) { 171 static void insert_mb_into_sb(SuperBlock* sb, MacroBlock mb, unsigned index) {
172 // Formula: ((index / 4) * 16 + (index % 4) * 2) / 2 172 // Formula: ((index / 4) * 16 + (index % 4) * 2) / 2
173 uint32_t *dst = sb->pixels32 + index + (index & -4); 173 uint32_t *dst = sb->pixels32 + index + (index & -4);
263 // FIXME: I don't think this handles integer overflow 263 // FIXME: I don't think this handles integer overflow
264 // properly 264 // properly
265 cb_size = s->num_superblocks << cb_depth; 265 cb_size = s->num_superblocks << cb_depth;
266 } 266 }
267 } 267 }
268 av_free(s->codebooks[i]); 268 av_free(s->codebooks[i].blocks);
269 s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size); 269 s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size);
270 if (!s->codebooks[i]) 270 if (!s->codebooks[i].blocks)
271 return -1; 271 return -1;
272 } 272 }
273 } 273 }
274 274
275 new_frame.reference = 3; 275 new_frame.reference = 3;