Signed-off-by: Justin Ruggles <justin.ruggles@gmail.com>
Ronald Bultje authored on 2012/04/01 02:10:54... | ... |
@@ -34,17 +34,10 @@ |
34 | 34 |
|
35 | 35 |
typedef struct AascContext { |
36 | 36 |
AVCodecContext *avctx; |
37 |
+ GetByteContext gb; |
|
37 | 38 |
AVFrame frame; |
38 | 39 |
} AascContext; |
39 | 40 |
|
40 |
-#define FETCH_NEXT_STREAM_BYTE() \ |
|
41 |
- if (stream_ptr >= buf_size) \ |
|
42 |
- { \ |
|
43 |
- av_log(s->avctx, AV_LOG_ERROR, " AASC: stream ptr just went out of bounds (fetch)\n"); \ |
|
44 |
- break; \ |
|
45 |
- } \ |
|
46 |
- stream_byte = buf[stream_ptr++]; |
|
47 |
- |
|
48 | 41 |
static av_cold int aasc_decode_init(AVCodecContext *avctx) |
49 | 42 |
{ |
50 | 43 |
AascContext *s = avctx->priv_data; |
... | ... |
@@ -84,7 +77,8 @@ static int aasc_decode_frame(AVCodecContext *avctx, |
84 | 84 |
} |
85 | 85 |
break; |
86 | 86 |
case 1: |
87 |
- ff_msrle_decode(avctx, (AVPicture*)&s->frame, 8, buf - 4, buf_size + 4); |
|
87 |
+ bytestream2_init(&s->gb, buf - 4, buf_size + 4); |
|
88 |
+ ff_msrle_decode(avctx, (AVPicture*)&s->frame, 8, &s->gb); |
|
88 | 89 |
break; |
89 | 90 |
default: |
90 | 91 |
av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr); |
... | ... |
@@ -52,6 +52,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, |
52 | 52 |
uint8_t *ptr; |
53 | 53 |
int dsize; |
54 | 54 |
const uint8_t *buf0 = buf; |
55 |
+ GetByteContext gb; |
|
55 | 56 |
|
56 | 57 |
if(buf_size < 14){ |
57 | 58 |
av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size); |
... | ... |
@@ -265,7 +266,8 @@ static int bmp_decode_frame(AVCodecContext *avctx, |
265 | 265 |
p->data[0] += p->linesize[0] * (avctx->height - 1); |
266 | 266 |
p->linesize[0] = -p->linesize[0]; |
267 | 267 |
} |
268 |
- ff_msrle_decode(avctx, (AVPicture*)p, depth, buf, dsize); |
|
268 |
+ bytestream2_init(&gb, buf, dsize); |
|
269 |
+ ff_msrle_decode(avctx, (AVPicture*)p, depth, &gb); |
|
269 | 270 |
if(height < 0){ |
270 | 271 |
p->data[0] += p->linesize[0] * (avctx->height - 1); |
271 | 272 |
p->linesize[0] = -p->linesize[0]; |
... | ... |
@@ -40,6 +40,7 @@ typedef struct MsrleContext { |
40 | 40 |
AVCodecContext *avctx; |
41 | 41 |
AVFrame frame; |
42 | 42 |
|
43 |
+ GetByteContext gb; |
|
43 | 44 |
const unsigned char *buf; |
44 | 45 |
int size; |
45 | 46 |
|
... | ... |
@@ -123,7 +124,8 @@ static int msrle_decode_frame(AVCodecContext *avctx, |
123 | 123 |
ptr += s->frame.linesize[0]; |
124 | 124 |
} |
125 | 125 |
} else { |
126 |
- ff_msrle_decode(avctx, (AVPicture*)&s->frame, avctx->bits_per_coded_sample, buf, buf_size); |
|
126 |
+ bytestream2_init(&s->gb, buf, buf_size); |
|
127 |
+ ff_msrle_decode(avctx, (AVPicture*)&s->frame, avctx->bits_per_coded_sample, &s->gb); |
|
127 | 128 |
} |
128 | 129 |
|
129 | 130 |
*data_size = sizeof(AVFrame); |
... | ... |
@@ -30,18 +30,9 @@ |
30 | 30 |
#include "avcodec.h" |
31 | 31 |
#include "msrledec.h" |
32 | 32 |
|
33 |
-#define FETCH_NEXT_STREAM_BYTE() \ |
|
34 |
- if (stream_ptr >= data_size) \ |
|
35 |
- { \ |
|
36 |
- av_log(avctx, AV_LOG_ERROR, " MS RLE: stream ptr just went out of bounds (1)\n"); \ |
|
37 |
- return -1; \ |
|
38 |
- } \ |
|
39 |
- stream_byte = data[stream_ptr++]; |
|
40 |
- |
|
41 | 33 |
static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, |
42 |
- const uint8_t *data, int data_size) |
|
34 |
+ GetByteContext *gb) |
|
43 | 35 |
{ |
44 |
- int stream_ptr = 0; |
|
45 | 36 |
unsigned char rle_code; |
46 | 37 |
unsigned char extra_byte, odd_pixel; |
47 | 38 |
unsigned char stream_byte; |
... | ... |
@@ -52,11 +43,16 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, |
52 | 52 |
int i; |
53 | 53 |
|
54 | 54 |
while (row_ptr >= 0) { |
55 |
- FETCH_NEXT_STREAM_BYTE(); |
|
56 |
- rle_code = stream_byte; |
|
55 |
+ if (bytestream2_get_bytes_left(gb) <= 0) { |
|
56 |
+ av_log(avctx, AV_LOG_ERROR, |
|
57 |
+ "MS RLE: bytestream overrun, %d rows left\n", |
|
58 |
+ row_ptr); |
|
59 |
+ return AVERROR_INVALIDDATA; |
|
60 |
+ } |
|
61 |
+ rle_code = stream_byte = bytestream2_get_byteu(gb); |
|
57 | 62 |
if (rle_code == 0) { |
58 | 63 |
/* fetch the next byte to see how to handle escape code */ |
59 |
- FETCH_NEXT_STREAM_BYTE(); |
|
64 |
+ stream_byte = bytestream2_get_byte(gb); |
|
60 | 65 |
if (stream_byte == 0) { |
61 | 66 |
/* line is done, goto the next one */ |
62 | 67 |
row_ptr -= row_dec; |
... | ... |
@@ -66,24 +62,26 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, |
66 | 66 |
return 0; |
67 | 67 |
} else if (stream_byte == 2) { |
68 | 68 |
/* reposition frame decode coordinates */ |
69 |
- FETCH_NEXT_STREAM_BYTE(); |
|
69 |
+ stream_byte = bytestream2_get_byte(gb); |
|
70 | 70 |
pixel_ptr += stream_byte; |
71 |
- FETCH_NEXT_STREAM_BYTE(); |
|
71 |
+ stream_byte = bytestream2_get_byte(gb); |
|
72 | 72 |
row_ptr -= stream_byte * row_dec; |
73 | 73 |
} else { |
74 | 74 |
// copy pixels from encoded stream |
75 | 75 |
odd_pixel = stream_byte & 1; |
76 | 76 |
rle_code = (stream_byte + 1) / 2; |
77 | 77 |
extra_byte = rle_code & 0x01; |
78 |
- if (row_ptr + pixel_ptr + stream_byte > frame_size) { |
|
79 |
- av_log(avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (1)\n"); |
|
80 |
- return -1; |
|
78 |
+ if (row_ptr + pixel_ptr + stream_byte > frame_size || |
|
79 |
+ bytestream2_get_bytes_left(gb) < rle_code) { |
|
80 |
+ av_log(avctx, AV_LOG_ERROR, |
|
81 |
+ "MS RLE: frame/stream ptr just went out of bounds (copy)\n"); |
|
82 |
+ return AVERROR_INVALIDDATA; |
|
81 | 83 |
} |
82 | 84 |
|
83 | 85 |
for (i = 0; i < rle_code; i++) { |
84 | 86 |
if (pixel_ptr >= avctx->width) |
85 | 87 |
break; |
86 |
- FETCH_NEXT_STREAM_BYTE(); |
|
88 |
+ stream_byte = bytestream2_get_byteu(gb); |
|
87 | 89 |
pic->data[0][row_ptr + pixel_ptr] = stream_byte >> 4; |
88 | 90 |
pixel_ptr++; |
89 | 91 |
if (i + 1 == rle_code && odd_pixel) |
... | ... |
@@ -96,15 +94,16 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, |
96 | 96 |
|
97 | 97 |
// if the RLE code is odd, skip a byte in the stream |
98 | 98 |
if (extra_byte) |
99 |
- stream_ptr++; |
|
99 |
+ bytestream2_skip(gb, 1); |
|
100 | 100 |
} |
101 | 101 |
} else { |
102 | 102 |
// decode a run of data |
103 | 103 |
if (row_ptr + pixel_ptr + stream_byte > frame_size) { |
104 |
- av_log(avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (1)\n"); |
|
105 |
- return -1; |
|
104 |
+ av_log(avctx, AV_LOG_ERROR, |
|
105 |
+ "MS RLE: frame ptr just went out of bounds (run)\n"); |
|
106 |
+ return AVERROR_INVALIDDATA; |
|
106 | 107 |
} |
107 |
- FETCH_NEXT_STREAM_BYTE(); |
|
108 |
+ stream_byte = bytestream2_get_byte(gb); |
|
108 | 109 |
for (i = 0; i < rle_code; i++) { |
109 | 110 |
if (pixel_ptr >= avctx->width) |
110 | 111 |
break; |
... | ... |
@@ -118,21 +117,21 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, |
118 | 118 |
} |
119 | 119 |
|
120 | 120 |
/* one last sanity check on the way out */ |
121 |
- if (stream_ptr < data_size) { |
|
122 |
- av_log(avctx, AV_LOG_ERROR, " MS RLE: ended frame decode with bytes left over (%d < %d)\n", |
|
123 |
- stream_ptr, data_size); |
|
124 |
- return -1; |
|
121 |
+ if (bytestream2_get_bytes_left(gb)) { |
|
122 |
+ av_log(avctx, AV_LOG_ERROR, |
|
123 |
+ "MS RLE: ended frame decode with %d bytes left over\n", |
|
124 |
+ bytestream2_get_bytes_left(gb)); |
|
125 |
+ return AVERROR_INVALIDDATA; |
|
125 | 126 |
} |
126 | 127 |
|
127 | 128 |
return 0; |
128 | 129 |
} |
129 | 130 |
|
130 | 131 |
|
131 |
-static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int depth, |
|
132 |
- const uint8_t *data, int srcsize) |
|
132 |
+static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, |
|
133 |
+ int depth, GetByteContext *gb) |
|
133 | 134 |
{ |
134 | 135 |
uint8_t *output, *output_end; |
135 |
- const uint8_t* src = data; |
|
136 | 136 |
int p1, p2, line=avctx->height - 1, pos=0, i; |
137 | 137 |
uint16_t pix16; |
138 | 138 |
uint32_t pix32; |
... | ... |
@@ -140,23 +139,29 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de |
140 | 140 |
|
141 | 141 |
output = pic->data[0] + (avctx->height - 1) * pic->linesize[0]; |
142 | 142 |
output_end = pic->data[0] + avctx->height * pic->linesize[0]; |
143 |
- while(src < data + srcsize) { |
|
144 |
- p1 = *src++; |
|
143 |
+ while (bytestream2_get_bytes_left(gb) > 0) { |
|
144 |
+ p1 = bytestream2_get_byteu(gb); |
|
145 | 145 |
if(p1 == 0) { //Escape code |
146 |
- p2 = *src++; |
|
146 |
+ p2 = bytestream2_get_byte(gb); |
|
147 | 147 |
if(p2 == 0) { //End-of-line |
148 | 148 |
output = pic->data[0] + (--line) * pic->linesize[0]; |
149 |
- if (line < 0 && !(src+1 < data + srcsize && AV_RB16(src) == 1)) { |
|
150 |
- av_log(avctx, AV_LOG_ERROR, "Next line is beyond picture bounds\n"); |
|
151 |
- return -1; |
|
149 |
+ if (line < 0) { |
|
150 |
+ if (bytestream2_get_be16(gb) == 1) { // end-of-picture |
|
151 |
+ return 0; |
|
152 |
+ } else { |
|
153 |
+ av_log(avctx, AV_LOG_ERROR, |
|
154 |
+ "Next line is beyond picture bounds (%d bytes left)\n", |
|
155 |
+ bytestream2_get_bytes_left(gb)); |
|
156 |
+ return AVERROR_INVALIDDATA; |
|
157 |
+ } |
|
152 | 158 |
} |
153 | 159 |
pos = 0; |
154 | 160 |
continue; |
155 | 161 |
} else if(p2 == 1) { //End-of-picture |
156 | 162 |
return 0; |
157 | 163 |
} else if(p2 == 2) { //Skip |
158 |
- p1 = *src++; |
|
159 |
- p2 = *src++; |
|
164 |
+ p1 = bytestream2_get_byte(gb); |
|
165 |
+ p2 = bytestream2_get_byte(gb); |
|
160 | 166 |
line -= p2; |
161 | 167 |
pos += p1; |
162 | 168 |
if (line < 0 || pos >= width){ |
... | ... |
@@ -167,31 +172,31 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de |
167 | 167 |
continue; |
168 | 168 |
} |
169 | 169 |
// Copy data |
170 |
- if ((pic->linesize[0] > 0 && output + p2 * (depth >> 3) > output_end) |
|
171 |
- ||(pic->linesize[0] < 0 && output + p2 * (depth >> 3) < output_end)) { |
|
172 |
- src += p2 * (depth >> 3); |
|
170 |
+ if ((pic->linesize[0] > 0 && output + p2 * (depth >> 3) > output_end) || |
|
171 |
+ (pic->linesize[0] < 0 && output + p2 * (depth >> 3) < output_end)) { |
|
172 |
+ bytestream2_skip(gb, 2 * (depth >> 3)); |
|
173 | 173 |
continue; |
174 |
+ } else if (bytestream2_get_bytes_left(gb) < p2 * (depth >> 3)) { |
|
175 |
+ av_log(avctx, AV_LOG_ERROR, "bytestream overrun\n"); |
|
176 |
+ return AVERROR_INVALIDDATA; |
|
174 | 177 |
} |
178 |
+ |
|
175 | 179 |
if ((depth == 8) || (depth == 24)) { |
176 | 180 |
for(i = 0; i < p2 * (depth >> 3); i++) { |
177 |
- *output++ = *src++; |
|
181 |
+ *output++ = bytestream2_get_byteu(gb); |
|
178 | 182 |
} |
179 | 183 |
// RLE8 copy is actually padded - and runs are not! |
180 | 184 |
if(depth == 8 && (p2 & 1)) { |
181 |
- src++; |
|
185 |
+ bytestream2_skip(gb, 1); |
|
182 | 186 |
} |
183 | 187 |
} else if (depth == 16) { |
184 | 188 |
for(i = 0; i < p2; i++) { |
185 |
- pix16 = AV_RL16(src); |
|
186 |
- src += 2; |
|
187 |
- *(uint16_t*)output = pix16; |
|
189 |
+ *(uint16_t*)output = bytestream2_get_le16u(gb); |
|
188 | 190 |
output += 2; |
189 | 191 |
} |
190 | 192 |
} else if (depth == 32) { |
191 | 193 |
for(i = 0; i < p2; i++) { |
192 |
- pix32 = AV_RL32(src); |
|
193 |
- src += 4; |
|
194 |
- *(uint32_t*)output = pix32; |
|
194 |
+ *(uint32_t*)output = bytestream2_get_le32u(gb); |
|
195 | 195 |
output += 4; |
196 | 196 |
} |
197 | 197 |
} |
... | ... |
@@ -199,21 +204,19 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de |
199 | 199 |
} else { //run of pixels |
200 | 200 |
uint8_t pix[3]; //original pixel |
201 | 201 |
switch(depth){ |
202 |
- case 8: pix[0] = *src++; |
|
202 |
+ case 8: pix[0] = bytestream2_get_byte(gb); |
|
203 | 203 |
break; |
204 |
- case 16: pix16 = AV_RL16(src); |
|
205 |
- src += 2; |
|
204 |
+ case 16: pix16 = bytestream2_get_le16(gb); |
|
206 | 205 |
break; |
207 |
- case 24: pix[0] = *src++; |
|
208 |
- pix[1] = *src++; |
|
209 |
- pix[2] = *src++; |
|
206 |
+ case 24: pix[0] = bytestream2_get_byte(gb); |
|
207 |
+ pix[1] = bytestream2_get_byte(gb); |
|
208 |
+ pix[2] = bytestream2_get_byte(gb); |
|
210 | 209 |
break; |
211 |
- case 32: pix32 = AV_RL32(src); |
|
212 |
- src += 4; |
|
210 |
+ case 32: pix32 = bytestream2_get_le32(gb); |
|
213 | 211 |
break; |
214 | 212 |
} |
215 |
- if ((pic->linesize[0] > 0 && output + p1 * (depth >> 3) > output_end) |
|
216 |
- ||(pic->linesize[0] < 0 && output + p1 * (depth >> 3) < output_end)) |
|
213 |
+ if ((pic->linesize[0] > 0 && output + p1 * (depth >> 3) > output_end) || |
|
214 |
+ (pic->linesize[0] < 0 && output + p1 * (depth >> 3) < output_end)) |
|
217 | 215 |
continue; |
218 | 216 |
for(i = 0; i < p1; i++) { |
219 | 217 |
switch(depth){ |
... | ... |
@@ -240,17 +243,17 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de |
240 | 240 |
} |
241 | 241 |
|
242 | 242 |
|
243 |
-int ff_msrle_decode(AVCodecContext *avctx, AVPicture *pic, int depth, |
|
244 |
- const uint8_t* data, int data_size) |
|
243 |
+int ff_msrle_decode(AVCodecContext *avctx, AVPicture *pic, |
|
244 |
+ int depth, GetByteContext *gb) |
|
245 | 245 |
{ |
246 | 246 |
switch(depth){ |
247 | 247 |
case 4: |
248 |
- return msrle_decode_pal4(avctx, pic, data, data_size); |
|
248 |
+ return msrle_decode_pal4(avctx, pic, gb); |
|
249 | 249 |
case 8: |
250 | 250 |
case 16: |
251 | 251 |
case 24: |
252 | 252 |
case 32: |
253 |
- return msrle_decode_8_16_24_32(avctx, pic, depth, data, data_size); |
|
253 |
+ return msrle_decode_8_16_24_32(avctx, pic, depth, gb); |
|
254 | 254 |
default: |
255 | 255 |
av_log(avctx, AV_LOG_ERROR, "Unknown depth %d\n", depth); |
256 | 256 |
return -1; |
... | ... |
@@ -23,6 +23,7 @@ |
23 | 23 |
#define AVCODEC_MSRLEDEC_H |
24 | 24 |
|
25 | 25 |
#include "avcodec.h" |
26 |
+#include "bytestream.h" |
|
26 | 27 |
|
27 | 28 |
/** |
28 | 29 |
* Decode stream in MS RLE format into frame. |
... | ... |
@@ -30,10 +31,9 @@ |
30 | 30 |
* @param avctx codec context |
31 | 31 |
* @param pic destination frame |
32 | 32 |
* @param depth bit depth |
33 |
- * @param data input stream |
|
34 |
- * @param data_size input size |
|
33 |
+ * @param gb input bytestream context |
|
35 | 34 |
*/ |
36 |
-int ff_msrle_decode(AVCodecContext *avctx, AVPicture *pic, int depth, |
|
37 |
- const uint8_t* data, int data_size); |
|
35 |
+int ff_msrle_decode(AVCodecContext *avctx, AVPicture *pic, |
|
36 |
+ int depth, GetByteContext *gb); |
|
38 | 37 |
|
39 | 38 |
#endif /* AVCODEC_MSRLEDEC_H */ |
... | ... |
@@ -58,6 +58,7 @@ typedef struct TsccContext { |
58 | 58 |
unsigned int decomp_size; |
59 | 59 |
// Decompression buffer |
60 | 60 |
unsigned char* decomp_buf; |
61 |
+ GetByteContext gb; |
|
61 | 62 |
int height; |
62 | 63 |
z_stream zstream; |
63 | 64 |
|
... | ... |
@@ -105,8 +106,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac |
105 | 105 |
} |
106 | 106 |
|
107 | 107 |
|
108 |
- if(zret != Z_DATA_ERROR) |
|
109 |
- ff_msrle_decode(avctx, (AVPicture*)&c->pic, c->bpp, c->decomp_buf, c->decomp_size - c->zstream.avail_out); |
|
108 |
+ if (zret != Z_DATA_ERROR) { |
|
109 |
+ bytestream2_init(&c->gb, c->decomp_buf, |
|
110 |
+ c->decomp_size - c->zstream.avail_out); |
|
111 |
+ ff_msrle_decode(avctx, (AVPicture*)&c->pic, c->bpp, &c->gb); |
|
112 |
+ } |
|
110 | 113 |
|
111 | 114 |
/* make the palette available on the way out */ |
112 | 115 |
if (c->avctx->pix_fmt == PIX_FMT_PAL8) { |