diff options
Diffstat (limited to 'src/libffmpeg/libavcodec/flicvideo.c')
-rw-r--r-- | src/libffmpeg/libavcodec/flicvideo.c | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/src/libffmpeg/libavcodec/flicvideo.c b/src/libffmpeg/libavcodec/flicvideo.c index fa128d0d3..95cb26ce4 100644 --- a/src/libffmpeg/libavcodec/flicvideo.c +++ b/src/libffmpeg/libavcodec/flicvideo.c @@ -2,18 +2,20 @@ * FLI/FLC Animation Video Decoder * Copyright (C) 2003, 2004 the ffmpeg project * - * This library is free software; you can redistribute it and/or + * This file is part of FFmpeg. + * + * FFmpeg 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 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * FFmpeg 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 this library; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ @@ -154,7 +156,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, int starting_line; signed short line_packets; int y_ptr; - signed char byte_run; + int byte_run; int pixel_skip; int pixel_countdown; unsigned char *pixels; @@ -188,7 +190,6 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, case FLI_256_COLOR: case FLI_COLOR: stream_ptr_after_color_chunk = stream_ptr + chunk_size - 6; - s->new_palette = 1; /* check special case: If this file is from the Magic Carpet * game and uses 6-bit colors even though it reports 256-color @@ -214,6 +215,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, color_changes = 256; for (j = 0; j < color_changes; j++) { + unsigned int entry; /* wrap around, for good measure */ if ((unsigned)palette_ptr >= 256) @@ -222,7 +224,10 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, r = buf[stream_ptr++] << color_shift; g = buf[stream_ptr++] << color_shift; b = buf[stream_ptr++] << color_shift; - s->palette[palette_ptr++] = (r << 16) | (g << 8) | b; + entry = (r << 16) | (g << 8) | b; + if (s->palette[palette_ptr] != entry) + s->new_palette = 1; + s->palette[palette_ptr++] = entry; } } @@ -241,9 +246,15 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, while (compressed_lines > 0) { line_packets = LE_16(&buf[stream_ptr]); stream_ptr += 2; - if (line_packets < 0) { + if ((line_packets & 0xC000) == 0xC000) { + // line skip opcode line_packets = -line_packets; y_ptr += line_packets * s->frame.linesize[0]; + } else if ((line_packets & 0xC000) == 0x4000) { + av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets); + } else if ((line_packets & 0xC000) == 0x8000) { + // "last byte" opcode + pixels[y_ptr + s->frame.linesize[0] - 1] = line_packets & 0xff; } else { compressed_lines--; pixel_ptr = y_ptr; @@ -253,7 +264,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, pixel_skip = buf[stream_ptr++]; pixel_ptr += pixel_skip; pixel_countdown -= pixel_skip; - byte_run = buf[stream_ptr++]; + byte_run = (signed char)(buf[stream_ptr++]); if (byte_run < 0) { byte_run = -byte_run; palette_idx1 = buf[stream_ptr++]; @@ -296,14 +307,14 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, pixel_skip = buf[stream_ptr++]; pixel_ptr += pixel_skip; pixel_countdown -= pixel_skip; - byte_run = buf[stream_ptr++]; + byte_run = (signed char)(buf[stream_ptr++]); if (byte_run > 0) { CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++, pixel_countdown--) { palette_idx1 = buf[stream_ptr++]; pixels[pixel_ptr++] = palette_idx1; } - } else { + } else if (byte_run < 0) { byte_run = -byte_run; palette_idx1 = buf[stream_ptr++]; CHECK_PIXEL_PTR(byte_run); @@ -336,7 +347,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, stream_ptr++; pixel_countdown = s->avctx->width; while (pixel_countdown > 0) { - byte_run = buf[stream_ptr++]; + byte_run = (signed char)(buf[stream_ptr++]); if (byte_run > 0) { palette_idx1 = buf[stream_ptr++]; CHECK_PIXEL_PTR(byte_run); @@ -402,9 +413,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, "and final chunk ptr = %d\n", buf_size, stream_ptr); /* make the palette available on the way out */ -// if (s->new_palette) { - if (1) { - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + if (s->new_palette) { s->frame.palette_has_changed = 1; s->new_palette = 0; } @@ -439,7 +449,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, int compressed_lines; signed short line_packets; int y_ptr; - signed char byte_run; + int byte_run; int pixel_skip; int pixel_countdown; unsigned char *pixels; @@ -499,7 +509,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, pixel_skip = buf[stream_ptr++]; pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */ pixel_countdown -= pixel_skip; - byte_run = buf[stream_ptr++]; + byte_run = (signed char)(buf[stream_ptr++]); if (byte_run < 0) { byte_run = -byte_run; pixel = LE_16(&buf[stream_ptr]); @@ -530,9 +540,9 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, break; case FLI_BLACK: - /* set the whole frame to 0x0000 which is balck in both 15Bpp and 16Bpp modes. */ + /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */ memset(pixels, 0x0000, - s->frame.linesize[0] * s->avctx->height * 2); + s->frame.linesize[0] * s->avctx->height); break; case FLI_BRUN: @@ -545,7 +555,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, pixel_countdown = (s->avctx->width * 2); while (pixel_countdown > 0) { - byte_run = buf[stream_ptr++]; + byte_run = (signed char)(buf[stream_ptr++]); if (byte_run > 0) { palette_idx1 = buf[stream_ptr++]; CHECK_PIXEL_PTR(byte_run); @@ -599,7 +609,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */ while (pixel_countdown > 0) { - byte_run = buf[stream_ptr++]; + byte_run = (signed char)(buf[stream_ptr++]); if (byte_run > 0) { pixel = LE_16(&buf[stream_ptr]); stream_ptr += 2; |