Unified · Split
| @@ -51,6 +51,8 @@ typedef struct LagarithContext { · 50 unmodified lines | ||
| 51 | 51 | DSPContext dsp; |
| 52 | 52 | int zeros; /**< number of consecutive zero bytes encountered */ |
| 53 | 53 | int zeros_rem; /**< number of zero bytes remaining to output */ |
| 54 | + uint8_t *rgb_planes; | |
| 55 | + int rgb_stride; | |
| 54 | 56 | } LagarithContext; |
| 55 | 57 | |
| 56 | 58 | /** |
| @@ -443,6 +445,9 @@ static int lag_decode_frame(AVCodecContext *avctx, · 386 unmodified lines | ||
| 443 | 445 | AVFrame *const p = &l->picture; |
| 444 | 446 | uint8_t frametype = 0; |
| 445 | 447 | uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9; |
| 448 | + int offs[4]; | |
| 449 | + uint8_t *srcs[4], *dst; | |
| 450 | + int i, j; | |
| 446 | 451 | |
| 447 | 452 | AVFrame *picture = data; |
| 448 | 453 | |
| @@ -458,6 +463,67 @@ static int lag_decode_frame(AVCodecContext *avctx, · 9 unmodified lines | ||
| 458 | 463 | offset_bv = AV_RL32(buf + 5); |
| 459 | 464 | |
| 460 | 465 | switch (frametype) { |
| 466 | + case FRAME_SOLID_RGBA: | |
| 467 | + avctx->pix_fmt = PIX_FMT_RGB32; | |
| 468 | + | |
| 469 | + if (avctx->get_buffer(avctx, p) < 0) { | |
| 470 | + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
| 471 | + return -1; | |
| 472 | + } | |
| 473 | + | |
| 474 | + dst = p->data[0]; | |
| 475 | + for (j = 0; j < avctx->height; j++) { | |
| 476 | + for (i = 0; i < avctx->width; i++) | |
| 477 | + AV_WN32(dst + i * 4, offset_gu); | |
| 478 | + dst += p->linesize[0]; | |
| 479 | + } | |
| 480 | + break; | |
| 481 | + case FRAME_ARITH_RGBA: | |
| 482 | + avctx->pix_fmt = PIX_FMT_RGB32; | |
| 483 | + | |
| 484 | + if (avctx->get_buffer(avctx, p) < 0) { | |
| 485 | + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
| 486 | + return -1; | |
| 487 | + } | |
| 488 | + offs[0] = offset_bv; | |
| 489 | + offs[1] = offset_gu; | |
| 490 | + offs[2] = 13; | |
| 491 | + offs[3] = AV_RL32(buf + 9); | |
| 492 | + | |
| 493 | + if (!l->rgb_planes) { | |
| 494 | + l->rgb_stride = FFALIGN(avctx->width, 16); | |
| 495 | + l->rgb_planes = av_malloc(l->rgb_stride * avctx->height * 4); | |
| 496 | + if (!l->rgb_planes) { | |
| 497 | + av_log(avctx, AV_LOG_ERROR, "cannot allocate temporary buffer\n"); | |
| 498 | + return AVERROR(ENOMEM); | |
| 499 | + } | |
| 500 | + } | |
| 501 | + for (i = 0; i < 4; i++) | |
| 502 | + srcs[i] = l->rgb_planes + (i + 1) * l->rgb_stride * avctx->height - l->rgb_stride; | |
| 503 | + for (i = 0; i < 4; i++) | |
| 504 | + lag_decode_arith_plane(l, srcs[i], | |
| 505 | + avctx->width, avctx->height, | |
| 506 | + -l->rgb_stride, buf + offs[i], | |
| 507 | + buf_size); | |
| 508 | + dst = p->data[0]; | |
| 509 | + for (i = 0; i < 4; i++) | |
| 510 | + srcs[i] = l->rgb_planes + i * l->rgb_stride * avctx->height; | |
| 511 | + for (j = 0; j < avctx->height; j++) { | |
| 512 | + for (i = 0; i < avctx->width; i++) { | |
| 513 | + uint8_t r, g, b, a; | |
| 514 | + r = srcs[0][i]; | |
| 515 | + g = srcs[1][i]; | |
| 516 | + b = srcs[2][i]; | |
| 517 | + a = srcs[3][i]; | |
| 518 | + r += g; | |
| 519 | + b += g; | |
| 520 | + AV_WN32(dst + i * 4, MKBETAG(a, r, g, b)); | |
| 521 | + } | |
| 522 | + dst += p->linesize[0]; | |
| 523 | + for (i = 0; i < 4; i++) | |
| 524 | + srcs[i] += l->rgb_stride; | |
| 525 | + } | |
| 526 | + break; | |
| 461 | 527 | case FRAME_ARITH_YV12: |
| 462 | 528 | avctx->pix_fmt = PIX_FMT_YUV420P; |
| 463 | 529 | |
| @@ -504,6 +570,7 @@ static av_cold int lag_decode_end(AVCodecContext *avctx) · 40 unmodified lines | ||
| 504 | 570 | |
| 505 | 571 | if (l->picture.data[0]) |
| 506 | 572 | avctx->release_buffer(avctx, &l->picture); |
| 573 | + av_freep(&l->rgb_planes); | |
| 507 | 574 | |
| 508 | 575 | return 0; |
| 509 | 576 | } |