Add some bounds checking to CLLC; reduce HQX variable scoping,
add an error message.
... | ... |
@@ -156,7 +156,7 @@ OBJS-$(CONFIG_CDXL_DECODER) += cdxl.o |
156 | 156 |
OBJS-$(CONFIG_CINEPAK_DECODER) += cinepak.o |
157 | 157 |
OBJS-$(CONFIG_CLJR_DECODER) += cljrdec.o |
158 | 158 |
OBJS-$(CONFIG_CLJR_ENCODER) += cljrenc.o |
159 |
-OBJS-$(CONFIG_CLLC_DECODER) += cllc.o |
|
159 |
+OBJS-$(CONFIG_CLLC_DECODER) += cllc.o canopus.o |
|
160 | 160 |
OBJS-$(CONFIG_COOK_DECODER) += cook.o |
161 | 161 |
OBJS-$(CONFIG_COMFORTNOISE_DECODER) += cngdec.o celp_filters.o |
162 | 162 |
OBJS-$(CONFIG_COMFORTNOISE_ENCODER) += cngenc.o |
... | ... |
@@ -232,7 +232,7 @@ OBJS-$(CONFIG_HEVC_DECODER) += hevc.o hevc_mvs.o hevc_ps.o hevc_sei.o |
232 | 232 |
hevc_cabac.o hevc_refs.o hevcpred.o \ |
233 | 233 |
hevcdsp.o hevc_filter.o |
234 | 234 |
OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o |
235 |
-OBJS-$(CONFIG_HQX_DECODER) += hqx.o hqxvlc.o hqxdsp.o |
|
235 |
+OBJS-$(CONFIG_HQX_DECODER) += hqx.o hqxvlc.o hqxdsp.o canopus.o |
|
236 | 236 |
OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o huffyuvdec.o |
237 | 237 |
OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o huffyuvenc.o |
238 | 238 |
OBJS-$(CONFIG_IDCIN_DECODER) += idcinvideo.o |
239 | 239 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,63 @@ |
0 |
+/* |
|
1 |
+ * Canopus common routines |
|
2 |
+ * Copyright (c) 2015 Vittorio Giovara <vittorio.giovara@gmail.com> |
|
3 |
+ * |
|
4 |
+ * This file is part of Libav. |
|
5 |
+ * |
|
6 |
+ * Libav is free software; you can redistribute it and/or |
|
7 |
+ * modify it under the terms of the GNU Lesser General Public |
|
8 |
+ * License as published by the Free Software Foundation; either |
|
9 |
+ * version 2.1 of the License, or (at your option) any later version. |
|
10 |
+ * |
|
11 |
+ * Libav is distributed in the hope that it will be useful, |
|
12 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 |
+ * Lesser General Public License for more details. |
|
15 |
+ * |
|
16 |
+ * You should have received a copy of the GNU Lesser General Public |
|
17 |
+ * License along with Libav; if not, write to the Free Software |
|
18 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
19 |
+ */ |
|
20 |
+ |
|
21 |
+#include <stdint.h> |
|
22 |
+ |
|
23 |
+#include "libavutil/rational.h" |
|
24 |
+ |
|
25 |
+#include "avcodec.h" |
|
26 |
+#include "bytestream.h" |
|
27 |
+#include "canopus.h" |
|
28 |
+ |
|
29 |
+int ff_canopus_parse_info_tag(AVCodecContext *avctx, |
|
30 |
+ const uint8_t *src, size_t size) |
|
31 |
+{ |
|
32 |
+ GetByteContext gbc; |
|
33 |
+ int par_x, par_y, field_order; |
|
34 |
+ |
|
35 |
+ bytestream2_init(&gbc, src, size); |
|
36 |
+ |
|
37 |
+ /* Parse aspect ratio. */ |
|
38 |
+ bytestream2_skip(&gbc, 8); // unknown, 16 bits 1 |
|
39 |
+ par_x = bytestream2_get_le32(&gbc); |
|
40 |
+ par_y = bytestream2_get_le32(&gbc); |
|
41 |
+ if (par_x && par_y) |
|
42 |
+ av_reduce(&avctx->sample_aspect_ratio.num, |
|
43 |
+ &avctx->sample_aspect_ratio.den, |
|
44 |
+ par_x, par_y, 255); |
|
45 |
+ |
|
46 |
+ /* Short INFO tag (used in CLLC) has only AR data. */ |
|
47 |
+ if (size == 0x18) |
|
48 |
+ return 0; |
|
49 |
+ |
|
50 |
+ bytestream2_skip(&gbc, 16); // unknown RDRT tag |
|
51 |
+ |
|
52 |
+ /* Parse FIEL tag. */ |
|
53 |
+ bytestream2_skip(&gbc, 8); // 'FIEL' and 4 bytes 0 |
|
54 |
+ field_order = bytestream2_get_le32(&gbc); |
|
55 |
+ switch (field_order) { |
|
56 |
+ case 0: avctx->field_order = AV_FIELD_TT; break; |
|
57 |
+ case 1: avctx->field_order = AV_FIELD_BB; break; |
|
58 |
+ case 2: avctx->field_order = AV_FIELD_PROGRESSIVE; break; |
|
59 |
+ } |
|
60 |
+ |
|
61 |
+ return 0; |
|
62 |
+} |
0 | 63 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,32 @@ |
0 |
+/* |
|
1 |
+ * Canopus common routines |
|
2 |
+ * Copyright (c) 2015 Vittorio Giovara <vittorio.giovara@gmail.com> |
|
3 |
+ * |
|
4 |
+ * This file is part of Libav. |
|
5 |
+ * |
|
6 |
+ * Libav is free software; you can redistribute it and/or |
|
7 |
+ * modify it under the terms of the GNU Lesser General Public |
|
8 |
+ * License as published by the Free Software Foundation; either |
|
9 |
+ * version 2.1 of the License, or (at your option) any later version. |
|
10 |
+ * |
|
11 |
+ * Libav is distributed in the hope that it will be useful, |
|
12 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 |
+ * Lesser General Public License for more details. |
|
15 |
+ * |
|
16 |
+ * You should have received a copy of the GNU Lesser General Public |
|
17 |
+ * License along with Libav; if not, write to the Free Software |
|
18 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
19 |
+ */ |
|
20 |
+ |
|
21 |
+#ifndef AVCODEC_CANOPUS_H |
|
22 |
+#define AVCODEC_CANOPUS_H |
|
23 |
+ |
|
24 |
+#include <stdint.h> |
|
25 |
+ |
|
26 |
+#include "avcodec.h" |
|
27 |
+ |
|
28 |
+int ff_canopus_parse_info_tag(AVCodecContext *avctx, |
|
29 |
+ const uint8_t *src, size_t size); |
|
30 |
+ |
|
31 |
+#endif /* AVCODEC_CANOPUS_H */ |
... | ... |
@@ -24,6 +24,7 @@ |
24 | 24 |
|
25 | 25 |
#include "libavutil/intreadwrite.h" |
26 | 26 |
#include "bswapdsp.h" |
27 |
+#include "canopus.h" |
|
27 | 28 |
#include "get_bits.h" |
28 | 29 |
#include "avcodec.h" |
29 | 30 |
#include "internal.h" |
... | ... |
@@ -362,7 +363,11 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data, |
362 | 362 |
GetBitContext gb; |
363 | 363 |
int coding_type, ret; |
364 | 364 |
|
365 |
- /* Skip the INFO header if present */ |
|
365 |
+ if (avpkt->size < 4 + 4) { |
|
366 |
+ av_log(avctx, AV_LOG_ERROR, "Frame is too small %d.\n", avpkt->size); |
|
367 |
+ return AVERROR_INVALIDDATA; |
|
368 |
+ } |
|
369 |
+ |
|
366 | 370 |
info_offset = 0; |
367 | 371 |
info_tag = AV_RL32(src); |
368 | 372 |
if (info_tag == MKTAG('I', 'N', 'F', 'O')) { |
... | ... |
@@ -373,11 +378,10 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data, |
373 | 373 |
info_offset); |
374 | 374 |
return AVERROR_INVALIDDATA; |
375 | 375 |
} |
376 |
+ ff_canopus_parse_info_tag(avctx, src + 8, info_offset); |
|
376 | 377 |
|
377 | 378 |
info_offset += 8; |
378 | 379 |
src += info_offset; |
379 |
- |
|
380 |
- av_log(avctx, AV_LOG_DEBUG, "Skipping INFO chunk.\n"); |
|
381 | 380 |
} |
382 | 381 |
|
383 | 382 |
data_size = (avpkt->size - info_offset) & ~1; |
... | ... |
@@ -24,6 +24,7 @@ |
24 | 24 |
#include "libavutil/intreadwrite.h" |
25 | 25 |
|
26 | 26 |
#include "avcodec.h" |
27 |
+#include "canopus.h" |
|
27 | 28 |
#include "get_bits.h" |
28 | 29 |
#include "internal.h" |
29 | 30 |
|
... | ... |
@@ -405,29 +406,28 @@ static int hqx_decode_frame(AVCodecContext *avctx, void *data, |
405 | 405 |
{ |
406 | 406 |
HQXContext *ctx = avctx->priv_data; |
407 | 407 |
uint8_t *src = avpkt->data; |
408 |
- uint32_t info_tag, info_offset; |
|
408 |
+ uint32_t info_tag; |
|
409 | 409 |
int data_start; |
410 | 410 |
int i, ret; |
411 | 411 |
|
412 |
- if (avpkt->size < 8) |
|
412 |
+ if (avpkt->size < 4 + 4) { |
|
413 |
+ av_log(avctx, AV_LOG_ERROR, "Frame is too small %d.\n", avpkt->size); |
|
413 | 414 |
return AVERROR_INVALIDDATA; |
415 |
+ } |
|
414 | 416 |
|
415 |
- /* Skip the INFO header if present */ |
|
416 |
- info_offset = 0; |
|
417 | 417 |
info_tag = AV_RL32(src); |
418 | 418 |
if (info_tag == MKTAG('I', 'N', 'F', 'O')) { |
419 |
- info_offset = AV_RL32(src + 4); |
|
419 |
+ int info_offset = AV_RL32(src + 4); |
|
420 | 420 |
if (info_offset > UINT32_MAX - 8 || info_offset + 8 > avpkt->size) { |
421 | 421 |
av_log(avctx, AV_LOG_ERROR, |
422 | 422 |
"Invalid INFO header offset: 0x%08"PRIX32" is too large.\n", |
423 | 423 |
info_offset); |
424 | 424 |
return AVERROR_INVALIDDATA; |
425 | 425 |
} |
426 |
+ ff_canopus_parse_info_tag(avctx, src + 8, info_offset); |
|
426 | 427 |
|
427 | 428 |
info_offset += 8; |
428 | 429 |
src += info_offset; |
429 |
- |
|
430 |
- av_log(avctx, AV_LOG_DEBUG, "Skipping INFO chunk.\n"); |
|
431 | 430 |
} |
432 | 431 |
|
433 | 432 |
data_start = src - avpkt->data; |