X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=libavcodec%2Fvqavideo.c;h=7a6308aeb108c42acd40ec09b6a731386a61a46c;hb=bcc73960657538f601dc90076e30df3cc6032569;hp=912ced0df8e056947f712e7c69491fa38d0df2c9;hpb=7667896a364edf67bfd2149a27bbc8f4a224ced5;p=ffmpeg diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c index 912ced0df8e..7a6308aeb10 100644 --- a/libavcodec/vqavideo.c +++ b/libavcodec/vqavideo.c @@ -2,29 +2,28 @@ * Westwood Studios VQA Video Decoder * Copyright (C) 2003 the ffmpeg project * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * */ /** - * @file vqavideo.c - * VQA Video Decoder by Mike Melanson (melanson@pcisys.net) - * For more information about the VQA format, visit: - * http://wiki.multimedia.cx/index.php?title=VQA + * @file + * VQA Video Decoder + * @author Mike Melanson (melanson@pcisys.net) + * @see http://wiki.multimedia.cx/index.php?title=VQA * * The VQA video decoder outputs PAL8 or RGB555 colorspace data, depending * on the type of data in the file. @@ -55,7 +54,7 @@ * file. This is an interesting technique, although it makes random file * seeking difficult despite the fact that the frames are all intracoded. * - * V1,2 VQA uses 12-bit codebook indices. If the 12-bit indices were + * V1,2 VQA uses 12-bit codebook indexes. If the 12-bit indexes were * packed into bytes and then RLE compressed, bytewise, the results would * be poor. That is why the coding method divides each index into 2 parts, * the top 4 bits and the bottom 8 bits, then RL encodes the 4-bit pieces @@ -67,11 +66,10 @@ #include #include #include -#include -#include "common.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/imgutils.h" #include "avcodec.h" -#include "dsputil.h" #define PALETTE_COUNT 256 #define VQA_HEADER_SIZE 0x2A @@ -92,21 +90,12 @@ #define CPLZ_TAG MKBETAG('C', 'P', 'L', 'Z') #define VPTZ_TAG MKBETAG('V', 'P', 'T', 'Z') -#define VQA_DEBUG 0 - -#if VQA_DEBUG -#define vqa_debug printf -#else -static inline void vqa_debug(const char *format, ...) { } -#endif - typedef struct VqaContext { AVCodecContext *avctx; - DSPContext dsp; AVFrame frame; - unsigned char *buf; + const unsigned char *buf; int size; uint32_t palette[PALETTE_COUNT]; @@ -131,16 +120,14 @@ typedef struct VqaContext { } VqaContext; -static int vqa_decode_init(AVCodecContext *avctx) +static av_cold int vqa_decode_init(AVCodecContext *avctx) { - VqaContext *s = (VqaContext *)avctx->priv_data; + VqaContext *s = avctx->priv_data; unsigned char *vqa_header; - int i, j, codebook_index;; + int i, j, codebook_index; s->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; - avctx->has_b_frames = 0; - dsputil_init(&s->dsp, avctx); /* make sure the extradata made it */ if (s->avctx->extradata_size != VQA_HEADER_SIZE) { @@ -151,9 +138,9 @@ static int vqa_decode_init(AVCodecContext *avctx) /* load up the VQA parameters from the header */ vqa_header = (unsigned char *)s->avctx->extradata; s->vqa_version = vqa_header[0]; - s->width = LE_16(&vqa_header[6]); - s->height = LE_16(&vqa_header[8]); - if(avcodec_check_dimensions(avctx, s->width, s->height)){ + s->width = AV_RL16(&vqa_header[6]); + s->height = AV_RL16(&vqa_header[8]); + if(av_image_check_size(s->width, s->height, 0, avctx)){ s->width= s->height= 0; return -1; } @@ -205,7 +192,7 @@ static int vqa_decode_init(AVCodecContext *avctx) return; \ } -static void decode_format80(unsigned char *src, int src_size, +static void decode_format80(const unsigned char *src, int src_size, unsigned char *dest, int dest_size, int check_size) { int src_index = 0; @@ -217,7 +204,7 @@ static void decode_format80(unsigned char *src, int src_size, while (src_index < src_size) { - vqa_debug(" opcode %02X: ", src[src_index]); + av_dlog(NULL, " opcode %02X: ", src[src_index]); /* 0x80 means that frame is finished */ if (src[src_index] == 0x80) @@ -232,11 +219,11 @@ static void decode_format80(unsigned char *src, int src_size, if (src[src_index] == 0xFF) { src_index++; - count = LE_16(&src[src_index]); + count = AV_RL16(&src[src_index]); src_index += 2; - src_pos = LE_16(&src[src_index]); + src_pos = AV_RL16(&src[src_index]); src_index += 2; - vqa_debug("(1) copy %X bytes from absolute pos %X\n", count, src_pos); + av_dlog(NULL, "(1) copy %X bytes from absolute pos %X\n", count, src_pos); CHECK_COUNT(); for (i = 0; i < count; i++) dest[dest_index + i] = dest[src_pos + i]; @@ -245,10 +232,10 @@ static void decode_format80(unsigned char *src, int src_size, } else if (src[src_index] == 0xFE) { src_index++; - count = LE_16(&src[src_index]); + count = AV_RL16(&src[src_index]); src_index += 2; color = src[src_index++]; - vqa_debug("(2) set %X bytes to %02X\n", count, color); + av_dlog(NULL, "(2) set %X bytes to %02X\n", count, color); CHECK_COUNT(); memset(&dest[dest_index], color, count); dest_index += count; @@ -256,9 +243,9 @@ static void decode_format80(unsigned char *src, int src_size, } else if ((src[src_index] & 0xC0) == 0xC0) { count = (src[src_index++] & 0x3F) + 3; - src_pos = LE_16(&src[src_index]); + src_pos = AV_RL16(&src[src_index]); src_index += 2; - vqa_debug("(3) copy %X bytes from absolute pos %X\n", count, src_pos); + av_dlog(NULL, "(3) copy %X bytes from absolute pos %X\n", count, src_pos); CHECK_COUNT(); for (i = 0; i < count; i++) dest[dest_index + i] = dest[src_pos + i]; @@ -267,7 +254,7 @@ static void decode_format80(unsigned char *src, int src_size, } else if (src[src_index] > 0x80) { count = src[src_index++] & 0x3F; - vqa_debug("(4) copy %X bytes from source to dest\n", count); + av_dlog(NULL, "(4) copy %X bytes from source to dest\n", count); CHECK_COUNT(); memcpy(&dest[dest_index], &src[src_index], count); src_index += count; @@ -276,9 +263,9 @@ static void decode_format80(unsigned char *src, int src_size, } else { count = ((src[src_index] & 0x70) >> 4) + 3; - src_pos = BE_16(&src[src_index]) & 0x0FFF; + src_pos = AV_RB16(&src[src_index]) & 0x0FFF; src_index += 2; - vqa_debug("(5) copy %X bytes from relpos %X\n", count, src_pos); + av_dlog(NULL, "(5) copy %X bytes from relpos %X\n", count, src_pos); CHECK_COUNT(); for (i = 0; i < count; i++) dest[dest_index + i] = dest[dest_index - src_pos + i]; @@ -326,8 +313,8 @@ static void vqa_decode_chunk(VqaContext *s) /* first, traverse through the frame and find the subchunks */ while (index < s->size) { - chunk_type = BE_32(&s->buf[index]); - chunk_size = BE_32(&s->buf[index + 4]); + chunk_type = AV_RB32(&s->buf[index]); + chunk_size = AV_RB32(&s->buf[index + 4]); switch (chunk_type) { @@ -391,7 +378,7 @@ static void vqa_decode_chunk(VqaContext *s) /* convert the RGB palette into the machine's endian format */ if (cpl0_chunk != -1) { - chunk_size = BE_32(&s->buf[cpl0_chunk + 4]); + chunk_size = AV_RB32(&s->buf[cpl0_chunk + 4]); /* sanity check the palette size */ if (chunk_size / 3 > 256) { av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found a palette chunk with %d colors\n", @@ -419,7 +406,7 @@ static void vqa_decode_chunk(VqaContext *s) /* decompress the full codebook chunk */ if (cbfz_chunk != -1) { - chunk_size = BE_32(&s->buf[cbfz_chunk + 4]); + chunk_size = AV_RB32(&s->buf[cbfz_chunk + 4]); cbfz_chunk += CHUNK_PREAMBLE_SIZE; decode_format80(&s->buf[cbfz_chunk], chunk_size, s->codebook, s->codebook_size, 0); @@ -428,7 +415,7 @@ static void vqa_decode_chunk(VqaContext *s) /* copy a full codebook */ if (cbf0_chunk != -1) { - chunk_size = BE_32(&s->buf[cbf0_chunk + 4]); + chunk_size = AV_RB32(&s->buf[cbf0_chunk + 4]); /* sanity check the full codebook size */ if (chunk_size > MAX_CODEBOOK_SIZE) { av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: CBF0 chunk too large (0x%X bytes)\n", @@ -448,7 +435,7 @@ static void vqa_decode_chunk(VqaContext *s) return; } - chunk_size = BE_32(&s->buf[vptz_chunk + 4]); + chunk_size = AV_RB32(&s->buf[vptz_chunk + 4]); vptz_chunk += CHUNK_PREAMBLE_SIZE; decode_format80(&s->buf[vptz_chunk], chunk_size, s->decode_buffer, s->decode_buffer_size, 1); @@ -469,8 +456,6 @@ static void vqa_decode_chunk(VqaContext *s) switch (s->vqa_version) { case 1: -/* still need sample media for this case (only one game, "Legend of - * Kyrandia III : Malcolm's Revenge", is known to use this version) */ lobyte = s->decode_buffer[lobytes * 2]; hibyte = s->decode_buffer[(lobytes * 2) + 1]; vector_index = ((hibyte << 8) | lobyte) >> 3; @@ -522,7 +507,7 @@ static void vqa_decode_chunk(VqaContext *s) if (cbp0_chunk != -1) { - chunk_size = BE_32(&s->buf[cbp0_chunk + 4]); + chunk_size = AV_RB32(&s->buf[cbp0_chunk + 4]); cbp0_chunk += CHUNK_PREAMBLE_SIZE; /* accumulate partial codebook */ @@ -545,7 +530,7 @@ static void vqa_decode_chunk(VqaContext *s) if (cbpz_chunk != -1) { - chunk_size = BE_32(&s->buf[cbpz_chunk + 4]); + chunk_size = AV_RB32(&s->buf[cbpz_chunk + 4]); cbpz_chunk += CHUNK_PREAMBLE_SIZE; /* accumulate partial codebook */ @@ -570,9 +555,11 @@ static void vqa_decode_chunk(VqaContext *s) static int vqa_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + AVPacket *avpkt) { - VqaContext *s = (VqaContext *)avctx->priv_data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + VqaContext *s = avctx->priv_data; s->buf = buf; s->size = buf_size; @@ -598,9 +585,9 @@ static int vqa_decode_frame(AVCodecContext *avctx, return buf_size; } -static int vqa_decode_end(AVCodecContext *avctx) +static av_cold int vqa_decode_end(AVCodecContext *avctx) { - VqaContext *s = (VqaContext *)avctx->priv_data; + VqaContext *s = avctx->priv_data; av_free(s->codebook); av_free(s->next_codebook_buffer); @@ -612,14 +599,14 @@ static int vqa_decode_end(AVCodecContext *avctx) return 0; } -AVCodec vqa_decoder = { - "vqavideo", - CODEC_TYPE_VIDEO, - CODEC_ID_WS_VQA, - sizeof(VqaContext), - vqa_decode_init, - NULL, - vqa_decode_end, - vqa_decode_frame, - CODEC_CAP_DR1, +AVCodec ff_vqa_decoder = { + .name = "vqavideo", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_WS_VQA, + .priv_data_size = sizeof(VqaContext), + .init = vqa_decode_init, + .close = vqa_decode_end, + .decode = vqa_decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Westwood Studios VQA (Vector Quantized Animation) video"), };