Mercurial > libavcodec.hg
annotate msrle.c @ 5473:a0d7ec11b87e libavcodec
move dnxhd data tables to separate file
author | bcoudurier |
---|---|
date | Sat, 04 Aug 2007 13:41:33 +0000 |
parents | f99e40a7155b |
children | dfdff1ca78a7 |
rev | line source |
---|---|
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
1 /* |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
2 * Micrsoft RLE Video Decoder |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
3 * Copyright (C) 2003 the ffmpeg project |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
4 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
8 * modify it under the terms of the GNU Lesser General Public |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
9 * License as published by the Free Software Foundation; either |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
15 * Lesser General Public License for more details. |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
16 * |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
17 * You should have received a copy of the GNU Lesser General Public |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2453
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
20 */ |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
21 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
22 /** |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
23 * @file msrle.c |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
24 * MS RLE Video Decoder by Mike Melanson (melanson@pcisys.net) |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
25 * For more information about the MS RLE format, visit: |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
26 * http://www.pcisys.net/~melanson/codecs/ |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
27 * |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
28 * The MS RLE decoder outputs PAL8 colorspace data. |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
29 * |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
30 * Note that this decoder expects the palette colors from the end of the |
1595 | 31 * BITMAPINFO header passed through palctrl. |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
32 */ |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
33 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
34 #include <stdio.h> |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
35 #include <stdlib.h> |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
36 #include <string.h> |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
37 #include <unistd.h> |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
38 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
39 #include "avcodec.h" |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
40 #include "dsputil.h" |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
41 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
42 typedef struct MsrleContext { |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
43 AVCodecContext *avctx; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
44 AVFrame frame; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
45 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
46 unsigned char *buf; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
47 int size; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
48 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
49 } MsrleContext; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
50 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
51 #define FETCH_NEXT_STREAM_BYTE() \ |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
52 if (stream_ptr >= s->size) \ |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
53 { \ |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1595
diff
changeset
|
54 av_log(s->avctx, AV_LOG_ERROR, " MS RLE: stream ptr just went out of bounds (1)\n"); \ |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
55 return; \ |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
56 } \ |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
57 stream_byte = s->buf[stream_ptr++]; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
58 |
1609 | 59 static void msrle_decode_pal4(MsrleContext *s) |
60 { | |
61 int stream_ptr = 0; | |
62 unsigned char rle_code; | |
63 unsigned char extra_byte, odd_pixel; | |
64 unsigned char stream_byte; | |
65 int pixel_ptr = 0; | |
66 int row_dec = s->frame.linesize[0]; | |
67 int row_ptr = (s->avctx->height - 1) * row_dec; | |
68 int frame_size = row_dec * s->avctx->height; | |
69 int i; | |
70 | |
71 /* make the palette available */ | |
72 memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE); | |
73 if (s->avctx->palctrl->palette_changed) { | |
74 s->frame.palette_has_changed = 1; | |
75 s->avctx->palctrl->palette_changed = 0; | |
76 } | |
77 | |
78 while (row_ptr >= 0) { | |
79 FETCH_NEXT_STREAM_BYTE(); | |
80 rle_code = stream_byte; | |
81 if (rle_code == 0) { | |
82 /* fetch the next byte to see how to handle escape code */ | |
83 FETCH_NEXT_STREAM_BYTE(); | |
84 if (stream_byte == 0) { | |
85 /* line is done, goto the next one */ | |
86 row_ptr -= row_dec; | |
87 pixel_ptr = 0; | |
88 } else if (stream_byte == 1) { | |
89 /* decode is done */ | |
90 return; | |
91 } else if (stream_byte == 2) { | |
92 /* reposition frame decode coordinates */ | |
93 FETCH_NEXT_STREAM_BYTE(); | |
94 pixel_ptr += stream_byte; | |
95 FETCH_NEXT_STREAM_BYTE(); | |
96 row_ptr -= stream_byte * row_dec; | |
97 } else { | |
98 // copy pixels from encoded stream | |
99 odd_pixel = stream_byte & 1; | |
100 rle_code = (stream_byte + 1) / 2; | |
101 extra_byte = rle_code & 0x01; | |
102 if ((row_ptr + pixel_ptr + stream_byte > frame_size) || | |
103 (row_ptr < 0)) { | |
104 av_log(s->avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (1)\n"); | |
105 return; | |
106 } | |
107 | |
108 for (i = 0; i < rle_code; i++) { | |
109 if (pixel_ptr >= s->avctx->width) | |
110 break; | |
111 FETCH_NEXT_STREAM_BYTE(); | |
112 s->frame.data[0][row_ptr + pixel_ptr] = stream_byte >> 4; | |
113 pixel_ptr++; | |
1769 | 114 if (i + 1 == rle_code && odd_pixel) |
115 break; | |
1609 | 116 if (pixel_ptr >= s->avctx->width) |
117 break; | |
118 s->frame.data[0][row_ptr + pixel_ptr] = stream_byte & 0x0F; | |
119 pixel_ptr++; | |
120 } | |
121 | |
122 // if the RLE code is odd, skip a byte in the stream | |
123 if (extra_byte) | |
124 stream_ptr++; | |
125 } | |
126 } else { | |
127 // decode a run of data | |
128 if ((row_ptr + pixel_ptr + stream_byte > frame_size) || | |
129 (row_ptr < 0)) { | |
130 av_log(s->avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (1)\n"); | |
131 return; | |
132 } | |
133 FETCH_NEXT_STREAM_BYTE(); | |
134 for (i = 0; i < rle_code; i++) { | |
135 if (pixel_ptr >= s->avctx->width) | |
136 break; | |
137 if ((i & 1) == 0) | |
138 s->frame.data[0][row_ptr + pixel_ptr] = stream_byte >> 4; | |
139 else | |
140 s->frame.data[0][row_ptr + pixel_ptr] = stream_byte & 0x0F; | |
141 pixel_ptr++; | |
142 } | |
143 } | |
144 } | |
145 | |
146 /* one last sanity check on the way out */ | |
147 if (stream_ptr < s->size) | |
148 av_log(s->avctx, AV_LOG_ERROR, " MS RLE: ended frame decode with bytes left over (%d < %d)\n", | |
149 stream_ptr, s->size); | |
150 } | |
151 | |
152 | |
153 | |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
154 static void msrle_decode_pal8(MsrleContext *s) |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
155 { |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
156 int stream_ptr = 0; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
157 unsigned char rle_code; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
158 unsigned char extra_byte; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
159 unsigned char stream_byte; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
160 int pixel_ptr = 0; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
161 int row_dec = s->frame.linesize[0]; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
162 int row_ptr = (s->avctx->height - 1) * row_dec; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
163 int frame_size = row_dec * s->avctx->height; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
164 |
1604
21190cfac0e1
100l: sometime palette was not copied to output frame
rtognimp
parents:
1598
diff
changeset
|
165 /* make the palette available */ |
21190cfac0e1
100l: sometime palette was not copied to output frame
rtognimp
parents:
1598
diff
changeset
|
166 memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE); |
21190cfac0e1
100l: sometime palette was not copied to output frame
rtognimp
parents:
1598
diff
changeset
|
167 if (s->avctx->palctrl->palette_changed) { |
21190cfac0e1
100l: sometime palette was not copied to output frame
rtognimp
parents:
1598
diff
changeset
|
168 s->frame.palette_has_changed = 1; |
21190cfac0e1
100l: sometime palette was not copied to output frame
rtognimp
parents:
1598
diff
changeset
|
169 s->avctx->palctrl->palette_changed = 0; |
21190cfac0e1
100l: sometime palette was not copied to output frame
rtognimp
parents:
1598
diff
changeset
|
170 } |
21190cfac0e1
100l: sometime palette was not copied to output frame
rtognimp
parents:
1598
diff
changeset
|
171 |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
172 while (row_ptr >= 0) { |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
173 FETCH_NEXT_STREAM_BYTE(); |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
174 rle_code = stream_byte; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
175 if (rle_code == 0) { |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
176 /* fetch the next byte to see how to handle escape code */ |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
177 FETCH_NEXT_STREAM_BYTE(); |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
178 if (stream_byte == 0) { |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
179 /* line is done, goto the next one */ |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
180 row_ptr -= row_dec; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
181 pixel_ptr = 0; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
182 } else if (stream_byte == 1) { |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
183 /* decode is done */ |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
184 return; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
185 } else if (stream_byte == 2) { |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
186 /* reposition frame decode coordinates */ |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
187 FETCH_NEXT_STREAM_BYTE(); |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
188 pixel_ptr += stream_byte; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
189 FETCH_NEXT_STREAM_BYTE(); |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
190 row_ptr -= stream_byte * row_dec; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
191 } else { |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
192 /* copy pixels from encoded stream */ |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
193 if ((row_ptr + pixel_ptr + stream_byte > frame_size) || |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
194 (row_ptr < 0)) { |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1595
diff
changeset
|
195 av_log(s->avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (1)\n"); |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
196 return; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
197 } |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
198 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
199 rle_code = stream_byte; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
200 extra_byte = stream_byte & 0x01; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
201 if (stream_ptr + rle_code + extra_byte > s->size) { |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1595
diff
changeset
|
202 av_log(s->avctx, AV_LOG_ERROR, " MS RLE: stream ptr just went out of bounds (2)\n"); |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
203 return; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
204 } |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
205 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
206 while (rle_code--) { |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
207 FETCH_NEXT_STREAM_BYTE(); |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
208 s->frame.data[0][row_ptr + pixel_ptr] = stream_byte; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
209 pixel_ptr++; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
210 } |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
211 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
212 /* if the RLE code is odd, skip a byte in the stream */ |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
213 if (extra_byte) |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
214 stream_ptr++; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
215 } |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
216 } else { |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
217 /* decode a run of data */ |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
218 if ((row_ptr + pixel_ptr + stream_byte > frame_size) || |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
219 (row_ptr < 0)) { |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1595
diff
changeset
|
220 av_log(s->avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (2)\n"); |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
221 return; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
222 } |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
223 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
224 FETCH_NEXT_STREAM_BYTE(); |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
225 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
226 while(rle_code--) { |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
227 s->frame.data[0][row_ptr + pixel_ptr] = stream_byte; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
228 pixel_ptr++; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
229 } |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
230 } |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
231 } |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
232 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
233 /* one last sanity check on the way out */ |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
234 if (stream_ptr < s->size) |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1595
diff
changeset
|
235 av_log(s->avctx, AV_LOG_ERROR, " MS RLE: ended frame decode with bytes left over (%d < %d)\n", |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
236 stream_ptr, s->size); |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
237 } |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
238 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
239 static int msrle_decode_init(AVCodecContext *avctx) |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
240 { |
4827 | 241 MsrleContext *s = avctx->priv_data; |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
242 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
243 s->avctx = avctx; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
244 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
245 avctx->pix_fmt = PIX_FMT_PAL8; |
1630 | 246 s->frame.data[0] = NULL; |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
247 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
248 return 0; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
249 } |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
250 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
251 static int msrle_decode_frame(AVCodecContext *avctx, |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
252 void *data, int *data_size, |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
253 uint8_t *buf, int buf_size) |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
254 { |
4827 | 255 MsrleContext *s = avctx->priv_data; |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
256 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
257 s->buf = buf; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
258 s->size = buf_size; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
259 |
1592 | 260 s->frame.reference = 1; |
1630 | 261 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; |
262 if (avctx->reget_buffer(avctx, &s->frame)) { | |
263 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); | |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
264 return -1; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
265 } |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
266 |
1609 | 267 switch (avctx->bits_per_sample) { |
268 case 8: | |
269 msrle_decode_pal8(s); | |
270 break; | |
271 case 4: | |
272 msrle_decode_pal4(s); | |
273 break; | |
274 default: | |
275 av_log(avctx, AV_LOG_ERROR, "Don't know how to decode depth %u.\n", | |
276 avctx->bits_per_sample); | |
277 } | |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
278 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
279 *data_size = sizeof(AVFrame); |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
280 *(AVFrame*)data = s->frame; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
281 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
282 /* report that the buffer was completely consumed */ |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
283 return buf_size; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
284 } |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
285 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
286 static int msrle_decode_end(AVCodecContext *avctx) |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
287 { |
4827 | 288 MsrleContext *s = avctx->priv_data; |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
289 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
290 /* release the last frame */ |
1630 | 291 if (s->frame.data[0]) |
292 avctx->release_buffer(avctx, &s->frame); | |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
293 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
294 return 0; |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
295 } |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
296 |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
297 AVCodec msrle_decoder = { |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
298 "msrle", |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
299 CODEC_TYPE_VIDEO, |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
300 CODEC_ID_MSRLE, |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
301 sizeof(MsrleContext), |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
302 msrle_decode_init, |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
303 NULL, |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
304 msrle_decode_end, |
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
305 msrle_decode_frame, |
1630 | 306 CODEC_CAP_DR1, |
1491
222643544cf1
New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE &
tmmm
parents:
diff
changeset
|
307 }; |