alacenc: add a fixed LPC coefficient mode as compression level 1. old
[FFMpeg-mirror/lagarith.git] / libavformat / wc3movie.c
blob5369057dd46bbe272fce52c60a1a1b16727263ed
1 /*
2 * Wing Commander III Movie (.mve) File Demuxer
3 * Copyright (c) 2003 The ffmpeg Project
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 /**
23 * @file libavformat/wc3movie.c
24 * Wing Commander III Movie file demuxer
25 * by Mike Melanson (melanson@pcisys.net)
26 * for more information on the WC3 .mve file format, visit:
27 * http://www.pcisys.net/~melanson/codecs/
30 #include "libavutil/intreadwrite.h"
31 #include "avformat.h"
33 #define FORM_TAG MKTAG('F', 'O', 'R', 'M')
34 #define MOVE_TAG MKTAG('M', 'O', 'V', 'E')
35 #define PC__TAG MKTAG('_', 'P', 'C', '_')
36 #define SOND_TAG MKTAG('S', 'O', 'N', 'D')
37 #define BNAM_TAG MKTAG('B', 'N', 'A', 'M')
38 #define SIZE_TAG MKTAG('S', 'I', 'Z', 'E')
39 #define PALT_TAG MKTAG('P', 'A', 'L', 'T')
40 #define INDX_TAG MKTAG('I', 'N', 'D', 'X')
41 #define BRCH_TAG MKTAG('B', 'R', 'C', 'H')
42 #define SHOT_TAG MKTAG('S', 'H', 'O', 'T')
43 #define VGA__TAG MKTAG('V', 'G', 'A', ' ')
44 #define TEXT_TAG MKTAG('T', 'E', 'X', 'T')
45 #define AUDI_TAG MKTAG('A', 'U', 'D', 'I')
47 /* video resolution unless otherwise specified */
48 #define WC3_DEFAULT_WIDTH 320
49 #define WC3_DEFAULT_HEIGHT 165
51 /* always use the same PCM audio parameters */
52 #define WC3_SAMPLE_RATE 22050
53 #define WC3_AUDIO_CHANNELS 1
54 #define WC3_AUDIO_BITS 16
56 /* nice, constant framerate */
57 #define WC3_FRAME_FPS 15
59 #define PALETTE_SIZE (256 * 3)
60 #define PALETTE_COUNT 256
62 typedef struct Wc3DemuxContext {
63 int width;
64 int height;
65 unsigned char *palettes;
66 int palette_count;
67 int64_t pts;
68 int video_stream_index;
69 int audio_stream_index;
71 AVPaletteControl palette_control;
73 } Wc3DemuxContext;
75 /**
76 * palette lookup table that does gamma correction
78 * can be calculated by this formula:
79 * for i between 0 and 251 inclusive:
80 * wc3_pal_lookup[i] = round(pow(i / 256.0, 0.8) * 256);
81 * values 252, 253, 254 and 255 are all 0xFD
82 * calculating this at runtime should not cause any
83 * rounding issues, the maximum difference between
84 * the table values and the calculated doubles is
85 * about 0.497527
87 static const unsigned char wc3_pal_lookup[] = {
88 0x00, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0E,
89 0x10, 0x12, 0x13, 0x15, 0x16, 0x18, 0x19, 0x1A,
90 0x1C, 0x1D, 0x1F, 0x20, 0x21, 0x23, 0x24, 0x25,
91 0x27, 0x28, 0x29, 0x2A, 0x2C, 0x2D, 0x2E, 0x2F,
92 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38, 0x39,
93 0x3A, 0x3B, 0x3C, 0x3D, 0x3F, 0x40, 0x41, 0x42,
94 0x43, 0x44, 0x45, 0x46, 0x48, 0x49, 0x4A, 0x4B,
95 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
96 0x54, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C,
97 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64,
98 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C,
99 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74,
100 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
101 0x7D, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83,
102 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B,
103 0x8C, 0x8D, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92,
104 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x99,
105 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1,
106 0xA2, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
107 0xA9, 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
108 0xB0, 0xB1, 0xB2, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
109 0xB7, 0xB8, 0xB9, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD,
110 0xBE, 0xBF, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4,
111 0xC5, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB,
112 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD0, 0xD1,
113 0xD2, 0xD3, 0xD4, 0xD5, 0xD5, 0xD6, 0xD7, 0xD8,
114 0xD9, 0xDA, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
115 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5,
116 0xE6, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEB, 0xEC,
117 0xED, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF1, 0xF2,
118 0xF3, 0xF4, 0xF5, 0xF6, 0xF6, 0xF7, 0xF8, 0xF9,
119 0xFA, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD
123 static int wc3_probe(AVProbeData *p)
125 if (p->buf_size < 12)
126 return 0;
128 if ((AV_RL32(&p->buf[0]) != FORM_TAG) ||
129 (AV_RL32(&p->buf[8]) != MOVE_TAG))
130 return 0;
132 return AVPROBE_SCORE_MAX;
135 static int wc3_read_header(AVFormatContext *s,
136 AVFormatParameters *ap)
138 Wc3DemuxContext *wc3 = s->priv_data;
139 ByteIOContext *pb = s->pb;
140 unsigned int fourcc_tag;
141 unsigned int size;
142 AVStream *st;
143 char buffer[513];
144 int ret = 0;
145 int current_palette = 0;
146 int bytes_to_read;
147 int i;
148 unsigned char rotate;
150 /* default context members */
151 wc3->width = WC3_DEFAULT_WIDTH;
152 wc3->height = WC3_DEFAULT_HEIGHT;
153 wc3->palettes = NULL;
154 wc3->palette_count = 0;
155 wc3->pts = 0;
156 wc3->video_stream_index = wc3->audio_stream_index = 0;
158 /* skip the first 3 32-bit numbers */
159 url_fseek(pb, 12, SEEK_CUR);
161 /* traverse through the chunks and load the header information before
162 * the first BRCH tag */
163 fourcc_tag = get_le32(pb);
164 size = (get_be32(pb) + 1) & (~1);
166 do {
167 switch (fourcc_tag) {
169 case SOND_TAG:
170 case INDX_TAG:
171 /* SOND unknown, INDX unnecessary; ignore both */
172 url_fseek(pb, size, SEEK_CUR);
173 break;
175 case PC__TAG:
176 /* need the number of palettes */
177 url_fseek(pb, 8, SEEK_CUR);
178 wc3->palette_count = get_le32(pb);
179 if((unsigned)wc3->palette_count >= UINT_MAX / PALETTE_SIZE){
180 wc3->palette_count= 0;
181 return -1;
183 wc3->palettes = av_malloc(wc3->palette_count * PALETTE_SIZE);
184 break;
186 case BNAM_TAG:
187 /* load up the name */
188 if ((unsigned)size < 512)
189 bytes_to_read = size;
190 else
191 bytes_to_read = 512;
192 if ((ret = get_buffer(pb, buffer, bytes_to_read)) != bytes_to_read)
193 return AVERROR(EIO);
194 buffer[bytes_to_read] = 0;
195 av_metadata_set(&s->metadata, "title", buffer);
196 break;
198 case SIZE_TAG:
199 /* video resolution override */
200 wc3->width = get_le32(pb);
201 wc3->height = get_le32(pb);
202 break;
204 case PALT_TAG:
205 /* one of several palettes */
206 if ((unsigned)current_palette >= wc3->palette_count)
207 return AVERROR_INVALIDDATA;
208 if ((ret = get_buffer(pb,
209 &wc3->palettes[current_palette * PALETTE_SIZE],
210 PALETTE_SIZE)) != PALETTE_SIZE)
211 return AVERROR(EIO);
213 /* transform the current palette in place */
214 for (i = current_palette * PALETTE_SIZE;
215 i < (current_palette + 1) * PALETTE_SIZE; i++) {
216 /* rotate each palette component left by 2 and use the result
217 * as an index into the color component table */
218 rotate = ((wc3->palettes[i] << 2) & 0xFF) |
219 ((wc3->palettes[i] >> 6) & 0xFF);
220 wc3->palettes[i] = wc3_pal_lookup[rotate];
222 current_palette++;
223 break;
225 default:
226 av_log(s, AV_LOG_ERROR, " unrecognized WC3 chunk: %c%c%c%c (0x%02X%02X%02X%02X)\n",
227 (uint8_t)fourcc_tag, (uint8_t)(fourcc_tag >> 8), (uint8_t)(fourcc_tag >> 16), (uint8_t)(fourcc_tag >> 24),
228 (uint8_t)fourcc_tag, (uint8_t)(fourcc_tag >> 8), (uint8_t)(fourcc_tag >> 16), (uint8_t)(fourcc_tag >> 24));
229 return AVERROR_INVALIDDATA;
230 break;
233 fourcc_tag = get_le32(pb);
234 /* chunk sizes are 16-bit aligned */
235 size = (get_be32(pb) + 1) & (~1);
236 if (url_feof(pb))
237 return AVERROR(EIO);
239 } while (fourcc_tag != BRCH_TAG);
241 /* initialize the decoder streams */
242 st = av_new_stream(s, 0);
243 if (!st)
244 return AVERROR(ENOMEM);
245 av_set_pts_info(st, 33, 1, WC3_FRAME_FPS);
246 wc3->video_stream_index = st->index;
247 st->codec->codec_type = CODEC_TYPE_VIDEO;
248 st->codec->codec_id = CODEC_ID_XAN_WC3;
249 st->codec->codec_tag = 0; /* no fourcc */
250 st->codec->width = wc3->width;
251 st->codec->height = wc3->height;
253 /* palette considerations */
254 st->codec->palctrl = &wc3->palette_control;
256 st = av_new_stream(s, 0);
257 if (!st)
258 return AVERROR(ENOMEM);
259 av_set_pts_info(st, 33, 1, WC3_FRAME_FPS);
260 wc3->audio_stream_index = st->index;
261 st->codec->codec_type = CODEC_TYPE_AUDIO;
262 st->codec->codec_id = CODEC_ID_PCM_S16LE;
263 st->codec->codec_tag = 1;
264 st->codec->channels = WC3_AUDIO_CHANNELS;
265 st->codec->bits_per_coded_sample = WC3_AUDIO_BITS;
266 st->codec->sample_rate = WC3_SAMPLE_RATE;
267 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
268 st->codec->bits_per_coded_sample;
269 st->codec->block_align = WC3_AUDIO_BITS * WC3_AUDIO_CHANNELS;
271 return 0;
274 static int wc3_read_packet(AVFormatContext *s,
275 AVPacket *pkt)
277 Wc3DemuxContext *wc3 = s->priv_data;
278 ByteIOContext *pb = s->pb;
279 unsigned int fourcc_tag;
280 unsigned int size;
281 int packet_read = 0;
282 int ret = 0;
283 unsigned char text[1024];
284 unsigned int palette_number;
285 int i;
286 unsigned char r, g, b;
287 int base_palette_index;
289 while (!packet_read) {
291 fourcc_tag = get_le32(pb);
292 /* chunk sizes are 16-bit aligned */
293 size = (get_be32(pb) + 1) & (~1);
294 if (url_feof(pb))
295 return AVERROR(EIO);
297 switch (fourcc_tag) {
299 case BRCH_TAG:
300 /* no-op */
301 break;
303 case SHOT_TAG:
304 /* load up new palette */
305 palette_number = get_le32(pb);
306 if (palette_number >= wc3->palette_count)
307 return AVERROR_INVALIDDATA;
308 base_palette_index = palette_number * PALETTE_COUNT * 3;
309 for (i = 0; i < PALETTE_COUNT; i++) {
310 r = wc3->palettes[base_palette_index + i * 3 + 0];
311 g = wc3->palettes[base_palette_index + i * 3 + 1];
312 b = wc3->palettes[base_palette_index + i * 3 + 2];
313 wc3->palette_control.palette[i] = (r << 16) | (g << 8) | (b);
315 wc3->palette_control.palette_changed = 1;
316 break;
318 case VGA__TAG:
319 /* send out video chunk */
320 ret= av_get_packet(pb, pkt, size);
321 pkt->stream_index = wc3->video_stream_index;
322 pkt->pts = wc3->pts;
323 packet_read = 1;
324 break;
326 case TEXT_TAG:
327 /* subtitle chunk */
328 #if 0
329 url_fseek(pb, size, SEEK_CUR);
330 #else
331 if ((unsigned)size > sizeof(text) || (ret = get_buffer(pb, text, size)) != size)
332 ret = AVERROR(EIO);
333 else {
334 int i = 0;
335 av_log (s, AV_LOG_DEBUG, "Subtitle time!\n");
336 av_log (s, AV_LOG_DEBUG, " inglish: %s\n", &text[i + 1]);
337 i += text[i] + 1;
338 av_log (s, AV_LOG_DEBUG, " doytsch: %s\n", &text[i + 1]);
339 i += text[i] + 1;
340 av_log (s, AV_LOG_DEBUG, " fronsay: %s\n", &text[i + 1]);
342 #endif
343 break;
345 case AUDI_TAG:
346 /* send out audio chunk */
347 ret= av_get_packet(pb, pkt, size);
348 pkt->stream_index = wc3->audio_stream_index;
349 pkt->pts = wc3->pts;
351 /* time to advance pts */
352 wc3->pts++;
354 packet_read = 1;
355 break;
357 default:
358 av_log (s, AV_LOG_ERROR, " unrecognized WC3 chunk: %c%c%c%c (0x%02X%02X%02X%02X)\n",
359 (uint8_t)fourcc_tag, (uint8_t)(fourcc_tag >> 8), (uint8_t)(fourcc_tag >> 16), (uint8_t)(fourcc_tag >> 24),
360 (uint8_t)fourcc_tag, (uint8_t)(fourcc_tag >> 8), (uint8_t)(fourcc_tag >> 16), (uint8_t)(fourcc_tag >> 24));
361 ret = AVERROR_INVALIDDATA;
362 packet_read = 1;
363 break;
367 return ret;
370 static int wc3_read_close(AVFormatContext *s)
372 Wc3DemuxContext *wc3 = s->priv_data;
374 av_free(wc3->palettes);
376 return 0;
379 AVInputFormat wc3_demuxer = {
380 "wc3movie",
381 NULL_IF_CONFIG_SMALL("Wing Commander III movie format"),
382 sizeof(Wc3DemuxContext),
383 wc3_probe,
384 wc3_read_header,
385 wc3_read_packet,
386 wc3_read_close,