Used for cockpit in http://samples.mplayerhq.hu/game-formats/la-san/rebelassault/L8PLAY.ANM
Signed-off-by: Reimar Döffinger <reimar.doeffin...@gmx.de> --- libavcodec/sanm.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index 6aeaa2c..277949e 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -602,6 +602,43 @@ static int old_codec1(SANMVideoContext *ctx, int top, return 0; } +static int old_codec21(SANMVideoContext *ctx, int top, + int left, int width, int height) +{ + uint8_t *dst = ((uint8_t *)ctx->frm0) + left + top * ctx->pitch; + int i, len, end; + + for (i = 0; i < height; i++) { + int pos = 0; + if (bytestream2_get_bytes_left(&ctx->gb) < 4) + return AVERROR_INVALIDDATA; + + bytestream2_skip(&ctx->gb, 2); // 00 01 in the files tested + end = bytestream2_tell(&ctx->gb); + len = bytestream2_get_le16u(&ctx->gb); + end += len; + + while (bytestream2_tell(&ctx->gb) < end) { + int count; + if (bytestream2_get_bytes_left(&ctx->gb) < 4) + return AVERROR_INVALIDDATA; + + pos += bytestream2_get_le16u(&ctx->gb); + count = bytestream2_get_le16u(&ctx->gb) + 1; + if (pos + count > width) + return AVERROR_INVALIDDATA; + if (bytestream2_get_bytes_left(&ctx->gb) < count) + return AVERROR_INVALIDDATA; + bytestream2_get_bufferu(&ctx->gb, dst + pos, count); + pos += count; + } + dst += ctx->pitch; + } + ctx->rotate_code = 0; + + return 0; +} + static inline void codec37_mv(uint8_t *dst, const uint8_t *src, int height, int stride, int x, int y) { @@ -1125,6 +1162,10 @@ static int process_frame_obj(SANMVideoContext *ctx) return AVERROR_INVALIDDATA; } + // ignore negative values (padding?) + if (left & 0x8000) left = 0; + if (top & 0x8000) top = 0; + if (ctx->width < left + w || ctx->height < top + h) { int ret = ff_set_dimensions(ctx->avctx, FFMAX(left + w, ctx->width), FFMAX(top + h, ctx->height)); @@ -1137,7 +1178,7 @@ static int process_frame_obj(SANMVideoContext *ctx) return AVERROR(ENOMEM); } } - bytestream2_skip(&ctx->gb, 4); + bytestream2_skip(&ctx->gb, codec == 21 ? 2 : 4); switch (codec) { case 1: @@ -1147,6 +1188,8 @@ static int process_frame_obj(SANMVideoContext *ctx) ctx->prev_codec = codec; return old_codec1(ctx, top, left, w, h); break; + case 21: + return old_codec21(ctx, top, left, w, h); case 37: if (ctx->prev_codec == 1) FFSWAP(uint16_t*, ctx->frm0, ctx->frm1); ctx->prev_codec = codec; -- 2.7.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel