| 976 | } |
| 977 | |
| 978 | static int iv_decode_frame(AVCodecContext *avctx, |
| 979 | const uint8_t *buf, int buf_size) |
| 980 | { |
| 981 | Indeo3DecodeContext *s = avctx->priv_data; |
| 982 | unsigned int image_width, image_height, |
| 983 | chroma_width, chroma_height; |
| 984 | unsigned long flags, cb_offset, data_size, |
| 985 | y_offset, v_offset, u_offset, mc_vector_count; |
| 986 | const uint8_t *hdr_pos, *buf_pos; |
| 987 | |
| 988 | buf_pos = buf; |
| 989 | buf_pos += 18; /* skip OS header (16 bytes) and version number */ |
| 990 | |
| 991 | flags = bytestream_get_le16(&buf_pos); |
| 992 | data_size = bytestream_get_le32(&buf_pos); |
| 993 | cb_offset = *buf_pos++; |
| 994 | buf_pos += 3; /* skip reserved byte and checksum */ |
| 995 | image_height = bytestream_get_le16(&buf_pos); |
| 996 | image_width = bytestream_get_le16(&buf_pos); |
| 997 | |
| 998 | if(avcodec_check_dimensions(avctx, image_width, image_height)) |
| 999 | return -1; |
| 1000 | if (image_width != avctx->width || image_height != avctx->height) { |
| 1001 | int ret; |
| 1002 | avcodec_set_dimensions(avctx, image_width, image_height); |
| 1003 | s->width = avctx->width; |
| 1004 | s->height = avctx->height; |
| 1005 | ret = iv_alloc_frames(s); |
| 1006 | if (ret < 0) { |
| 1007 | s->width = s->height = 0; |
| 1008 | return ret; |
| 1009 | } |
| 1010 | } |
| 1011 | |
| 1012 | chroma_height = ((image_height >> 2) + 3) & 0x7ffc; |
| 1013 | chroma_width = ((image_width >> 2) + 3) & 0x7ffc; |
| 1014 | y_offset = bytestream_get_le32(&buf_pos); |
| 1015 | v_offset = bytestream_get_le32(&buf_pos); |
| 1016 | u_offset = bytestream_get_le32(&buf_pos); |
| 1017 | buf_pos += 4; /* reserved */ |
| 1018 | hdr_pos = buf_pos; |
| 1019 | if(data_size == 0x80) return 4; |
| 1020 | |
| 1021 | if(FFMAX3(y_offset, v_offset, u_offset) >= buf_size-16) { |
| 1022 | av_log(s->avctx, AV_LOG_ERROR, "y/u/v offset outside buffer\n"); |
| 1023 | return -1; |
| 1024 | } |
| 1025 | |
| 1026 | if(flags & 0x200) { |
| 1027 | s->cur_frame = s->iv_frame + 1; |
| 1028 | s->ref_frame = s->iv_frame; |
| 1029 | } else { |
| 1030 | s->cur_frame = s->iv_frame; |
| 1031 | s->ref_frame = s->iv_frame + 1; |
| 1032 | } |
| 1033 | |
| 1034 | buf_pos = buf + 16 + y_offset; |
| 1035 | mc_vector_count = bytestream_get_le32(&buf_pos); |
no test coverage detected