annotate flicvideo.c @ 2892:41315d0120b3 libavcodec

replace a few mov + psrlq with pshufw, there are more cases which could benefit from this but they would require us to duplicate some functions ... the trick is from various places (my own code in libpostproc, a patch on the x264 list, ...)
author michael
date Wed, 21 Sep 2005 21:17:09 +0000
parents faa53103dde0
children f7114e03d8dd
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
2825
faa53103dde0 tinfoil patch: make sure that pixel pointer does not go out of bounds
melanson
parents: 2422
diff changeset
54 #define CHECK_PIXEL_PTR(n) \
faa53103dde0 tinfoil patch: make sure that pixel pointer does not go out of bounds
melanson
parents: 2422
diff changeset
55 if (pixel_ptr + n > pixel_limit) { \
faa53103dde0 tinfoil patch: make sure that pixel pointer does not go out of bounds
melanson
parents: 2422
diff changeset
56 av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)\n", \
faa53103dde0 tinfoil patch: make sure that pixel pointer does not go out of bounds
melanson
parents: 2422
diff changeset
57 pixel_ptr + n, pixel_limit); \
faa53103dde0 tinfoil patch: make sure that pixel pointer does not go out of bounds
melanson
parents: 2422
diff changeset
58 return -1; \
faa53103dde0 tinfoil patch: make sure that pixel pointer does not go out of bounds
melanson
parents: 2422
diff changeset
59 } \
faa53103dde0 tinfoil patch: make sure that pixel pointer does not go out of bounds
melanson
parents: 2422
diff changeset
60
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
61 typedef struct FlicDecodeContext {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
62 AVCodecContext *avctx;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
63 AVFrame frame;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
64
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
65 unsigned int palette[256];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
66 int new_palette;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
67 int fli_type; /* either 0xAF11 or 0xAF12, affects palette resolution */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
68 } FlicDecodeContext;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
69
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
70 static int flic_decode_init(AVCodecContext *avctx)
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
71 {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
72 FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
73 unsigned char *fli_header = (unsigned char *)avctx->extradata;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
74
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
75 s->avctx = avctx;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
76 avctx->pix_fmt = PIX_FMT_PAL8;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
77 avctx->has_b_frames = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
78
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
79 if (s->avctx->extradata_size == 12) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
80 /* special case for magic carpet FLIs */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
81 s->fli_type = 0xAF13;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
82 } else if (s->avctx->extradata_size == 128) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
83 s->fli_type = LE_16(&fli_header[4]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
84 } else {
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
85 av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n");
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
86 return -1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
87 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
88
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
89 s->frame.data[0] = NULL;
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
90 s->new_palette = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
91
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
92 return 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
93 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
94
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
95 static int flic_decode_frame(AVCodecContext *avctx,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
96 void *data, int *data_size,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
97 uint8_t *buf, int buf_size)
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
98 {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
99 FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
100
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
101 int stream_ptr = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
102 int stream_ptr_after_color_chunk;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
103 int pixel_ptr;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
104 int palette_ptr;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
105 unsigned char palette_idx1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
106 unsigned char palette_idx2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
107
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
108 unsigned int frame_size;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
109 int num_chunks;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
110
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
111 unsigned int chunk_size;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
112 int chunk_type;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
113
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
114 int i, j;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
115
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
116 int color_packets;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
117 int color_changes;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
118 int color_shift;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
119 unsigned char r, g, b;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
120
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
121 int lines;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
122 int compressed_lines;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
123 int starting_line;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
124 signed short line_packets;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
125 int y_ptr;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
126 signed char byte_run;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
127 int pixel_skip;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
128 int pixel_countdown;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
129 unsigned char *pixels;
2825
faa53103dde0 tinfoil patch: make sure that pixel pointer does not go out of bounds
melanson
parents: 2422
diff changeset
130 int pixel_limit;
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
131
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
132 s->frame.reference = 1;
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
133 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
134 if (avctx->reget_buffer(avctx, &s->frame) < 0) {
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
135 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
136 return -1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
137 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
138
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
139 pixels = s->frame.data[0];
2825
faa53103dde0 tinfoil patch: make sure that pixel pointer does not go out of bounds
melanson
parents: 2422
diff changeset
140 pixel_limit = s->avctx->height * s->frame.linesize[0];
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
141
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
142 frame_size = LE_32(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
143 stream_ptr += 6; /* skip the magic number */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
144 num_chunks = LE_16(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
145 stream_ptr += 10; /* skip padding */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
146
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
147 frame_size -= 16;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
148
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
149 /* iterate through the chunks */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
150 while ((frame_size > 0) && (num_chunks > 0)) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
151 chunk_size = LE_32(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
152 stream_ptr += 4;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
153 chunk_type = LE_16(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
154 stream_ptr += 2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
155
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
156 switch (chunk_type) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
157 case FLI_256_COLOR:
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
158 case FLI_COLOR:
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
159 stream_ptr_after_color_chunk = stream_ptr + chunk_size - 6;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
160 s->new_palette = 1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
161
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
162 /* check special case: If this file is from the Magic Carpet
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
163 * game and uses 6-bit colors even though it reports 256-color
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
164 * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
165 * initialization) */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
166 if ((chunk_type == FLI_256_COLOR) && (s->fli_type != 0xAF13))
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
167 color_shift = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
168 else
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
169 color_shift = 2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
170 /* set up the palette */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
171 color_packets = LE_16(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
172 stream_ptr += 2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
173 palette_ptr = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
174 for (i = 0; i < color_packets; i++) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
175 /* first byte is how many colors to skip */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
176 palette_ptr += buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
177
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
178 /* next byte indicates how many entries to change */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
179 color_changes = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
180
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
181 /* if there are 0 color changes, there are actually 256 */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
182 if (color_changes == 0)
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
183 color_changes = 256;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
184
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
185 for (j = 0; j < color_changes; j++) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
186
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
187 /* wrap around, for good measure */
2422
18b8b2dcc037 various security fixes and precautionary checks
michael
parents: 1881
diff changeset
188 if ((unsigned)palette_ptr >= 256)
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
189 palette_ptr = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
190
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
191 r = buf[stream_ptr++] << color_shift;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
192 g = buf[stream_ptr++] << color_shift;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
193 b = buf[stream_ptr++] << color_shift;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
194 s->palette[palette_ptr++] = (r << 16) | (g << 8) | b;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
195 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
196 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
197
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
198 /* color chunks sometimes have weird 16-bit alignment issues;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
199 * therefore, take the hardline approach and set the stream_ptr
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
200 * to the value calculated w.r.t. the size specified by the color
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
201 * chunk header */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
202 stream_ptr = stream_ptr_after_color_chunk;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
203
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
204 break;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
205
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
206 case FLI_DELTA:
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
207 y_ptr = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
208 compressed_lines = LE_16(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
209 stream_ptr += 2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
210 while (compressed_lines > 0) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
211 line_packets = LE_16(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
212 stream_ptr += 2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
213 if (line_packets < 0) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
214 line_packets = -line_packets;
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
215 y_ptr += line_packets * s->frame.linesize[0];
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
216 } else {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
217 compressed_lines--;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
218 pixel_ptr = y_ptr;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
219 pixel_countdown = s->avctx->width;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
220 for (i = 0; i < line_packets; i++) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
221 /* account for the skip bytes */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
222 pixel_skip = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
223 pixel_ptr += pixel_skip;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
224 pixel_countdown -= pixel_skip;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
225 byte_run = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
226 if (byte_run < 0) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
227 byte_run = -byte_run;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
228 palette_idx1 = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
229 palette_idx2 = buf[stream_ptr++];
2825
faa53103dde0 tinfoil patch: make sure that pixel pointer does not go out of bounds
melanson
parents: 2422
diff changeset
230 CHECK_PIXEL_PTR(byte_run);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
231 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
232 pixels[pixel_ptr++] = palette_idx1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
233 pixels[pixel_ptr++] = palette_idx2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
234 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
235 } else {
2825
faa53103dde0 tinfoil patch: make sure that pixel pointer does not go out of bounds
melanson
parents: 2422
diff changeset
236 CHECK_PIXEL_PTR(byte_run * 2);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
237 for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
238 palette_idx1 = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
239 pixels[pixel_ptr++] = palette_idx1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
240 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
241 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
242 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
243
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
244 y_ptr += s->frame.linesize[0];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
245 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
246 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
247 break;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
248
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
249 case FLI_LC:
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
250 /* line compressed */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
251 starting_line = LE_16(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
252 stream_ptr += 2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
253 y_ptr = 0;
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
254 y_ptr += starting_line * s->frame.linesize[0];
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
255
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
256 compressed_lines = LE_16(&buf[stream_ptr]);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
257 stream_ptr += 2;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
258 while (compressed_lines > 0) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
259 pixel_ptr = y_ptr;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
260 pixel_countdown = s->avctx->width;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
261 line_packets = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
262 if (line_packets > 0) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
263 for (i = 0; i < line_packets; i++) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
264 /* account for the skip bytes */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
265 pixel_skip = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
266 pixel_ptr += pixel_skip;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
267 pixel_countdown -= pixel_skip;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
268 byte_run = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
269 if (byte_run > 0) {
2825
faa53103dde0 tinfoil patch: make sure that pixel pointer does not go out of bounds
melanson
parents: 2422
diff changeset
270 CHECK_PIXEL_PTR(byte_run);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
271 for (j = 0; j < byte_run; j++, pixel_countdown--) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
272 palette_idx1 = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
273 pixels[pixel_ptr++] = palette_idx1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
274 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
275 } else {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
276 byte_run = -byte_run;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
277 palette_idx1 = buf[stream_ptr++];
2825
faa53103dde0 tinfoil patch: make sure that pixel pointer does not go out of bounds
melanson
parents: 2422
diff changeset
278 CHECK_PIXEL_PTR(byte_run);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
279 for (j = 0; j < byte_run; j++, pixel_countdown--) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
280 pixels[pixel_ptr++] = palette_idx1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
281 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
282 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
283 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
284 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
285
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
286 y_ptr += s->frame.linesize[0];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
287 compressed_lines--;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
288 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
289 break;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
290
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
291 case FLI_BLACK:
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
292 /* set the whole frame to color 0 (which is usually black) */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
293 memset(pixels, 0,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
294 s->frame.linesize[0] * s->avctx->height);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
295 break;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
296
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
297 case FLI_BRUN:
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
298 /* Byte run compression: This chunk type only occurs in the first
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
299 * FLI frame and it will update the entire frame. */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
300 y_ptr = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
301 for (lines = 0; lines < s->avctx->height; lines++) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
302 pixel_ptr = y_ptr;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
303 /* disregard the line packets; instead, iterate through all
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
304 * pixels on a row */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
305 stream_ptr++;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
306 pixel_countdown = s->avctx->width;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
307 while (pixel_countdown > 0) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
308 byte_run = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
309 if (byte_run > 0) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
310 palette_idx1 = buf[stream_ptr++];
2825
faa53103dde0 tinfoil patch: make sure that pixel pointer does not go out of bounds
melanson
parents: 2422
diff changeset
311 CHECK_PIXEL_PTR(byte_run);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
312 for (j = 0; j < byte_run; j++) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
313 pixels[pixel_ptr++] = palette_idx1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
314 pixel_countdown--;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
315 if (pixel_countdown < 0)
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
316 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
317 pixel_countdown);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
318 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
319 } else { /* copy bytes if byte_run < 0 */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
320 byte_run = -byte_run;
2825
faa53103dde0 tinfoil patch: make sure that pixel pointer does not go out of bounds
melanson
parents: 2422
diff changeset
321 CHECK_PIXEL_PTR(byte_run);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
322 for (j = 0; j < byte_run; j++) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
323 palette_idx1 = buf[stream_ptr++];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
324 pixels[pixel_ptr++] = palette_idx1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
325 pixel_countdown--;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
326 if (pixel_countdown < 0)
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
327 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
328 pixel_countdown);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
329 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
330 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
331 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
332
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
333 y_ptr += s->frame.linesize[0];
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
334 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
335 break;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
336
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
337 case FLI_COPY:
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
338 /* copy the chunk (uncompressed frame) */
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
339 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
340 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
341 "bigger than image, skipping chunk\n", chunk_size - 6);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
342 stream_ptr += chunk_size - 6;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
343 } else {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
344 for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
345 y_ptr += s->frame.linesize[0]) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
346 memcpy(&pixels[y_ptr], &buf[stream_ptr],
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
347 s->avctx->width);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
348 stream_ptr += s->avctx->width;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
349 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
350 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
351 break;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
352
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
353 case FLI_MINI:
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
354 /* some sort of a thumbnail? disregard this chunk... */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
355 stream_ptr += chunk_size - 6;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
356 break;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
357
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
358 default:
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
359 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
360 break;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
361 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
362
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
363 frame_size -= chunk_size;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
364 num_chunks--;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
365 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
366
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
367 /* by the end of the chunk, the stream ptr should equal the frame
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
368 * size (minus 1, possibly); if it doesn't, issue a warning */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
369 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
370 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
371 "and final chunk ptr = %d\n", buf_size, stream_ptr);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
372
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
373 /* make the palette available on the way out */
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
374 // if (s->new_palette) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
375 if (1) {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
376 memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
377 s->frame.palette_has_changed = 1;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
378 s->new_palette = 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
379 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
380
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
381 *data_size=sizeof(AVFrame);
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
382 *(AVFrame*)data = s->frame;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
383
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
384 return buf_size;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
385 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
386
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
387 static int flic_decode_end(AVCodecContext *avctx)
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
388 {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
389 FlicDecodeContext *s = avctx->priv_data;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
390
1759
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
391 if (s->frame.data[0])
e73a3b86565f Use reget buffer instead of copying from prev frame
rtognimp
parents: 1624
diff changeset
392 avctx->release_buffer(avctx, &s->frame);
1624
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
393
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
394 return 0;
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
395 }
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
396
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
397 AVCodec flic_decoder = {
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
398 "flic",
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
399 CODEC_TYPE_VIDEO,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
400 CODEC_ID_FLIC,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
401 sizeof(FlicDecodeContext),
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
402 flic_decode_init,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
403 NULL,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
404 flic_decode_end,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
405 flic_decode_frame,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
406 CODEC_CAP_DR1,
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
407 NULL
46dee16488ae yep, FLI support
melanson
parents:
diff changeset
408 };