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