annotate flicvideo.c @ 2497:69adfbbdcdeb libavcodec

- samples from mplayer ftp in the "adv" profile seem to have profile=2, which isn't the advanced one; and indeed, using adv. profile parser fails. Using normal parser works, and that's what is done - attempt at taking care of stride for NORM2 bitplane decoding - duplication of much code from msmpeg4.c; this code isn't yet used, but goes down as far as the block layer (mainly Transform Type stuff, the remains are wild editing without checking). Unusable yet, and lacks the AC decoding (but a step further in bitstream parsing) patch by anonymous
author michael
date Fri, 04 Feb 2005 02:20:38 +0000
parents 18b8b2dcc037
children faa53103dde0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
1 /*
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
2 * FLI/FLC Animation Video Decoder
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
3 * Copyright (C) 2003, 2004 the ffmpeg project
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
4 *
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
9 *
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
13 * Lesser General Public License for more details.
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
14 *
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
18 *
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
19 */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
20
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
21 /**
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
22 * @file flic.c
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
23 * Autodesk Animator FLI/FLC Video Decoder
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
24 * by Mike Melanson (melanson@pcisys.net)
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
25 * for more information on the .fli/.flc file format and all of its many
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
26 * variations, visit:
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
27 * http://www.compuphase.com/flic.htm
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
28 *
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
29 * This decoder outputs PAL8 colorspace data. To use this decoder, be
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
30 * sure that your demuxer sends the FLI file header to the decoder via
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
31 * the extradata chunk in AVCodecContext. The chunk should be 128 bytes
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
32 * large. The only exception is for FLI files from the game "Magic Carpet",
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
33 * in which the header is only 12 bytes.
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
34 */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
35
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
36 #include <stdio.h>
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
37 #include <stdlib.h>
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
38 #include <string.h>
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
39 #include <unistd.h>
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
40
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
41 #include "common.h"
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
42 #include "avcodec.h"
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
43 #include "bswap.h"
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
44
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
45 #define FLI_256_COLOR 4
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
46 #define FLI_DELTA 7
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
47 #define FLI_COLOR 11
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
48 #define FLI_LC 12
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
49 #define FLI_BLACK 13
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
50 #define FLI_BRUN 15
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
51 #define FLI_COPY 16
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
52 #define FLI_MINI 18
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
53
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
54 typedef struct FlicDecodeContext {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
55 AVCodecContext *avctx;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
56 AVFrame frame;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
57
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
58 unsigned int palette[256];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
59 int new_palette;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
60 int fli_type; /* either 0xAF11 or 0xAF12, affects palette resolution */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
61 } FlicDecodeContext;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
62
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
63 static int flic_decode_init(AVCodecContext *avctx)
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
64 {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
65 FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
66 unsigned char *fli_header = (unsigned char *)avctx->extradata;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
67
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
68 s->avctx = avctx;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
69 avctx->pix_fmt = PIX_FMT_PAL8;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
70 avctx->has_b_frames = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
71
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
72 if (s->avctx->extradata_size == 12) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
73 /* special case for magic carpet FLIs */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
74 s->fli_type = 0xAF13;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
75 } else if (s->avctx->extradata_size == 128) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
76 s->fli_type = LE_16(&fli_header[4]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
77 } else {
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
78 av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n");
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
79 return -1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
80 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
81
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
82 s->frame.data[0] = NULL;
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
83 s->new_palette = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
84
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
85 return 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
86 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
87
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
88 static int flic_decode_frame(AVCodecContext *avctx,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
89 void *data, int *data_size,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
90 uint8_t *buf, int buf_size)
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
91 {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
92 FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
93
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
94 int stream_ptr = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
95 int stream_ptr_after_color_chunk;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
96 int pixel_ptr;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
97 int palette_ptr;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
98 unsigned char palette_idx1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
99 unsigned char palette_idx2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
100
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
101 unsigned int frame_size;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
102 int num_chunks;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
103
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
104 unsigned int chunk_size;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
105 int chunk_type;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
106
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
107 int i, j;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
108
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
109 int color_packets;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
110 int color_changes;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
111 int color_shift;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
112 unsigned char r, g, b;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
113
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
114 int lines;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
115 int compressed_lines;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
116 int starting_line;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
117 signed short line_packets;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
118 int y_ptr;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
119 signed char byte_run;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
120 int pixel_skip;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
121 int pixel_countdown;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
122 unsigned char *pixels;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
123
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
124 s->frame.reference = 1;
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
125 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
126 if (avctx->reget_buffer(avctx, &s->frame) < 0) {
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
127 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
128 return -1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
129 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
130
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
131 pixels = s->frame.data[0];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
132
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
133 frame_size = LE_32(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
134 stream_ptr += 6; /* skip the magic number */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
135 num_chunks = LE_16(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
136 stream_ptr += 10; /* skip padding */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
137
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
138 frame_size -= 16;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
139
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
140 /* iterate through the chunks */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
141 while ((frame_size > 0) && (num_chunks > 0)) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
142 chunk_size = LE_32(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
143 stream_ptr += 4;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
144 chunk_type = LE_16(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
145 stream_ptr += 2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
146
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
147 switch (chunk_type) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
148 case FLI_256_COLOR:
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
149 case FLI_COLOR:
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
150 stream_ptr_after_color_chunk = stream_ptr + chunk_size - 6;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
151 s->new_palette = 1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
152
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
153 /* check special case: If this file is from the Magic Carpet
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
154 * game and uses 6-bit colors even though it reports 256-color
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
155 * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
156 * initialization) */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
157 if ((chunk_type == FLI_256_COLOR) && (s->fli_type != 0xAF13))
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
158 color_shift = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
159 else
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
160 color_shift = 2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
161 /* set up the palette */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
162 color_packets = LE_16(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
163 stream_ptr += 2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
164 palette_ptr = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
165 for (i = 0; i < color_packets; i++) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
166 /* first byte is how many colors to skip */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
167 palette_ptr += buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
168
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
169 /* next byte indicates how many entries to change */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
170 color_changes = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
171
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
172 /* if there are 0 color changes, there are actually 256 */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
173 if (color_changes == 0)
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
174 color_changes = 256;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
175
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
176 for (j = 0; j < color_changes; j++) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
177
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
178 /* wrap around, for good measure */
2422
18b8b2dcc037 various security fixes and precautionary checks
michael
parents: 1881
diff changeset
179 if ((unsigned)palette_ptr >= 256)
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
180 palette_ptr = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
181
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
182 r = buf[stream_ptr++] << color_shift;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
183 g = buf[stream_ptr++] << color_shift;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
184 b = buf[stream_ptr++] << color_shift;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
185 s->palette[palette_ptr++] = (r << 16) | (g << 8) | b;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
186 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
187 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
188
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
189 /* color chunks sometimes have weird 16-bit alignment issues;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
190 * therefore, take the hardline approach and set the stream_ptr
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
191 * to the value calculated w.r.t. the size specified by the color
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
192 * chunk header */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
193 stream_ptr = stream_ptr_after_color_chunk;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
194
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
195 break;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
196
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
197 case FLI_DELTA:
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
198 y_ptr = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
199 compressed_lines = LE_16(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
200 stream_ptr += 2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
201 while (compressed_lines > 0) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
202 line_packets = LE_16(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
203 stream_ptr += 2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
204 if (line_packets < 0) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
205 line_packets = -line_packets;
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
206 y_ptr += line_packets * s->frame.linesize[0];
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
207 } else {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
208 compressed_lines--;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
209 pixel_ptr = y_ptr;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
210 pixel_countdown = s->avctx->width;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
211 for (i = 0; i < line_packets; i++) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
212 /* account for the skip bytes */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
213 pixel_skip = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
214 pixel_ptr += pixel_skip;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
215 pixel_countdown -= pixel_skip;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
216 byte_run = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
217 if (byte_run < 0) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
218 byte_run = -byte_run;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
219 palette_idx1 = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
220 palette_idx2 = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
221 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
222 pixels[pixel_ptr++] = palette_idx1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
223 pixels[pixel_ptr++] = palette_idx2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
224 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
225 } else {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
226 for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
227 palette_idx1 = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
228 pixels[pixel_ptr++] = palette_idx1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
229 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
230 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
231 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
232
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
233 y_ptr += s->frame.linesize[0];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
234 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
235 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
236 break;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
237
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
238 case FLI_LC:
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
239 /* line compressed */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
240 starting_line = LE_16(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
241 stream_ptr += 2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
242 y_ptr = 0;
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
243 y_ptr += starting_line * s->frame.linesize[0];
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
244
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
245 compressed_lines = LE_16(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
246 stream_ptr += 2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
247 while (compressed_lines > 0) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
248 pixel_ptr = y_ptr;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
249 pixel_countdown = s->avctx->width;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
250 line_packets = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
251 if (line_packets > 0) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
252 for (i = 0; i < line_packets; i++) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
253 /* account for the skip bytes */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
254 pixel_skip = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
255 pixel_ptr += pixel_skip;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
256 pixel_countdown -= pixel_skip;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
257 byte_run = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
258 if (byte_run > 0) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
259 for (j = 0; j < byte_run; j++, pixel_countdown--) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
260 palette_idx1 = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
261 pixels[pixel_ptr++] = palette_idx1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
262 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
263 } else {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
264 byte_run = -byte_run;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
265 palette_idx1 = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
266 for (j = 0; j < byte_run; j++, pixel_countdown--) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
267 pixels[pixel_ptr++] = palette_idx1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
268 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
269 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
270 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
271 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
272
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
273 y_ptr += s->frame.linesize[0];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
274 compressed_lines--;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
275 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
276 break;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
277
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
278 case FLI_BLACK:
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
279 /* set the whole frame to color 0 (which is usually black) */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
280 memset(pixels, 0,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
281 s->frame.linesize[0] * s->avctx->height);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
282 break;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
283
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
284 case FLI_BRUN:
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
285 /* Byte run compression: This chunk type only occurs in the first
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
286 * FLI frame and it will update the entire frame. */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
287 y_ptr = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
288 for (lines = 0; lines < s->avctx->height; lines++) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
289 pixel_ptr = y_ptr;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
290 /* disregard the line packets; instead, iterate through all
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
291 * pixels on a row */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
292 stream_ptr++;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
293 pixel_countdown = s->avctx->width;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
294 while (pixel_countdown > 0) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
295 byte_run = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
296 if (byte_run > 0) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
297 palette_idx1 = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
298 for (j = 0; j < byte_run; j++) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
299 pixels[pixel_ptr++] = palette_idx1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
300 pixel_countdown--;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
301 if (pixel_countdown < 0)
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
302 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
303 pixel_countdown);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
304 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
305 } else { /* copy bytes if byte_run < 0 */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
306 byte_run = -byte_run;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
307 for (j = 0; j < byte_run; j++) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
308 palette_idx1 = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
309 pixels[pixel_ptr++] = palette_idx1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
310 pixel_countdown--;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
311 if (pixel_countdown < 0)
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
312 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
313 pixel_countdown);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
314 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
315 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
316 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
317
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
318 y_ptr += s->frame.linesize[0];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
319 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
320 break;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
321
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
322 case FLI_COPY:
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
323 /* copy the chunk (uncompressed frame) */
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
324 if (chunk_size - 6 > s->avctx->width * s->avctx->height) {
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
325 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
326 "bigger than image, skipping chunk\n", chunk_size - 6);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
327 stream_ptr += chunk_size - 6;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
328 } else {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
329 for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
330 y_ptr += s->frame.linesize[0]) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
331 memcpy(&pixels[y_ptr], &buf[stream_ptr],
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
332 s->avctx->width);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
333 stream_ptr += s->avctx->width;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
334 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
335 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
336 break;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
337
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
338 case FLI_MINI:
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
339 /* some sort of a thumbnail? disregard this chunk... */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
340 stream_ptr += chunk_size - 6;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
341 break;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
342
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
343 default:
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
344 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
345 break;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
346 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
347
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
348 frame_size -= chunk_size;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
349 num_chunks--;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
350 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
351
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
352 /* by the end of the chunk, the stream ptr should equal the frame
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
353 * size (minus 1, possibly); if it doesn't, issue a warning */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
354 if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
355 av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
356 "and final chunk ptr = %d\n", buf_size, stream_ptr);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
357
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
358 /* make the palette available on the way out */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
359 // if (s->new_palette) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
360 if (1) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
361 memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
362 s->frame.palette_has_changed = 1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
363 s->new_palette = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
364 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
365
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
366 *data_size=sizeof(AVFrame);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
367 *(AVFrame*)data = s->frame;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
368
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
369 return buf_size;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
370 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
371
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
372 static int flic_decode_end(AVCodecContext *avctx)
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
373 {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
374 FlicDecodeContext *s = avctx->priv_data;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
375
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
376 if (s->frame.data[0])
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
377 avctx->release_buffer(avctx, &s->frame);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
378
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
379 return 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
380 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
381
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
382 AVCodec flic_decoder = {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
383 "flic",
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
384 CODEC_TYPE_VIDEO,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
385 CODEC_ID_FLIC,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
386 sizeof(FlicDecodeContext),
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
387 flic_decode_init,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
388 NULL,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
389 flic_decode_end,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
390 flic_decode_frame,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
391 CODEC_CAP_DR1,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
392 NULL
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
393 };