+ return ret;
+ }
+ }
+ break;
+ case 3:
+ case 5:
+ /* Virtually the same as version 4, but is for RGB24 */
+ planes = 3;
+ if ((ret = ff_reget_buffer(avctx, f)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
+ return ret;
+ }
+ /* skip frame */
+ if (buf_size == 8) {
+ f->pict_type = AV_PICTURE_TYPE_P;
+ f->key_frame = 0;
+ break;
+ }
+ f->pict_type = AV_PICTURE_TYPE_I;
+ f->key_frame = 1;
+ if ((AV_RL32(buf) != FPS_TAG)||(buf_size < (planes*1024 + 24))) {
+ av_log(avctx, AV_LOG_ERROR, "Fraps: error in data stream\n");
+ return AVERROR_INVALIDDATA;
+ }
+ for (i = 0; i < planes; i++) {
+ offs[i] = AV_RL32(buf + 4 + i * 4);
+ if (offs[i] >= buf_size || (i && offs[i] <= offs[i - 1] + 1024)) {
+ av_log(avctx, AV_LOG_ERROR, "Fraps: plane %i offset is out of bounds\n", i);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ offs[planes] = buf_size;
+ for (i = 0; i < planes; i++) {
+ av_fast_padded_malloc(&s->tmpbuf, &s->tmpbuf_size,
+ offs[i + 1] - offs[i] - 1024);
+ if (!s->tmpbuf)
+ return AVERROR(ENOMEM);
+ if ((ret = fraps2_decode_plane(s, f->data[0] + i + (f->linesize[0] * (avctx->height - 1)),
+ -f->linesize[0], avctx->width, avctx->height,
+ buf + offs[i], offs[i + 1] - offs[i], 0, 3)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i);
+ return ret;
+ }
+ }
+ // convert pseudo-YUV into real RGB
+ for (j = 0; j < avctx->height; j++) {
+ for (i = 0; i < avctx->width; i++) {
+ f->data[0][0 + i*3 + j*f->linesize[0]] += f->data[0][1 + i*3 + j*f->linesize[0]];
+ f->data[0][2 + i*3 + j*f->linesize[0]] += f->data[0][1 + i*3 + j*f->linesize[0]];