X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=libavcodec%2Fdxv.c;h=4fdfd65404d40f06404e696c9dfcd7ea2fb755ee;hb=a852db796edce2792525d88ab47cf78222e01512;hp=e375734ebd6d26875beba567c1398509924e48d0;hpb=64f72bb61f0f341698c75231ff7deaa2be3853b2;p=ffmpeg diff --git a/libavcodec/dxv.c b/libavcodec/dxv.c index e375734ebd6..4fdfd65404d 100644 --- a/libavcodec/dxv.c +++ b/libavcodec/dxv.c @@ -314,6 +314,15 @@ static int dxv_decompress_lzf(AVCodecContext *avctx) return ff_lzf_uncompress(&ctx->gbc, &ctx->tex_data, &ctx->tex_size); } +static int dxv_decompress_raw(AVCodecContext *avctx) +{ + DXVContext *ctx = avctx->priv_data; + GetByteContext *gbc = &ctx->gbc; + + bytestream2_get_buffer(gbc, ctx->tex_data, ctx->tex_size); + return 0; +} + static int dxv_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { @@ -321,8 +330,10 @@ static int dxv_decode(AVCodecContext *avctx, void *data, ThreadFrame tframe; GetByteContext *gbc = &ctx->gbc; int (*decompress_tex)(AVCodecContext *avctx); + const char *msgcomp, *msgtext; uint32_t tag; - int channels, size = 0, old_type = 0; + int version_major, version_minor = 0; + int size = 0, old_type = 0; int ret; bytestream2_init(gbc, avpkt->data, avpkt->size); @@ -334,14 +345,16 @@ static int dxv_decode(AVCodecContext *avctx, void *data, ctx->tex_funct = ctx->texdsp.dxt1_block; ctx->tex_rat = 8; ctx->tex_step = 8; - av_log(avctx, AV_LOG_DEBUG, "DXTR1 compression and DXT1 texture "); + msgcomp = "DXTR1"; + msgtext = "DXT1"; break; case MKBETAG('D', 'X', 'T', '5'): decompress_tex = dxv_decompress_dxt5; ctx->tex_funct = ctx->texdsp.dxt5_block; ctx->tex_rat = 4; ctx->tex_step = 16; - av_log(avctx, AV_LOG_DEBUG, "DXTR5 compression and DXT5 texture "); + msgcomp = "DXTR5"; + msgtext = "DXT5"; break; case MKBETAG('Y', 'C', 'G', '6'): case MKBETAG('Y', 'G', '1', '0'): @@ -351,34 +364,56 @@ static int dxv_decode(AVCodecContext *avctx, void *data, /* Old version does not have a real header, just size and type. */ size = tag & 0x00FFFFFF; old_type = tag >> 24; - channels = old_type & 0x0F; + version_major = (old_type & 0x0F) - 1; + + if (old_type & 0x80) { + msgcomp = "RAW"; + decompress_tex = dxv_decompress_raw; + } else { + msgcomp = "LZF"; + decompress_tex = dxv_decompress_lzf; + } + if (old_type & 0x40) { - av_log(avctx, AV_LOG_DEBUG, "LZF compression and DXT5 texture "); + msgtext = "DXT5"; + ctx->tex_funct = ctx->texdsp.dxt5_block; ctx->tex_step = 16; - } else if (old_type & 0x20 || old_type & 0x2) { - av_log(avctx, AV_LOG_DEBUG, "LZF compression and DXT1 texture "); + } else if (old_type & 0x20 || version_major == 1) { + msgtext = "DXT1"; + ctx->tex_funct = ctx->texdsp.dxt1_block; ctx->tex_step = 8; } else { av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08X)\n.", tag); return AVERROR_INVALIDDATA; } - decompress_tex = dxv_decompress_lzf; ctx->tex_rat = 1; break; } /* New header is 12 bytes long. */ if (!old_type) { - channels = bytestream2_get_byte(gbc); - bytestream2_skip(gbc, 3); // unknown + version_major = bytestream2_get_byte(gbc) - 1; + version_minor = bytestream2_get_byte(gbc); + + /* Encoder copies texture data when compression is not advantageous. */ + if (bytestream2_get_byte(gbc)) { + msgcomp = "RAW"; + ctx->tex_rat = 1; + decompress_tex = dxv_decompress_raw; + } + + bytestream2_skip(gbc, 1); // unknown size = bytestream2_get_le32(gbc); } - av_log(avctx, AV_LOG_DEBUG, "(%d channels)\n", channels); + av_log(avctx, AV_LOG_DEBUG, + "%s compression with %s texture (version %d.%d)\n", + msgcomp, msgtext, version_major, version_minor); if (size != bytestream2_get_bytes_left(gbc)) { - av_log(avctx, AV_LOG_ERROR, "Incomplete or invalid file (%u > %u)\n.", + av_log(avctx, AV_LOG_ERROR, + "Incomplete or invalid file (header %d, left %d).\n", size, bytestream2_get_bytes_left(gbc)); return AVERROR_INVALIDDATA; }