<commit_before>/*
 * VapourSynth D2V Plugin
 *
 * Copyright (c) 2012 <NAME>
 *
 * This file is part of d2vsource.
 *
 * d2vsource is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * d2vsource is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with d2vsource; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

extern "C" {
#include <stdint.h>
#include <stdlib.h>
}

#include <algorithm>

#include <VapourSynth.h>
#include <VSHelper.h>

#include "applyrff.hpp"
#include "d2v.hpp"
#include "gop.hpp"

void VS_CC rffInit(VSMap *in, VSMap *out, void **instanceData, VSNode *node, VSCore *core, const VSAPI *vsapi)
{
    rffData *d = (rffData *) *instanceData;
    vsapi->setVideoInfo(&d->vi, 1, node);
}

const VSFrameRef *VS_CC rffGetFrame(int n, int activationReason, void **instanceData, void **frameData,
                                    VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi)
{
    rffData *d = (rffData *) *instanceData;
    VSFrameRef *st, *sb, *f;
    string msg;
    int top, bottom;
    int dst_stride[3], srct_stride[3], srcb_stride[3];
    int i;
    bool samefields;

    /* What frames to use for fields. */
    top    = d->frames[n].top;
    bottom = d->frames[n].bottom;

    samefields = top == bottom;

    /* Request out source frames. */
    if (activationReason == arInitial) {
        if (samefields) {
            vsapi->requestFrameFilter(top, d->node, frameCtx);
        } else {
            vsapi->requestFrameFilter(min(top, bottom), d->node, frameCtx);
            vsapi->requestFrameFilter(max(top, bottom), d->node, frameCtx);
        }
        return NULL;
    }

    /* Check if we're ready yet. */
    if (activationReason != arAllFramesReady)
        return NULL;

    /* Source and destination frames. */
    st = (VSFrameRef *) vsapi->getFrameFilter(top, d->node, frameCtx);
    sb = samefields ? NULL : (VSFrameRef *) vsapi->getFrameFilter(bottom, d->node, frameCtx);
    f  = vsapi->newVideoFrame(d->vi.format, d->vi.width, d->vi.height, NULL, core);

    /*
     * Set progressive/interlaced flag.
     *
     * This assumes the d2v has been properly run through d2vfix,
     * so that there is only one field order.
     *
     * This is probably wildly wrong. I hope nothign relies on this.
     */
    if (samefields) {
        VSMap *props = vsapi->getFramePropsRW(f);
        frame top_f = d->d2v->frames[top];

        vsapi->propSetInt(props, "_FieldBased",
                          1 + !!(d->d2v->gops[top_f.gop].flags[top_f.offset] & FRAME_FLAG_TFF), paReplace);
    }

    /* Stash our strides for convenience. */
    for(i = 0; i < 3; i++) {
        dst_stride[i]  = vsapi->getStride(f, i);
        srct_stride[i] = vsapi->getStride(st, i);
        srcb_stride[i] = samefields ? 0 : vsapi->getStride(sb, i);
    }

    /* Copy into VS's buffers. */
    if (samefields) {
        /* Luma. */
        vs_bitblt(vsapi->getWritePtr(f, 0), dst_stride[0], vsapi->getWritePtr(st, 0), srct_stride[0],
                  d->vi.width, d->vi.height);

        /* Chroma. */
        vs_bitblt(vsapi->getWritePtr(f, 1), dst_stride[1], vsapi->getWritePtr(st, 1), srct_stride[1],
                  d->vi.width >> d->vi.format->subSamplingW, d->vi.height >> d->vi.format->subSamplingH);
        vs_bitblt(vsapi->getWritePtr(f, 2), dst_stride[2], vsapi->getWritePtr(st, 2), srct_stride[2],
                  d->vi.width >> d->vi.format->subSamplingW, d->vi.height >> d->vi.format->subSamplingH);
    } else {
        /* Luma. */
        vs_bitblt(vsapi->getWritePtr(f, 0), dst_stride[0] * 2,
                  vsapi->getWritePtr(st, 0), srct_stride[0] * 2,
                  d->vi.width, d->vi.height / 2);
        vs_bitblt(vsapi->getWritePtr(f, 0) + dst_stride[0], dst_stride[0] * 2,
                  vsapi->getWritePtr(sb, 0) + srcb_stride[0], srcb_stride[0] * 2,
                  d->vi.width, d->vi.height / 2);

        /* Chroma. */
        vs_bitblt(vsapi->getWritePtr(f, 1), dst_stride[1] * 2,
                  vsapi->getWritePtr(st, 1), srct_stride[1] * 2,
                  d->vi.width >> d->vi.format->subSamplingW, (d->vi.height >> d->vi.format->subSamplingH) / 2);
        vs_bitblt(vsapi->getWritePtr(f, 1) + dst_stride[1], dst_stride[1] * 2,
                  vsapi->getWritePtr(sb, 1) + srcb_stride[1], srcb_stride[1] * 2,
                  d->vi.width >> d->vi.format->subSamplingW, (d->vi.height >> d->vi.format->subSamplingH) / 2);

        vs_bitblt(vsapi->getWritePtr(f, 2), dst_stride[2] * 2,
                  vsapi->getWritePtr(st, 2), srct_stride[2] * 2,
                  d->vi.width >> d->vi.format->subSamplingW, (d->vi.height >> d->vi.format->subSamplingH) / 2);
        vs_bitblt(vsapi->getWritePtr(f, 2) + dst_stride[2], dst_stride[2] * 2,
                  vsapi->getWritePtr(sb, 2) + srcb_stride[2], srcb_stride[2] * 2,
                  d->vi.width >> d->vi.format->subSamplingW, (d->vi.height >> d->vi.format->subSamplingH) / 2);
    }

    vsapi->freeFrame(st);
    if (!samefields)
        vsapi->freeFrame(sb);

    return f;
}

void VS_CC rffFree(void *instanceData, VSCore *core, const VSAPI *vsapi)
{
    rffData *d = (rffData *) instanceData;
    vsapi->freeNode(d->node);
    d2vfreep(&d->d2v);
    d->frames.clear();
    delete d;
}

void VS_CC rffCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi)
{
    rffData *data;
    VSVideoInfo *vi;
    fieldFrame ff = { -1, -1 };
    string msg;
    int total_fields;
    int i;

    /* Allocate our private data. */
    data = new rffData;
    if (!data) {
        vsapi->setError(out, "Cannot allocate private data.");
        return;
    }

    /* Parse the D2V to get flags. */
    data->d2v = d2vparse((char *) vsapi->propGetData(in, "d2v", 0, 0), msg);
    if (!data->d2v) {
        vsapi->setError(out, msg.c_str());
        return;
    }

    /* Get our frame info and copy it, so we can modify it after. */
    data->node = vsapi->propGetNode(in, "clip", 0, 0);
    vi         = (VSVideoInfo *) vsapi->getVideoInfo(data->node);
    data->vi   = *vi;

    /*
     * Parse all the RFF flags to figure out which fields go
     * with which frames, and out total number of frames after
     * apply the RFF flags.
     */
    total_fields = 0;
    data->frames.push_back(ff);
    for(i = 0; i < data->vi.numFrames; i++) {<commit_msg>applyrff: Use nothrow new; avoid leak<commit_after>/*
 * VapourSynth D2V Plugin
 *
 * Copyright (c) 2012 <NAME>
 *
 * This file is part of d2vsource.
 *
 * d2vsource is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * d2vsource is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with d2vsource; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

extern "C" {
#include <stdint.h>
#include <stdlib.h>
}

#include <algorithm>

#include <VapourSynth.h>
#include <VSHelper.h>

#include "applyrff.hpp"
#include "d2v.hpp"
#include "gop.hpp"

void VS_CC rffInit(VSMap *in, VSMap *out, void **instanceData, VSNode *node, VSCore *core, const VSAPI *vsapi)
{
    rffData *d = (rffData *) *instanceData;
    vsapi->setVideoInfo(&d->vi, 1, node);
}

const VSFrameRef *VS_CC rffGetFrame(int n, int activationReason, void **instanceData, void **frameData,
                                    VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi)
{
    rffData *d = (rffData *) *instanceData;
    VSFrameRef *st, *sb, *f;
    string msg;
    int top, bottom;
    int dst_stride[3], srct_stride[3], srcb_stride[3];
    int i;
    bool samefields;

    /* What frames to use for fields. */
    top    = d->frames[n].top;
    bottom = d->frames[n].bottom;

    samefields = top == bottom;

    /* Request out source frames. */
    if (activationReason == arInitial) {
        if (samefields) {
            vsapi->requestFrameFilter(top, d->node, frameCtx);
        } else {
            vsapi->requestFrameFilter(min(top, bottom), d->node, frameCtx);
            vsapi->requestFrameFilter(max(top, bottom), d->node, frameCtx);
        }
        return NULL;
    }

    /* Check if we're ready yet. */
    if (activationReason != arAllFramesReady)
        return NULL;

    /* Source and destination frames. */
    st = (VSFrameRef *) vsapi->getFrameFilter(top, d->node, frameCtx);
    sb = samefields ? NULL : (VSFrameRef *) vsapi->getFrameFilter(bottom, d->node, frameCtx);
    f  = vsapi->newVideoFrame(d->vi.format, d->vi.width, d->vi.height, NULL, core);

    /*
     * Set progressive/interlaced flag.
     *
     * This assumes the d2v has been properly run through d2vfix,
     * so that there is only one field order.
     *
     * This is probably wildly wrong. I hope nothign relies on this.
     */
    if (samefields) {
        VSMap *props = vsapi->getFramePropsRW(f);
        frame top_f = d->d2v->frames[top];

        vsapi->propSetInt(props, "_FieldBased",
                          1 + !!(d->d2v->gops[top_f.gop].flags[top_f.offset] & FRAME_FLAG_TFF), paReplace);
    }

    /* Stash our strides for convenience. */
    for(i = 0; i < 3; i++) {
        dst_stride[i]  = vsapi->getStride(f, i);
        srct_stride[i] = vsapi->getStride(st, i);
        srcb_stride[i] = samefields ? 0 : vsapi->getStride(sb, i);
    }

    /* Copy into VS's buffers. */
    if (samefields) {
        /* Luma. */
        vs_bitblt(vsapi->getWritePtr(f, 0), dst_stride[0], vsapi->getWritePtr(st, 0), srct_stride[0],
                  d->vi.width, d->vi.height);

        /* Chroma. */
        vs_bitblt(vsapi->getWritePtr(f, 1), dst_stride[1], vsapi->getWritePtr(st, 1), srct_stride[1],
                  d->vi.width >> d->vi.format->subSamplingW, d->vi.height >> d->vi.format->subSamplingH);
        vs_bitblt(vsapi->getWritePtr(f, 2), dst_stride[2], vsapi->getWritePtr(st, 2), srct_stride[2],
                  d->vi.width >> d->vi.format->subSamplingW, d->vi.height >> d->vi.format->subSamplingH);
    } else {
        /* Luma. */
        vs_bitblt(vsapi->getWritePtr(f, 0), dst_stride[0] * 2,
                  vsapi->getWritePtr(st, 0), srct_stride[0] * 2,
                  d->vi.width, d->vi.height / 2);
        vs_bitblt(vsapi->getWritePtr(f, 0) + dst_stride[0], dst_stride[0] * 2,
                  vsapi->getWritePtr(sb, 0) + srcb_stride[0], srcb_stride[0] * 2,
                  d->vi.width, d->vi.height / 2);

        /* Chroma. */
        vs_bitblt(vsapi->getWritePtr(f, 1), dst_stride[1] * 2,
                  vsapi->getWritePtr(st, 1), srct_stride[1] * 2,
                  d->vi.width >> d->vi.format->subSamplingW, (d->vi.height >> d->vi.format->subSamplingH) / 2);
        vs_bitblt(vsapi->getWritePtr(f, 1) + dst_stride[1], dst_stride[1] * 2,
                  vsapi->getWritePtr(sb, 1) + srcb_stride[1], srcb_stride[1] * 2,
                  d->vi.width >> d->vi.format->subSamplingW, (d->vi.height >> d->vi.format->subSamplingH) / 2);

        vs_bitblt(vsapi->getWritePtr(f, 2), dst_stride[2] * 2,
                  vsapi->getWritePtr(st, 2), srct_stride[2] * 2,
                  d->vi.width >> d->vi.format->subSamplingW, (d->vi.height >> d->vi.format->subSamplingH) / 2);
        vs_bitblt(vsapi->getWritePtr(f, 2) + dst_stride[2], dst_stride[2] * 2,
                  vsapi->getWritePtr(sb, 2) + srcb_stride[2], srcb_stride[2] * 2,
                  d->vi.width >> d->vi.format->subSamplingW, (d->vi.height >> d->vi.format->subSamplingH) / 2);
    }

    vsapi->freeFrame(st);
    if (!samefields)
        vsapi->freeFrame(sb);

    return f;
}

void VS_CC rffFree(void *instanceData, VSCore *core, const VSAPI *vsapi)
{
    rffData *d = (rffData *) instanceData;
    vsapi->freeNode(d->node);
    d2vfreep(&d->d2v);
    d->frames.clear();
    delete d;
}

void VS_CC rffCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi)
{
    rffData *data;
    VSVideoInfo *vi;
    fieldFrame ff = { -1, -1 };
    string msg;
    int total_fields;
    int i;

    /* Allocate our private data. */
    data = new(nothrow) rffData;
    if (!data) {
        vsapi->setError(out, "Cannot allocate private data.");
        return;
    }

    /* Parse the D2V to get flags. */
    data->d2v = d2vparse((char *) vsapi->propGetData(in, "d2v", 0, 0), msg);
    if (!data->d2v) {
        vsapi->setError(out, msg.c_str());
        delete data;
        return;
    }

    /* Get our frame info and copy it, so we can modify it after. */
    data->node = vsapi->propGetNode(in, "clip", 0, 0);
    vi         = (VSVideoInfo *) vsapi->getVideoInfo(data->node);
    data->vi   = *vi;

    /*
     * Parse all the RFF flags to figure out which fields go
     * with which frames, and out total number of frames after
     * apply the RFF flags.
     */
    total_fields = 0;
    data->frames.push_back(ff);
    for(i = 0; i < data->vi.numFrames; i++) {
{'fraction_non_alphanumeric': 0.14880174291938997, 'fraction_numerical': 0.01597676107480029, 'mean_word_length': 2.511218765935747, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 273, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1949494', 'n_tokens_mistral': 5056, 'n_tokens_neox': 4799, 'n_words': 1211}