Skip to content

Commit 350faea

Browse files
committed
Add missing files - Part 2
1 parent 377e8f0 commit 350faea

File tree

3 files changed

+893
-2
lines changed

3 files changed

+893
-2
lines changed

Circles.cpp

Lines changed: 345 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,345 @@
1+
/******************************************************************************
2+
Circles filter plugin for Vapoursynth+ 32/64 bit version
3+
Circles draws concentric circles with given origin coordinates and marks in bold specified diameter.
4+
Thread agnostic (operates under multi thread mode)
5+
Author V.C.Mohan
6+
7+
10 Sep 2021
8+
Copyright (C) <2021> <V.C.Mohan>
9+
10+
This program is free software: you can redistribute it and/or modify
11+
it under the terms of the GNU General Public License as published by
12+
the Free Software Foundation, version 3 of the License.
13+
14+
This program is distributed in the hope that it will be useful,
15+
but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
GNU General Public License for more details.
18+
19+
A copy of the GNU General Public License is at
20+
see <http://www.gnu.org/licenses/>.
21+
22+
For details of how to contact author see <http://www.avisynth.nl/users/vcmohan/vcmohan.html>
23+
24+
25+
********************************************************************************/
26+
27+
//#include "windows.h"
28+
//#include <stdint.h>const finc* sp,
29+
// #define _USE_MATH_DEFINES
30+
//#include "math.h"
31+
//#include "InterpolationPack.h"
32+
//
33+
//#include "VapourSynth.h"
34+
//
35+
36+
//-------------------------------------------------------------------------
37+
typedef struct {
38+
VSNodeRef* node;
39+
const VSVideoInfo* vi;
40+
41+
// circles origin coordinates
42+
int origin_y;
43+
int origin_x;
44+
int dots; // dot density 1 for 16, 2 for 12, 3 for 8, 4 for 4.
45+
float dim; // imaged dimmed to this level
46+
int fdia; // circle with this diameter will be high lighted
47+
int cint; // interval between circles
48+
int ddensity; // pixel interval of dots of
49+
unsigned char col[16]; // color components for fill
50+
unsigned char bgr[3];
51+
} CirclesData;
52+
53+
54+
55+
56+
/*--------------------------------------------------
57+
* The following is the implementation
58+
* of the defined functions.
59+
--------------------------------------------------*/
60+
//Here is the acutal constructor code used
61+
62+
static void VS_CC circlesInit(VSMap* in, VSMap* out, void** instanceData, VSNode* node, VSCore* core, const VSAPI* vsapi)
63+
{
64+
CirclesData* d = (CirclesData*)*instanceData;
65+
vsapi->setVideoInfo(d->vi, 1, node);
66+
67+
int ht = d->vi->height;
68+
int wd = d->vi->width;
69+
const VSFormat* fi = d->vi->format;
70+
int nbytes = fi->bytesPerSample;
71+
int nbits = fi->bitsPerSample;
72+
73+
d->ddensity = (5 - d->dots) * 16;
74+
//uint8_t bgr[] = { 0,0,0 };
75+
uint8_t yuv[3];
76+
BGR8_YUV(yuv, d->bgr, 8);
77+
uint8_t* bgr = d->bgr;
78+
79+
for (int k = 0; k < 3; k++)
80+
{
81+
if (nbytes == 1)
82+
{
83+
if (fi->colorFamily == cmRGB)
84+
d->col[k] = bgr[k];
85+
else
86+
d->col[k] = yuv[k];
87+
}
88+
else if (nbytes == 2)
89+
{
90+
if (fi->colorFamily == cmRGB)
91+
*((uint16_t*)d->col + k) = (uint16_t)(bgr[k] << (nbits - 8));
92+
else
93+
*((uint16_t*)d->col + k) = (uint16_t)(yuv[k] << (nbits - 8));
94+
}
95+
else // float
96+
{
97+
if (fi->colorFamily == cmRGB)
98+
*((float*)d->col + k) = (float)(bgr[k] / 255.0f);
99+
else
100+
{
101+
if (k == 0)
102+
*((float*)d->col + k) = (float)((yuv[k] - 16) / 220.0f);
103+
else
104+
*((float*)d->col + k) = (float)((yuv[k] - 128) / 220.0f);
105+
}
106+
}
107+
108+
}
109+
}
110+
111+
//------------------------------------------------------------------------------------------------
112+
113+
static const VSFrameRef* VS_CC circlesGetFrame(int n, int activationReason, void** instanceData,
114+
void** frameData, VSFrameContext* frameCtx, VSCore* core, const VSAPI* vsapi)
115+
{
116+
CirclesData* d = (CirclesData*)*instanceData;
117+
118+
if (activationReason == arInitial)
119+
{
120+
vsapi->requestFrameFilter(n, d->node, frameCtx);
121+
}
122+
else if (activationReason == arAllFramesReady)
123+
{
124+
const VSFrameRef* src = vsapi->getFrameFilter(n, d->node, frameCtx);
125+
VSFrameRef* dst;
126+
const VSFormat* fi = d->vi->format;
127+
int height = vsapi->getFrameHeight(src, 0);
128+
int width = vsapi->getFrameWidth(src, 0);
129+
int nbits = fi->bitsPerSample;
130+
int nbytes = fi->bytesPerSample;
131+
//will not process A plane
132+
int np = fi->numPlanes > 3 ? 3 : fi->numPlanes;
133+
134+
int kb = 1;
135+
136+
// get src on which dots will be overlain
137+
dst = vsapi->copyFrame(src, core);
138+
139+
int frsq = d->fdia * d->fdia / 4;
140+
141+
for (int p = 0; p < np; p++)
142+
{
143+
144+
const uint8_t* sp = vsapi->getReadPtr(src, p);
145+
uint8_t* dp = vsapi->getWritePtr(dst, p);
146+
int pitch = vsapi->getStride(src, p) / nbytes;
147+
148+
if ( fi->colorFamily == cmRGB)
149+
{
150+
if (nbytes == 1)
151+
dimplaneRGB(dp,sp, pitch, width, height, d->dim);
152+
else if (nbytes == 2)
153+
dimplaneRGB((uint16_t*)dp, (uint16_t*)sp, pitch, width, height, d->dim);
154+
else if (nbytes == 4)
155+
dimplaneRGB((float*)dp, (float *)sp, pitch, width, height, d->dim);
156+
}
157+
else if (p == 0 && fi->colorFamily == cmYUV)
158+
{
159+
if (nbytes == 1)
160+
{
161+
uint8_t limit = 16;
162+
dimplaneYUV(dp, sp, pitch, width, height, d->dim, limit);
163+
}
164+
else if (nbytes == 2)
165+
{
166+
uint16_t limit = (uint16_t)(16 << (nbits - 8));
167+
dimplaneYUV((uint16_t*)dp, (uint16_t*)sp, pitch, width, height, d->dim, limit);
168+
}
169+
else if (nbytes == 4)
170+
{
171+
float limit = 0.0f;
172+
dimplaneYUV((float*)dp, (float*)sp, pitch, width, height, d->dim, limit);
173+
}
174+
}
175+
int fdmax = VSMAX(VSMAX(abs(d->origin_y - height), abs(d->origin_y)), VSMAX(abs(d->origin_x - width), abs(d->origin_x))) ;
176+
// draw concentric circles
177+
for (int fd = 0; fd <= fdmax; fd += d->cint)
178+
{
179+
int inc = fd == 0 ? 1 : 6 - d->dots;
180+
int frad = fd == 0 ? d->fdia / 2 : fd;
181+
182+
for (int alfa = 1; alfa < 90; alfa += inc)
183+
{
184+
double cosalfa = cos(alfa * M_PI / 180);
185+
double sinalfa = sin(alfa * M_PI / 180);
186+
187+
int x = (int)(frad * cosalfa);
188+
int y = (int)(frad * sinalfa);
189+
190+
for (int i = -1; i < 2; i += 2)
191+
{
192+
for (int j = -1; j < 2; j += 2)
193+
{
194+
int w = d->origin_x + x * j;
195+
int h = d->origin_y + y * i;
196+
if (w >= 0 && w < width && h >= 0 && h < height)
197+
{
198+
if (nbytes == 1)
199+
*(dp + h * pitch + w) = d->col[p];
200+
201+
else if (nbytes == 2)
202+
*((uint16_t*)dp + h * pitch + w) = *((uint16_t*)d->col + p);
203+
else if (nbytes == 4)
204+
*((float*)dp + h * pitch + w) = *((float*)d->col + p);
205+
}
206+
}
207+
}
208+
}
209+
}
210+
211+
}
212+
vsapi->freeFrame(src);
213+
return dst;
214+
}
215+
return 0;
216+
}
217+
218+
/***************************************************************/
219+
static void VS_CC circlesFree(void* instanceData, VSCore* core, const VSAPI* vsapi)
220+
{
221+
CirclesData* d = (CirclesData*)instanceData;
222+
vsapi->freeNode(d->node);
223+
224+
free(d);
225+
}
226+
227+
static void VS_CC circlesCreate(const VSMap* in, VSMap* out, void* userData,
228+
VSCore* core, const VSAPI* vsapi)
229+
{
230+
CirclesData d;
231+
CirclesData* data;
232+
int err;
233+
int temp;
234+
235+
// Get a clip reference from the input arguments. This must be freed later.
236+
d.node = vsapi->propGetNode(in, "clip", 0, 0);
237+
d.vi = vsapi->getVideoInfo(d.node);
238+
239+
// In this first version we only want to handle 8bit integer formats. Note that
240+
// vi->format can be 0 if the input clip can change format midstream.
241+
if (!isConstantFormat(d.vi) || d.vi->width == 0 || d.vi->height == 0
242+
|| (d.vi->format->colorFamily != cmYUV && d.vi->format->colorFamily != cmGray
243+
&& d.vi->format->colorFamily != cmRGB))
244+
{
245+
vsapi->setError(out, "Circles: only RGB, Yuv or Gray color constant formats and const frame dimensions input supported");
246+
vsapi->freeNode(d.node);
247+
return;
248+
}
249+
250+
251+
if (d.vi->format->sampleType == stFloat && d.vi->format->bitsPerSample == 16)
252+
{
253+
vsapi->setError(out, "Circles: half float input not allowed.");
254+
vsapi->freeNode(d.node);
255+
return;
256+
}
257+
258+
// If a property read fails for some reason (index out of bounds/wrong type)
259+
// then err will have flags set to indicate why and 0 will be returned. This
260+
// can be very useful to know when having optional arguments. Since we have
261+
// strict checking because of what we wrote in the argument string, the only
262+
// reason this could fail is when the value wasn't set by the user.
263+
// And when it's not set we want it to default to enabled.
264+
265+
d.origin_x = int64ToIntS(vsapi->propGetInt(in, "xo", 0, &err));
266+
if (err)
267+
d.origin_x = d.vi->width / 2;
268+
269+
d.origin_y = int64ToIntS(vsapi->propGetInt(in, "yo", 0, &err));
270+
if (err)
271+
d.origin_y = d.vi->height / 2;
272+
273+
d.fdia = int64ToIntS(vsapi->propGetInt(in, "frad", 0, &err)) * 2;
274+
if (err)
275+
d.fdia = (d.vi->height > d.vi->width ? d.vi->width : d.vi->height) * 2;
276+
277+
else if (d.fdia < 128 )
278+
{
279+
vsapi->setError(out, "Circles: frad must be at least 64 ");
280+
vsapi->freeNode(d.node);
281+
return;
282+
}
283+
if ( (d.origin_x + d.fdia < 0 || d.origin_x - d.fdia > d.vi->width)
284+
|| (d.origin_y + d.fdia < 0 || d.origin_y - d.fdia > d.vi->height))
285+
{
286+
vsapi->setError(out, "Circles: fdia and origin takes the fisheye image outside frame ");
287+
vsapi->freeNode(d.node);
288+
return;
289+
}
290+
d.cint = int64ToIntS(vsapi->propGetInt(in, "cint", 0, &err));
291+
if (err)
292+
d.cint = 50;
293+
294+
else if (d.cint < 10 || d.cint > VSMAX(d.vi->width, d.vi->height) / 2 )
295+
{
296+
vsapi->setError(out, "Circles: cint must be at least 10 and not more than half of max dimension of frame");
297+
vsapi->freeNode(d.node);
298+
return;
299+
}
300+
301+
d.dots = int64ToIntS(vsapi->propGetInt(in, "dots", 0, &err));
302+
if (err)
303+
d.dots = 2;
304+
else if (d.dots < 1 || d.dots > 4)
305+
{
306+
vsapi->setError(out, "Circles: dots must be 1 to 4 only ");
307+
vsapi->freeNode(d.node);
308+
return;
309+
}
310+
311+
d.dim = (float)(1.0 - vsapi->propGetFloat(in, "dim", 0, &err));
312+
if (err)
313+
d.dim = 0.25f;
314+
if (d.dim < 0.0f || d.dim > 1.0f)
315+
{
316+
vsapi->setError(out, "Circles: dim must be from 0 to 1.0 only ");
317+
vsapi->freeNode(d.node);
318+
return;
319+
}
320+
for (int i = 0; i < 3; i++)
321+
{
322+
temp = int64ToIntS(vsapi->propGetInt(in, "rgb", 0, &err));
323+
if (err)
324+
d.bgr[2 - i] = (uint8_t)255;
325+
else if (temp < 0 || temp > 255)
326+
{
327+
vsapi->setError(out, "Circles: rgb array values must be from 0 to 255 only ");
328+
vsapi->freeNode(d.node);
329+
return;
330+
}
331+
else d.bgr[2 - i] = (uint8_t)temp;
332+
}
333+
334+
// I usually keep the filter data struct on the stack and don't allocate it
335+
// until all the input validation is done.
336+
data = (CirclesData*)malloc(sizeof(d));
337+
*data = d;
338+
339+
vsapi->createFilter(in, out, "Circles", circlesInit, circlesGetFrame, circlesFree, fmParallel, 0, data, core);
340+
341+
}
342+
343+
// registerFunc("Circles", "clip:clip;xo:int:opt;yo:int:opt;fdia:int:opt;cint:int:opt;dots:int:opt;rgb:int[]:opt;dim:float:opt;", circlesCreate, 0, plugin);
344+
345+

0 commit comments

Comments
 (0)