| @@ -41,19 +41,31 @@ static int avui_decode_frame(AVCodecContext *avctx, void *data, | |||||
| { | { | ||||
| AVFrame *pic = avctx->coded_frame; | AVFrame *pic = avctx->coded_frame; | ||||
| const uint8_t *src = avpkt->data; | const uint8_t *src = avpkt->data; | ||||
| const uint8_t *srca = src + 2 * (avctx->height + 16) * avctx->width + 9; | |||||
| const uint8_t *srca; | |||||
| uint8_t *y, *u, *v, *a; | uint8_t *y, *u, *v, *a; | ||||
| int transparent = 0, i, j, k; | |||||
| int transparent, interlaced = 1, skip[2], i, j, k; | |||||
| if (pic->data[0]) | if (pic->data[0]) | ||||
| avctx->release_buffer(avctx, pic); | avctx->release_buffer(avctx, pic); | ||||
| if (avpkt->size < 2 * avctx->width * (avctx->height + 16) + 4) { | |||||
| if (!memcmp(&avctx->extradata[4], "APRGAPRG0001", 12) && | |||||
| avctx->extradata_size >= 24) | |||||
| interlaced = avctx->extradata[19] != 1; | |||||
| skip[0] = skip[1] = 16; | |||||
| if (avctx->height == 486) { | |||||
| skip[0] = 8; | |||||
| skip[1] = 12; | |||||
| } | |||||
| if (avpkt->size < avctx->width * (2 * avctx->height + skip[0] + skip[1]) | |||||
| + 4 * interlaced) { | |||||
| av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n"); | av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n"); | ||||
| return AVERROR(EINVAL); | return AVERROR(EINVAL); | ||||
| } | } | ||||
| if (avpkt->size >= 4 * avctx->width * (avctx->height + 16) + 13) | |||||
| transparent = 1; | |||||
| transparent = avctx->bits_per_coded_sample == 32 && | |||||
| avpkt->size >= (2 * avctx->height + skip[0] + skip[1]) * | |||||
| 2 * avctx->width + 4 + 8 * interlaced; | |||||
| srca = src + (2 * avctx->height + skip[0] + skip[1]) * avctx->width | |||||
| + 5 + interlaced * 4; | |||||
| pic->reference = 0; | pic->reference = 0; | ||||
| @@ -65,16 +77,21 @@ static int avui_decode_frame(AVCodecContext *avctx, void *data, | |||||
| pic->key_frame = 1; | pic->key_frame = 1; | ||||
| pic->pict_type = AV_PICTURE_TYPE_I; | pic->pict_type = AV_PICTURE_TYPE_I; | ||||
| for (i = 0; i < 2; i++) { | |||||
| src += avctx->width * 16; | |||||
| srca += avctx->width * 16; | |||||
| if (!interlaced) { | |||||
| src += avctx->width * skip[1]; | |||||
| srca += avctx->width * skip[1]; | |||||
| } | |||||
| for (i = 0; i < interlaced + 1; i++) { | |||||
| src += avctx->width * skip[i]; | |||||
| srca += avctx->width * skip[i]; | |||||
| y = pic->data[0] + i * pic->linesize[0]; | y = pic->data[0] + i * pic->linesize[0]; | ||||
| u = pic->data[1] + i * pic->linesize[1]; | u = pic->data[1] + i * pic->linesize[1]; | ||||
| v = pic->data[2] + i * pic->linesize[2]; | v = pic->data[2] + i * pic->linesize[2]; | ||||
| a = pic->data[3] + i * pic->linesize[3]; | a = pic->data[3] + i * pic->linesize[3]; | ||||
| for (j = 0; j < (avctx->height + 1) >> 1; j++) { | |||||
| for (k = 0; k < (avctx->width + 1) >> 1; k++) { | |||||
| for (j = 0; j < avctx->height >> interlaced; j++) { | |||||
| for (k = 0; k < avctx->width >> 1; k++) { | |||||
| u[ k ] = *src++; | u[ k ] = *src++; | ||||
| y[2 * k ] = *src++; | y[2 * k ] = *src++; | ||||
| a[2 * k ] = 0xFF - (transparent ? *srca++ : 0); | a[2 * k ] = 0xFF - (transparent ? *srca++ : 0); | ||||
| @@ -85,10 +102,10 @@ static int avui_decode_frame(AVCodecContext *avctx, void *data, | |||||
| srca++; | srca++; | ||||
| } | } | ||||
| y += 2 * pic->linesize[0]; | |||||
| u += 2 * pic->linesize[1]; | |||||
| v += 2 * pic->linesize[2]; | |||||
| a += 2 * pic->linesize[3]; | |||||
| y += (interlaced + 1) * pic->linesize[0]; | |||||
| u += (interlaced + 1) * pic->linesize[1]; | |||||
| v += (interlaced + 1) * pic->linesize[2]; | |||||
| a += (interlaced + 1) * pic->linesize[3]; | |||||
| } | } | ||||
| src += 4; | src += 4; | ||||
| srca += 4; | srca += 4; | ||||