1 /*
2 * Discworld II BMV video decoder
3 * Copyright (c) 2011 Konstantin Shishkov
4 *
5 * This file is part of FFmpeg.
6 *
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.
11 *
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.
16 *
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
20 */
21
24
29
35
42 };
43
44 #define SCREEN_WIDE 640
45 #define SCREEN_HIGH 429
46
49
54
55 #define NEXT_BYTE(v) (v) = forward ? (v) + 1 : (v) - 1;
56
58 {
59 unsigned val, saved_val = 0;
60 int tmplen = src_len;
61 const uint8_t *
src, *source_end =
source + src_len;
63 uint8_t *
dst, *dst_end;
66 int read_two_nibbles,
flag;
67 int advance_mode;
70
71 if (src_len <= 0)
73
78 } else {
82 }
83 for (;;) {
86
87 /* The mode/len decoding is a bit strange:
88 * values are coded as variable-length codes with nibble units,
89 * code end is signalled by two top bits in the nibble being nonzero.
90 * And since data is bytepacked and we read two nibbles at a time,
91 * we may get a nibble belonging to the next code.
92 * Hence this convoluted loop.
93 */
94 if (!
mode || (tmplen == 4)) {
95 if (src < source || src >= source_end)
98 read_two_nibbles = 1;
99 } else {
101 read_two_nibbles = 0;
102 }
104 for (;;) {
106 return -1;
107 if (!read_two_nibbles) {
108 if (src < source || src >= source_end)
113 break;
114 }
115 // two upper bits of the nibble is zero,
116 // so shift top nibble value down into their place
117 read_two_nibbles = 0;
124 break;
125 }
126 }
129 }
131 tmplen = 4;
132 } else {
134 tmplen = 0;
137 }
138 advance_mode =
val & 1;
141 mode += 1 + advance_mode;
147 case 1:
157 } else {
164 for (
i =
len - 1;
i >= 0;
i--)
166 }
167 break;
168 case 2:
175 } else {
181 }
182 break;
183 case 3:
188 } else {
191 }
192 break;
193 }
195 return 0;
196 }
197 }
198
201 {
205 uint8_t *srcptr, *outptr;
206
208 type = bytestream_get_byte(&
c->stream);
210 int blobs = bytestream_get_byte(&
c->stream);
211 if (
pkt->
size < blobs * 65 + 2) {
214 }
215 c->stream += blobs * 65;
216 }
222 }
223 c->stream += command_size;
224 }
229 }
230 for (
i = 0;
i < 256;
i++)
231 c->pal[
i] = 0xFFU << 24 | bytestream_get_be24(&
c->stream);
232 }
237 }
238 scr_off = (int16_t)bytestream_get_le16(&
c->stream);
240 scr_off = -640;
241 } else {
242 scr_off = 0;
243 }
244
247
251 }
252
254
255 outptr =
frame->data[0];
257
259 memcpy(outptr, srcptr, avctx->
width);
260 srcptr += avctx->
width;
261 outptr +=
frame->linesize[0];
262 }
263
264 *got_frame = 1;
265
266 /* always report that the buffer was completely consumed */
268 }
269
271 {
273
276
280 }
281
282 c->frame =
c->frame_base + 640;
283
284 return 0;
285 }
286
288 .
p.
name =
"bmv_video",
296 };