* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
*/
/**
- * @file xan.c
+ * @file libavcodec/xan.c
* Xan video decoder for Wing Commander III computer game
* by Mario Brito (mbrito@student.dei.uc.pt)
* and Mike Melanson (melanson@pcisys.net)
#include <string.h>
#include <unistd.h>
-#include "common.h"
+#include "libavutil/intreadwrite.h"
#include "avcodec.h"
typedef struct XanContext {
AVFrame last_frame;
AVFrame current_frame;
- unsigned char *buf;
+ const unsigned char *buf;
int size;
/* scratch space */
} XanContext;
-static int xan_decode_init(AVCodecContext *avctx)
+static av_cold int xan_decode_init(AVCodecContext *avctx)
{
XanContext *s = avctx->priv_data;
* memcpy doesn't like that; it's not uncommon, for example, for
* dest = src+1, to turn byte A into pattern AAAAAAAA.
* This was originally repz movsb in Intel x86 ASM. */
-static inline void bytecopy(unsigned char *dest, unsigned char *src, int count)
+static inline void bytecopy(unsigned char *dest, const unsigned char *src, int count)
{
int i;
dest[i] = src[i];
}
-static int xan_huffman_decode(unsigned char *dest, unsigned char *src,
+static int xan_huffman_decode(unsigned char *dest, const unsigned char *src,
int dest_len)
{
unsigned char byte = *src++;
unsigned char ival = byte + 0x16;
- unsigned char * ptr = src + byte*2;
+ const unsigned char * ptr = src + byte*2;
unsigned char val = ival;
int counter = 0;
unsigned char *dest_end = dest + dest_len;
return 0;
}
-static void xan_unpack(unsigned char *dest, unsigned char *src, int dest_len)
+static void xan_unpack(unsigned char *dest, const unsigned char *src, int dest_len)
{
unsigned char opcode;
int size;
}
static inline void xan_wc3_output_pixel_run(XanContext *s,
- unsigned char *pixel_buffer, int x, int y, int pixel_count)
+ const unsigned char *pixel_buffer, int x, int y, int pixel_count)
{
int stride;
int line_inc;
unsigned char *opcode_buffer = s->buffer1;
int opcode_buffer_size = s->buffer1_size;
- unsigned char *imagedata_buffer = s->buffer2;
- int imagedata_buffer_size = s->buffer2_size;
+ const unsigned char *imagedata_buffer = s->buffer2;
/* pointers to segments inside the compressed chunk */
- unsigned char *huffman_segment;
- unsigned char *size_segment;
- unsigned char *vector_segment;
- unsigned char *imagedata_segment;
+ const unsigned char *huffman_segment;
+ const unsigned char *size_segment;
+ const unsigned char *vector_segment;
+ const unsigned char *imagedata_segment;
huffman_segment = s->buf + AV_RL16(&s->buf[0]);
size_segment = s->buf + AV_RL16(&s->buf[2]);
xan_huffman_decode(opcode_buffer, huffman_segment, opcode_buffer_size);
if (imagedata_segment[0] == 2)
- xan_unpack(imagedata_buffer, &imagedata_segment[1],
- imagedata_buffer_size);
+ xan_unpack(s->buffer2, &imagedata_segment[1], s->buffer2_size);
else
imagedata_buffer = &imagedata_segment[1];
case 11:
case 21:
- size = (size_segment[0] << 16) | (size_segment[1] << 8) |
- size_segment[2];
+ size = AV_RB24(size_segment);
size_segment += 3;
break;
}
static int xan_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
- uint8_t *buf, int buf_size)
+ const uint8_t *buf, int buf_size)
{
XanContext *s = avctx->priv_data;
AVPaletteControl *palette_control = avctx->palctrl;
if (s->last_frame.data[0])
avctx->release_buffer(avctx, &s->last_frame);
- /* shuffle frames */
- s->last_frame = s->current_frame;
-
*data_size = sizeof(AVFrame);
*(AVFrame*)data = s->current_frame;
+ /* shuffle frames */
+ FFSWAP(AVFrame, s->current_frame, s->last_frame);
+
/* always report that the buffer was completely consumed */
return buf_size;
}
-static int xan_decode_end(AVCodecContext *avctx)
+static av_cold int xan_decode_end(AVCodecContext *avctx)
{
XanContext *s = avctx->priv_data;
- /* release the last frame */
+ /* release the frames */
if (s->last_frame.data[0])
avctx->release_buffer(avctx, &s->last_frame);
+ if (s->current_frame.data[0])
+ avctx->release_buffer(avctx, &s->current_frame);
av_free(s->buffer1);
av_free(s->buffer2);
xan_decode_end,
xan_decode_frame,
CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"),
};
/*