| 367 | } |
| 368 | |
| 369 | static int cinepak_decode (CinepakContext *s) |
| 370 | { |
| 371 | const uint8_t *eod = (s->data + s->size); |
| 372 | int i, result, strip_size, frame_flags, num_strips; |
| 373 | int y0 = 0; |
| 374 | |
| 375 | frame_flags = s->data[0]; |
| 376 | num_strips = AV_RB16 (&s->data[8]); |
| 377 | |
| 378 | s->data += 10 + s->sega_film_skip_bytes; |
| 379 | |
| 380 | num_strips = FFMIN(num_strips, MAX_STRIPS); |
| 381 | |
| 382 | s->frame->flags &= ~AV_FRAME_FLAG_KEY; |
| 383 | |
| 384 | for (i=0; i < num_strips; i++) { |
| 385 | if ((s->data + 12) > eod) |
| 386 | return AVERROR_INVALIDDATA; |
| 387 | |
| 388 | s->strips[i].id = s->data[0]; |
| 389 | /* zero y1 means "relative to the previous stripe" */ |
| 390 | if (!(s->strips[i].y1 = AV_RB16 (&s->data[4]))) |
| 391 | s->strips[i].y2 = (s->strips[i].y1 = y0) + AV_RB16 (&s->data[8]); |
| 392 | else |
| 393 | s->strips[i].y2 = AV_RB16 (&s->data[8]); |
| 394 | s->strips[i].x1 = AV_RB16 (&s->data[6]); |
| 395 | s->strips[i].x2 = AV_RB16 (&s->data[10]); |
| 396 | |
| 397 | if (s->strips[i].id == 0x10) |
| 398 | s->frame->flags |= AV_FRAME_FLAG_KEY; |
| 399 | |
| 400 | strip_size = AV_RB24 (&s->data[1]) - 12; |
| 401 | if (strip_size < 0) |
| 402 | return AVERROR_INVALIDDATA; |
| 403 | s->data += 12; |
| 404 | strip_size = ((s->data + strip_size) > eod) ? (eod - s->data) : strip_size; |
| 405 | |
| 406 | if ((i > 0) && !(frame_flags & 0x01)) { |
| 407 | memcpy (s->strips[i].v4_codebook, s->strips[i-1].v4_codebook, |
| 408 | sizeof(s->strips[i].v4_codebook)); |
| 409 | memcpy (s->strips[i].v1_codebook, s->strips[i-1].v1_codebook, |
| 410 | sizeof(s->strips[i].v1_codebook)); |
| 411 | } |
| 412 | |
| 413 | result = cinepak_decode_strip (s, &s->strips[i], s->data, strip_size); |
| 414 | |
| 415 | if (result != 0) |
| 416 | return result; |
| 417 | |
| 418 | s->data += strip_size; |
| 419 | y0 = s->strips[i].y2; |
| 420 | } |
| 421 | return 0; |
| 422 | } |
| 423 | |
| 424 | static av_cold int cinepak_decode_init(AVCodecContext *avctx) |
| 425 | { |
no test coverage detected