#include <stdlib.h>
#include "VapourSynth4.h"
#include "VSHelper4.h"
typedef struct {
VSNode *node;
int enabled;
} InvertData;
static const VSFrame *VS_CC invertGetFrame(int n, int activationReason, void *instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi) {
InvertData *d = (InvertData *)instanceData;
if (activationReason == arInitial) {
vsapi->requestFrameFilter(n, d->node, frameCtx);
} else if (activationReason == arAllFramesReady) {
const VSFrame *src = vsapi->getFrameFilter(n, d->node, frameCtx);
const VSVideoFormat *fi = vsapi->getVideoFrameFormat(src);
int height = vsapi->getFrameHeight(src, 0);
int width = vsapi->getFrameWidth(src, 0);
VSFrame *dst = vsapi->newVideoFrame(fi, width, height, src, core);
int plane;
for (plane = 0; plane < fi->numPlanes; plane++) {
const uint8_t * VS_RESTRICT srcp = vsapi->getReadPtr(src, plane);
ptrdiff_t src_stride = vsapi->getStride(src, plane);
uint8_t * VS_RESTRICT dstp = vsapi->getWritePtr(dst, plane);
ptrdiff_t dst_stride = vsapi->getStride(dst, plane); int h = vsapi->getFrameHeight(src, plane);
int y;
int w = vsapi->getFrameWidth(src, plane);
int x;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++)
dstp[x] = ~srcp[x];
dstp += dst_stride;
srcp += src_stride;
}
}
vsapi->freeFrame(src);
return dst;
}
return NULL;
}
static void VS_CC invertFree(void *instanceData, VSCore *core, const VSAPI *vsapi) {
InvertData *d = (InvertData *)instanceData;
vsapi->freeNode(d->node);
free(d);
}
static void VS_CC invertCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) {
InvertData d;
InvertData *data;
int err;
d.node = vsapi->mapGetNode(in, "clip", 0, 0);
const VSVideoInfo *vi = vsapi->getVideoInfo(d.node);
if (!vsh_isConstantVideoFormat(vi) || vi->format.sampleType != stInteger || vi->format.bitsPerSample != 8) {
vsapi->mapSetError(out, "Invert: only constant format 8bit integer input supported");
vsapi->freeNode(d.node);
return;
}
d.enabled = !!vsapi->mapGetInt(in, "enable", 0, &err);
if (err)
d.enabled = 1;
if (d.enabled < 0 || d.enabled > 1) {
vsapi->mapSetError(out, "Invert: enabled must be 0 or 1");
vsapi->freeNode(d.node);
return;
}
data = (InvertData *)malloc(sizeof(d));
*data = d;
VSFilterDependency deps[] = {{d.node, rpStrictSpatial}};
vsapi->createVideoFilter(out, "Invert", vi, invertGetFrame, invertFree, fmParallel, deps, 1, data, core);
}
VS_EXTERNAL_API(void) VapourSynthPluginInit2(VSPlugin *plugin, const VSPLUGINAPI *vspapi) {
vspapi->configPlugin("com.example.invert", "invert", "VapourSynth Invert Example", VS_MAKE_VERSION(1, 0), VAPOURSYNTH_API_VERSION, 0, plugin);
vspapi->registerFunction("Filter", "clip:vnode;enabled:int:opt;", "clip:vnode;", invertCreate, NULL, plugin);
}