comparison interplayvideo.c @ 9312:601e91e470e7 libavcodec

Make ipvideo_decode_block_opcode_0x8 a lot simpler by decoding the pixels in a more natural order.
author reimar
date Tue, 31 Mar 2009 18:35:19 +0000
parents 5d20b2610662
children a476e5590725
comparison
equal deleted inserted replaced
9311:5d20b2610662 9312:601e91e470e7
241 } 241 }
242 242
243 static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s) 243 static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s)
244 { 244 {
245 int x, y; 245 int x, y;
246 unsigned char P[8]; 246 unsigned char P[2];
247 unsigned char B[8];
248 unsigned int flags = 0; 247 unsigned int flags = 0;
249 unsigned char P0 = 0, P1 = 0;
250 int lower_half = 0;
251 248
252 /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on 249 /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
253 * either top and bottom or left and right halves */ 250 * either top and bottom or left and right halves */
254 CHECK_STREAM_PTR(2); 251 CHECK_STREAM_PTR(2);
255 252
257 P[1] = *s->stream_ptr++; 254 P[1] = *s->stream_ptr++;
258 255
259 if (P[0] <= P[1]) { 256 if (P[0] <= P[1]) {
260 257
261 CHECK_STREAM_PTR(14); 258 CHECK_STREAM_PTR(14);
262 B[0] = *s->stream_ptr++; B[1] = *s->stream_ptr++; 259 s->stream_ptr -= 2;
263 P[2] = *s->stream_ptr++; P[3] = *s->stream_ptr++; 260
264 B[2] = *s->stream_ptr++; B[3] = *s->stream_ptr++; 261 for (y = 0; y < 16; y++) {
265 P[4] = *s->stream_ptr++; P[5] = *s->stream_ptr++; 262 // new values for each 4x4 block
266 B[4] = *s->stream_ptr++; B[5] = *s->stream_ptr++; 263 if (!(y & 3)) {
267 P[6] = *s->stream_ptr++; P[7] = *s->stream_ptr++; 264 P[0] = *s->stream_ptr++; P[1] = *s->stream_ptr++;
268 B[6] = *s->stream_ptr++; B[7] = *s->stream_ptr++; 265 flags = bytestream_get_le16(&s->stream_ptr);
269 266 }
270 for (y = 0; y < 8; y++) { 267
271 268 for (x = 0; x < 4; x++, flags >>= 1) {
272 /* time to reload flags? */ 269 *s->pixel_ptr++ = P[flags & 1];
273 if (y == 0) { 270 }
274 flags = 271 s->pixel_ptr += s->stride - 4;
275 ((B[0] & 0xF0) << 4) | ((B[4] & 0xF0) << 8) | 272 // switch to right half
276 ((B[0] & 0x0F) ) | ((B[4] & 0x0F) << 4) | 273 if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
277 ((B[1] & 0xF0) << 20) | ((B[5] & 0xF0) << 24) |
278 ((B[1] & 0x0F) << 16) | ((B[5] & 0x0F) << 20);
279 lower_half = 0; /* still on top half */
280 } else if (y == 4) {
281 flags =
282 ((B[2] & 0xF0) << 4) | ((B[6] & 0xF0) << 8) |
283 ((B[2] & 0x0F) ) | ((B[6] & 0x0F) << 4) |
284 ((B[3] & 0xF0) << 20) | ((B[7] & 0xF0) << 24) |
285 ((B[3] & 0x0F) << 16) | ((B[7] & 0x0F) << 20);
286 lower_half = 2;
287 }
288
289 for (x = 0; x < 8; x++, flags >>= 1) {
290 /* get the pixel values ready for this quadrant */
291 if (x == 0) {
292 P0 = P[lower_half + 0];
293 P1 = P[lower_half + 1];
294 } else if (x == 4) {
295 P0 = P[lower_half + 4];
296 P1 = P[lower_half + 5];
297 }
298
299 *s->pixel_ptr++ = flags & 1 ? P1 : P0;
300 }
301 s->pixel_ptr += s->line_inc;
302 } 274 }
303 275
304 } else { 276 } else {
305 277
306 /* need 10 more bytes */ 278 /* need 10 more bytes */
307 CHECK_STREAM_PTR(10); 279 CHECK_STREAM_PTR(10);
308 280
309 if (s->stream_ptr[4] <= s->stream_ptr[5]) { 281 if (s->stream_ptr[4] <= s->stream_ptr[5]) {
310 282
311 B[0] = *s->stream_ptr++; B[1] = *s->stream_ptr++; 283 flags = bytestream_get_le32(&s->stream_ptr);
312 B[2] = *s->stream_ptr++; B[3] = *s->stream_ptr++;
313 P[2] = *s->stream_ptr++; P[3] = *s->stream_ptr++;
314 B[4] = *s->stream_ptr++; B[5] = *s->stream_ptr++;
315 B[6] = *s->stream_ptr++; B[7] = *s->stream_ptr++;
316 284
317 /* vertical split; left & right halves are 2-color encoded */ 285 /* vertical split; left & right halves are 2-color encoded */
318 286
319 for (y = 0; y < 8; y++) { 287 for (y = 0; y < 16; y++) {
320 288 for (x = 0; x < 4; x++, flags >>= 1) {
321 /* time to reload flags? */ 289 *s->pixel_ptr++ = P[flags & 1];
322 if (y == 0) { 290 }
323 flags = 291 s->pixel_ptr += s->stride - 4;
324 ((B[0] & 0xF0) << 4) | ((B[4] & 0xF0) << 8) | 292 // switch to right half
325 ((B[0] & 0x0F) ) | ((B[4] & 0x0F) << 4) | 293 if (y == 7) {
326 ((B[1] & 0xF0) << 20) | ((B[5] & 0xF0) << 24) | 294 s->pixel_ptr -= 8 * s->stride - 4;
327 ((B[1] & 0x0F) << 16) | ((B[5] & 0x0F) << 20); 295 P[0] = *s->stream_ptr++; P[1] = *s->stream_ptr++;
328 } else if (y == 4) { 296 flags = bytestream_get_le32(&s->stream_ptr);
329 flags = 297 }
330 ((B[2] & 0xF0) << 4) | ((B[6] & 0xF0) << 8) |
331 ((B[2] & 0x0F) ) | ((B[6] & 0x0F) << 4) |
332 ((B[3] & 0xF0) << 20) | ((B[7] & 0xF0) << 24) |
333 ((B[3] & 0x0F) << 16) | ((B[7] & 0x0F) << 20);
334 }
335
336 for (x = 0; x < 8; x++, flags >>= 1) {
337 /* get the pixel values ready for this half */
338 if (x == 0) {
339 P0 = P[0];
340 P1 = P[1];
341 } else if (x == 4) {
342 P0 = P[2];
343 P1 = P[3];
344 }
345
346 *s->pixel_ptr++ = flags & 1 ? P1 : P0;
347 }
348 s->pixel_ptr += s->line_inc;
349 } 298 }
350 299
351 } else { 300 } else {
352 301
353 /* horizontal split; top & bottom halves are 2-color encoded */ 302 /* horizontal split; top & bottom halves are 2-color encoded */