1 /*
2 * Beam Software VB decoder
3 * Copyright (c) 2007 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
22 /**
23 * @file
24 * VB Video decoder
25 */
26
31
38 };
39
42
47
49 0x0660, 0xFF00, 0xCCCC, 0xF000, 0x8888, 0x000F, 0x1111, 0xFEC8,
50 0x8CEF, 0x137F, 0xF731, 0xC800, 0x008C, 0x0013, 0x3100, 0xCC00,
51 0x00CC, 0x0033, 0x3300, 0x0FF0, 0x6666, 0x00F0, 0x0F00, 0x2222,
52 0x4444, 0xF600, 0x8CC8, 0x006F, 0x1331, 0x318C, 0xC813, 0x33CC,
53 0x6600, 0x0CC0, 0x0066, 0x0330, 0xF900, 0xC88C, 0x009F, 0x3113,
54 0x6000, 0x0880, 0x0006, 0x0110, 0xCC88, 0xFC00, 0x00CF, 0x88CC,
55 0x003F, 0x1133, 0x3311, 0xF300, 0x6FF6, 0x0603, 0x08C6, 0x8C63,
56 0xC631, 0x6310, 0xC060, 0x0136, 0x136C, 0x36C8, 0x6C80, 0x324C
57 };
58
60 {
62
63 start = bytestream2_get_byte(&
c->stream);
64 size = (bytestream2_get_byte(&
c->stream) - 1) & 0xFF;
65 if (start +
size > 255) {
67 return;
68 }
69 if (
size*3+2 > data_size) {
71 return;
72 }
73 for (
i = start;
i <= start +
size;
i++)
74 c->pal[
i] = 0xFFU << 24 | bytestream2_get_be24(&
c->stream);
75 }
76
77 static inline int check_pixel(uint8_t *buf, uint8_t *start, uint8_t *end)
78 {
79 return buf >= start && buf < end;
80 }
81
82 static inline int check_line(uint8_t *buf, uint8_t *start, uint8_t *end)
83 {
84 return buf >= start && (buf + 4) <= end;
85 }
86
88 {
90 uint8_t *prev, *cur;
91 int blk, blocks, t, blk2;
92 int blocktypes = 0;
94 int pattype, pattern;
95 const int width =
c->avctx->width;
96 uint8_t *pstart =
c->prev_frame;
97 uint8_t *pend =
c->prev_frame +
width*
c->avctx->height;
98
100
103
104 blocks = (
c->avctx->width >> 2) * (
c->avctx->height >> 2);
105 blk2 = 0;
111 }
112 blocktypes = bytestream2_get_byte(&
g);
113 }
114 switch (blocktypes & 0xC0) {
115 case 0x00: //skip
116 for (y = 0; y < 4; y++)
119 else
120 memset(cur + y*
width, 0, 4);
121 break;
122 case 0x40:
123 t = bytestream2_get_byte(&
g);
124 if (!t) { //raw block
128 }
129 for (y = 0; y < 4; y++)
131 } else { // motion compensation
132 x = ((t & 0xF)^8) - 8;
133 y = ((t >> 4) ^8) - 8;
135 for (y = 0; y < 4; y++)
138 else
139 memset(cur + y*
width, 0, 4);
140 }
141 break;
142 case 0x80: // fill
143 t = bytestream2_get_byte(&
g);
144 for (y = 0; y < 4; y++)
145 memset(cur + y*
width, t, 4);
146 break;
147 case 0xC0: // pattern fill
148 t = bytestream2_get_byte(&
g);
149 pattype = t >> 6;
151 switch (pattype) {
152 case 0:
153 a = bytestream2_get_byte(&
g);
154 b = bytestream2_get_byte(&
g);
155 for (y = 0; y < 4; y++)
156 for (x = 0; x < 4; x++, pattern >>= 1)
157 cur[x + y*
width] = (pattern & 1) ?
b :
a;
158 break;
159 case 1:
160 pattern = ~pattern;
161 case 2:
162 a = bytestream2_get_byte(&
g);
163 for (y = 0; y < 4; y++)
164 for (x = 0; x < 4; x++, pattern >>= 1)
167 else
169 break;
170 case 3:
173 }
174 break;
175 }
176 blocktypes <<= 2;
177 cur += 4;
178 prev += 4;
179 blk2++;
180 if (blk2 == (
width >> 2)) {
181 blk2 = 0;
184 }
185 }
186 return 0;
187 }
188
191 {
193 uint8_t *outptr, *srcptr;
198
201
203
206
207 flags = bytestream2_get_le16(&
c->stream);
208
210 i = (int16_t)bytestream2_get_le16(&
c->stream);
211 j = (int16_t)bytestream2_get_le16(&
c->stream);
215 }
217 }
219 size = bytestream2_get_le32(&
c->stream);
222 return -1;
223 }
226 }
228 size = bytestream2_get_le32(&
c->stream);
230 }
231
234
235 outptr =
frame->data[0];
237
239 memcpy(outptr, srcptr, avctx->
width);
240 srcptr += avctx->
width;
241 outptr +=
frame->linesize[0];
242 }
243
244 FFSWAP(uint8_t*,
c->frame,
c->prev_frame);
245
246 *got_frame = 1;
247
248 /* always report that the buffer was completely consumed */
250 }
251
253 {
255
258
261
262 if (!
c->frame || !
c->prev_frame)
264
265 return 0;
266 }
267
269 {
271
274
275 return 0;
276 }
277
289 };