<commit_before>/*
* Copyright (c) 2012-2016 <NAME>
*
* This file is part of VapourSynth.
*
* VapourSynth 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.
*
* VapourSynth 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 VapourSynth; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "internalfilters.h"
#include "VSHelper.h"
#include "filtershared.h"
#include <stdlib.h>

#define CLAMP(value, lower, upper) min(max(value, lower), upper)

//////////////////////////////////////////
// PreMultiply

typedef struct {
    VSNodeRef *node1;
    VSNodeRef *node2;
    VSNodeRef *node2_23;
    const VSVideoInfo *vi;
} PreMultiplyData;

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

static const VSFrameRef *VS_CC preMultiplyGetFrame(int n, int activationReason, void **instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi) {
    PreMultiplyData *d = (PreMultiplyData *)*instanceData;

    if (activationReason == arInitial) {
        vsapi->requestFrameFilter(n, d->node1, frameCtx);
        vsapi->requestFrameFilter(n, d->node2, frameCtx);
        if (d->node2_23)
            vsapi->requestFrameFilter(n, d->node2_23, frameCtx);
    } else if (activationReason == arAllFramesReady) {
        const VSFrameRef *src1 = vsapi->getFrameFilter(n, d->node1, frameCtx);
        const VSFrameRef *src2 = vsapi->getFrameFilter(n, d->node2, frameCtx);
        const VSFrameRef *src2_23 = 0;
        if (d->node2_23)
            src2_23 = vsapi->getFrameFilter(n, d->node2_23, frameCtx);
        VSFrameRef *dst = vsapi->newVideoFrame(d->vi->format, d->vi->width, d->vi->height, src1, core);
        for (int plane = 0; plane < d->vi->format->numPlanes; plane++) {
            int h = vsapi->getFrameHeight(src1, plane);
            int w = vsapi->getFrameWidth(src1, plane);
            int stride = vsapi->getStride(src1, plane);
            const uint8_t *srcp1 = vsapi->getReadPtr(src1, plane);
            const uint8_t *srcp2 = vsapi->getReadPtr(plane > 0 ? src2_23 : src2, 0);
            uint8_t * VS_RESTRICT dstp = vsapi->getWritePtr(dst, plane);

            if (d->vi->format->sampleType == stInteger) {
                if (d->vi->format->bytesPerSample == 1) {
                    for (int y = 0; y < h; y++) {
                        for (int x = 0; x < w; x++) {
                            unsigned s1 = srcp1[x];
                            unsigned s2 = srcp2[x];
                            dstp[x] = ((s1 * (((s2 >> 1) & 1) + s2)) + 128) >> 8;
                        }
                        srcp1 += stride;
                        srcp2 += stride;
                        dstp += stride;
                    }
                } else if (d->vi->format->bytesPerSample == 2) {
                    const unsigned shift = d->vi->format->bitsPerSample;
                    const unsigned round = 1 << (shift - 1);
                    for (int y = 0; y < h; y++) {
                        for (int x = 0; x < w; x++) {
                            unsigned s1 = srcp1[x];
                            unsigned s2 = srcp2[x];
                            ((uint16_t *)dstp)[x] = ((s1 * (((s2 >> 1) & 1) + s2)) + round) >> shift;
                        }                           
                        srcp1 += stride;
                        srcp2 += stride;
                        dstp += stride;
                    }
                }
            } else if (d->vi->format->sampleType == stFloat) {
                if (d->vi->format->bytesPerSample == 4) {
                    for (int y = 0; y < h; y++) {
                        for (int x = 0; x < w; x++)
                            ((float *)dstp)[x] = ((const float *)srcp1)[x] * ((const float *)srcp2)[x];
                        srcp1 += stride;
                        srcp2 += stride;
                        dstp += stride;
                    }
                }
            }
        }

        vsapi->freeFrame(src1);
        vsapi->freeFrame(src2);
        vsapi->freeFrame(src2_23);
        return dst;
    }

    return 0;
}

static void VS_CC preMultiplyFree(void *instanceData, VSCore *core, const VSAPI *vsapi) {
    PreMultiplyData *d = (PreMultiplyData *)instanceData;
    vsapi->freeNode(d->node1);
    vsapi->freeNode(d->node2);
    vsapi->freeNode(d->node2_23);
    free(d);
}

static void VS_CC preMultiplyCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) {
    PreMultiplyData d;
    PreMultiplyData *data;

    d.node1 = vsapi->propGetNode(in, "clip", 0, 0);
    d.node2 = vsapi->propGetNode(in, "alpha", 0, 0);
    d.node2_23 = 0;

    d.vi = vsapi->getVideoInfo(d.node1);

    if (isCompatFormat(d.vi) || isCompatFormat(vsapi->getVideoInfo(d.node2))) {
        vsapi->freeNode(d.node1);
        vsapi->freeNode(d.node2);
        RETERROR("PreMultiply: compat formats are not supported");
    }

    const VSFormat *alphaformat = vsapi->registerFormat(cmGray, d.vi->format->sampleType, d.vi->format->bitsPerSample, 0, 0, core);
    const VSVideoInfo *alphavi = vsapi->getVideoInfo(d.node2);

    if (alphavi->format != alphaformat) {
        vsapi->freeNode(d.node1);
        vsapi->freeNode(d.node2);
        RETERROR("PreMultiply: alpha clip must be grayscale");
    }

    if (!isConstantFormat(d.vi) || !isConstantFormat(alphavi) || d.vi->width != alphavi->width || d.vi->height != alphavi->height) {
        vsapi->freeNode(d.node1);
        vsapi->freeNode(d.node2);
        RETERROR("PreMultiply: both clips must have constant format and dimensions, and the same dimensions");
    }

    if ((d.vi->format->sampleType == stInteger && d.vi->format->bytesPerSample != 1 && d.vi->format->bytesPerSample != 2)
        || (d.vi->format->sampleType == stFloat && d.vi->format->bytesPerSample != 4)) {
        vsapi->freeNode(d.node1);
        vsapi->freeNode(d.node2);
        RETERROR("PreMultiply: only 8-16 bit integer and 32 bit float input supported");
    }

    // do we need to resample the first mask plane and use it for all the planes?
    if ((d.vi->format->numPlanes > 1) && (d.vi->format->subSamplingH > 0 || d.vi->format->subSamplingW > 0)) {
        VSMap *min = vsapi->createMap();
        vsapi->propSetNode(min, "clip", d.node2, paAppend);
        vsapi->propSetInt(min, "width", d.vi->width >> d.vi->format->subSamplingW, paAppend);
        vsapi->propSetInt(min, "height", d.vi->height >> d.vi->format->subSamplingH, paAppend);
        VSMap *mout = vsapi->invoke(vsapi->getPluginById("com.vapoursynth.resize", core), "Bilinear", min);
        d.node2_23 = vsapi->propGetNode(mout, "clip", 0, 0);
        vsapi->freeMap(mout);
        vsapi->freeMap(min);<commit_msg>Fix bias for YUV in premultiply<commit_after>/*
* Copyright (c) 2012-2016 <NAME>
*
* This file is part of VapourSynth.
*
* VapourSynth 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.
*
* VapourSynth 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 VapourSynth; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "internalfilters.h"
#include "VSHelper.h"
#include "filtershared.h"
#include <stdlib.h>

#define CLAMP(value, lower, upper) min(max(value, lower), upper)

//////////////////////////////////////////
// PreMultiply

typedef struct {
    VSNodeRef *node1;
    VSNodeRef *node2;
    VSNodeRef *node2_23;
    const VSVideoInfo *vi;
} PreMultiplyData;

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

static const VSFrameRef *VS_CC preMultiplyGetFrame(int n, int activationReason, void **instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi) {
    PreMultiplyData *d = (PreMultiplyData *)*instanceData;

    if (activationReason == arInitial) {
        vsapi->requestFrameFilter(n, d->node1, frameCtx);
        vsapi->requestFrameFilter(n, d->node2, frameCtx);
        if (d->node2_23)
            vsapi->requestFrameFilter(n, d->node2_23, frameCtx);
    } else if (activationReason == arAllFramesReady) {
        const VSFrameRef *src1 = vsapi->getFrameFilter(n, d->node1, frameCtx);
        const VSFrameRef *src2 = vsapi->getFrameFilter(n, d->node2, frameCtx);
        const VSFrameRef *src2_23 = 0;
        if (d->node2_23)
            src2_23 = vsapi->getFrameFilter(n, d->node2_23, frameCtx);
        VSFrameRef *dst = vsapi->newVideoFrame(d->vi->format, d->vi->width, d->vi->height, src1, core);
        for (int plane = 0; plane < d->vi->format->numPlanes; plane++) {
            int h = vsapi->getFrameHeight(src1, plane);
            int w = vsapi->getFrameWidth(src1, plane);
            int stride = vsapi->getStride(src1, plane);
            const uint8_t *srcp1 = vsapi->getReadPtr(src1, plane);
            const uint8_t *srcp2 = vsapi->getReadPtr(plane > 0 ? src2_23 : src2, 0);
            uint8_t * VS_RESTRICT dstp = vsapi->getWritePtr(dst, plane);
            int yuvhandling = (plane > 0) && (d->vi->format->colorFamily == cmYUV || d->vi->format->colorFamily == cmYCoCg);

            if (d->vi->format->sampleType == stInteger) {
                if (d->vi->format->bytesPerSample == 1) {
                    if (yuvhandling) {
                        for (int y = 0; y < h; y++) {
                            for (int x = 0; x < w; x++) {
                                uint8_t s1 = srcp1[x];
                                uint8_t s2 = srcp2[x];
                                dstp[x] = ((((s1 - 128) * (((s2 >> 1) & 1) + s2))) >> 8) + 128;
                            }
                            srcp1 += stride;
                            srcp2 += stride;
                            dstp += stride;
                        }
                    } else {
                        for (int y = 0; y < h; y++) {
                            for (int x = 0; x < w; x++) {
                                uint8_t s1 = srcp1[x];
                                uint8_t s2 = srcp2[x];
                                dstp[x] = ((s1 * (((s2 >> 1) & 1) + s2)) + 128) >> 8;
                            }
                            srcp1 += stride;
                            srcp2 += stride;
                            dstp += stride;
                        }
                    }
                } else if (d->vi->format->bytesPerSample == 2) {
                    const unsigned shift = d->vi->format->bitsPerSample;
                    const unsigned halfpoint = 1 << (shift - 1);
                    if (yuvhandling) {
                        for (int y = 0; y < h; y++) {
                            for (int x = 0; x < w; x++) {
                                uint16_t s1 = ((const uint16_t *)srcp1)[x];
                                uint16_t s2 = ((const uint16_t *)srcp2)[x];
                                ((uint16_t *)dstp)[x] = (((s1 - halfpoint) * (((s2 >> 1) & 1) + s2)) >> shift) + halfpoint;
                            }
                            srcp1 += stride;
                            srcp2 += stride;
                            dstp += stride;
                        }
                    } else {
                        for (int y = 0; y < h; y++) {
                            for (int x = 0; x < w; x++) {
                                uint16_t s1 = ((const uint16_t *)srcp1)[x];
                                uint16_t s2 = ((const uint16_t *)srcp2)[x];
                                ((uint16_t *)dstp)[x] = ((s1 * (((s2 >> 1) & 1) + s2)) + halfpoint) >> shift;
                            }
                            srcp1 += stride;
                            srcp2 += stride;
                            dstp += stride;
                        }
                    }
                }
            } else if (d->vi->format->sampleType == stFloat) {
                if (d->vi->format->bytesPerSample == 4) {
                    for (int y = 0; y < h; y++) {
                        for (int x = 0; x < w; x++)
                            ((float *)dstp)[x] = ((const float *)srcp1)[x] * ((const float *)srcp2)[x];
                        srcp1 += stride;
                        srcp2 += stride;
                        dstp += stride;
                    }
                }
            }
        }

        vsapi->freeFrame(src1);
        vsapi->freeFrame(src2);
        vsapi->freeFrame(src2_23);
        return dst;
    }

    return 0;
}

static void VS_CC preMultiplyFree(void *instanceData, VSCore *core, const VSAPI *vsapi) {
    PreMultiplyData *d = (PreMultiplyData *)instanceData;
    vsapi->freeNode(d->node1);
    vsapi->freeNode(d->node2);
    vsapi->freeNode(d->node2_23);
    free(d);
}

static void VS_CC preMultiplyCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) {
    PreMultiplyData d;
    PreMultiplyData *data;

    d.node1 = vsapi->propGetNode(in, "clip", 0, 0);
    d.node2 = vsapi->propGetNode(in, "alpha", 0, 0);
    d.node2_23 = 0;

    d.vi = vsapi->getVideoInfo(d.node1);

    if (isCompatFormat(d.vi) || isCompatFormat(vsapi->getVideoInfo(d.node2))) {
        vsapi->freeNode(d.node1);
        vsapi->freeNode(d.node2);
        RETERROR("PreMultiply: compat formats are not supported");
    }

    const VSFormat *alphaformat = vsapi->registerFormat(cmGray, d.vi->format->sampleType, d.vi->format->bitsPerSample, 0, 0, core);
    const VSVideoInfo *alphavi = vsapi->getVideoInfo(d.node2);

    if (alphavi->format != alphaformat) {
        vsapi->freeNode(d.node1);
        vsapi->freeNode(d.node2);
        RETERROR("PreMultiply: alpha clip must be grayscale and same sample format and bitdepth as main clip");
    }

    if (!isConstantFormat(d.vi) || !isConstantFormat(alphavi) || d.vi->width != alphavi->width || d.vi->height != alphavi->height) {
        vsapi->freeNode(d.node1);
        vsapi->freeNode(d.node2);
        RETERROR("PreMultiply: both clips must have constant format and dimensions, and the same dimensions");
    }

    if ((d.vi->format->sampleType == stInteger && d.vi->format->bytesPerSample != 1 && d.vi->format->bytesPerSample != 2)
        || (d.vi->format->sampleType == stFloat && d.vi->format->bytesPerSample != 4)) {
        vsapi->freeNode(d.node1);
        vsapi->freeNode(d.node2);
        RETERROR("PreMultiply: only 8-16 bit integer and 32 bit float input supported");
    }

    // do we need to resample the first mask plane and use it for all the planes?
    if ((d.vi->format->numPlanes > 1) && (d.vi->format->subSamplingH > 0 || d.vi->format->subSamplingW > 0)) {
        VSMap *min = vsapi->createMap();
        vsapi->propSetNode(min, "clip", d.node2, paAppend);
        vsapi->propSetInt(min, "width", d.vi->width >> d.vi->format->subSamplingW, paAppend);
        vsapi->propSetInt(min, "height", d.vi->height >> d.vi->format->subSamplingH, paAppend);
        VSMap *mout = vsapi->invoke(vsapi->getPluginById("com.vapoursynth.resize", core), "Bilinear", min);
        d.node2_23 = vsapi->propGetNode(mout, "clip", 0, 0);
        vsapi->freeMap(mout);
        vsapi->freeMap(min);
{'fraction_non_alphanumeric': 0.1410971498620901, 'fraction_numerical': 0.023414036163040147, 'mean_word_length': 1.9037195230468056, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 280, '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': '7284965', 'n_tokens_mistral': 5421, 'n_tokens_neox': 5037, 'n_words': 1302}