Fixes ticket #1288.
Unified · Split
| @@ -41,19 +41,31 @@ static int avui_decode_frame(AVCodecContext *avctx, void *data, · 40 unmodified lines | ||
| 41 | 41 | { |
| 42 | 42 | AVFrame *pic = avctx->coded_frame; |
| 43 | 43 | const uint8_t *src = avpkt->data; |
| 44 | − const uint8_t *srca = src + 2 * (avctx->height + 16) * avctx->width + 9; | |
| 44 | + const uint8_t *srca; | |
| 45 | 45 | uint8_t *y, *u, *v, *a; |
| 46 | − int transparent = 0, i, j, k; | |
| 46 | + int transparent, interlaced = 1, skip[2], i, j, k; | |
| 47 | 47 | |
| 48 | 48 | if (pic->data[0]) |
| 49 | 49 | avctx->release_buffer(avctx, pic); |
| 50 | 50 | |
| 51 | − if (avpkt->size < 2 * avctx->width * (avctx->height + 16) + 4) { | |
| 51 | + if (!memcmp(&avctx->extradata[4], "APRGAPRG0001", 12) && | |
| 52 | + avctx->extradata_size >= 24) | |
| 53 | + interlaced = avctx->extradata[19] != 1; | |
| 54 | + skip[0] = skip[1] = 16; | |
| 55 | + if (avctx->height == 486) { | |
| 56 | + skip[0] = 8; | |
| 57 | + skip[1] = 12; | |
| 58 | + } | |
| 59 | + if (avpkt->size < avctx->width * (2 * avctx->height + skip[0] + skip[1]) | |
| 60 | + + 4 * interlaced) { | |
| 52 | 61 | av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n"); |
| 53 | 62 | return AVERROR(EINVAL); |
| 54 | 63 | } |
| 55 | − if (avpkt->size >= 4 * avctx->width * (avctx->height + 16) + 13) | |
| 56 | − transparent = 1; | |
| 64 | + transparent = avctx->bits_per_coded_sample == 32 && | |
| 65 | + avpkt->size >= (2 * avctx->height + skip[0] + skip[1]) * | |
| 66 | + 2 * avctx->width + 4 + 8 * interlaced; | |
| 67 | + srca = src + (2 * avctx->height + skip[0] + skip[1]) * avctx->width | |
| 68 | + + 5 + interlaced * 4; | |
| 57 | 69 | |
| 58 | 70 | pic->reference = 0; |
| 59 | 71 | |
| @@ -65,16 +77,21 @@ static int avui_decode_frame(AVCodecContext *avctx, void *data, · 5 unmodified lines | ||
| 65 | 77 | pic->key_frame = 1; |
| 66 | 78 | pic->pict_type = AV_PICTURE_TYPE_I; |
| 67 | 79 | |
| 68 | − for (i = 0; i < 2; i++) { | |
| 69 | − src += avctx->width * 16; | |
| 70 | − srca += avctx->width * 16; | |
| 80 | + if (!interlaced) { | |
| 81 | + src += avctx->width * skip[1]; | |
| 82 | + srca += avctx->width * skip[1]; | |
| 83 | + } | |
| 84 | + | |
| 85 | + for (i = 0; i < interlaced + 1; i++) { | |
| 86 | + src += avctx->width * skip[i]; | |
| 87 | + srca += avctx->width * skip[i]; | |
| 71 | 88 | y = pic->data[0] + i * pic->linesize[0]; |
| 72 | 89 | u = pic->data[1] + i * pic->linesize[1]; |
| 73 | 90 | v = pic->data[2] + i * pic->linesize[2]; |
| 74 | 91 | a = pic->data[3] + i * pic->linesize[3]; |
| 75 | 92 | |
| 76 | − for (j = 0; j < (avctx->height + 1) >> 1; j++) { | |
| 77 | − for (k = 0; k < (avctx->width + 1) >> 1; k++) { | |
| 93 | + for (j = 0; j < avctx->height >> interlaced; j++) { | |
| 94 | + for (k = 0; k < avctx->width >> 1; k++) { | |
| 78 | 95 | u[ k ] = *src++; |
| 79 | 96 | y[2 * k ] = *src++; |
| 80 | 97 | a[2 * k ] = 0xFF - (transparent ? *srca++ : 0); |
| @@ -85,10 +102,10 @@ static int avui_decode_frame(AVCodecContext *avctx, void *data, · 4 unmodified lines | ||
| 85 | 102 | srca++; |
| 86 | 103 | } |
| 87 | 104 | |
| 88 | − y += 2 * pic->linesize[0]; | |
| 89 | − u += 2 * pic->linesize[1]; | |
| 90 | − v += 2 * pic->linesize[2]; | |
| 91 | − a += 2 * pic->linesize[3]; | |
| 105 | + y += (interlaced + 1) * pic->linesize[0]; | |
| 106 | + u += (interlaced + 1) * pic->linesize[1]; | |
| 107 | + v += (interlaced + 1) * pic->linesize[2]; | |
| 108 | + a += (interlaced + 1) * pic->linesize[3]; | |
| 92 | 109 | } |
| 93 | 110 | src += 4; |
| 94 | 111 | srca += 4; |