Filter SDK/CMerge
From Avisynth wiki
(Difference between revisions)
(added Merge) |
Revision as of 00:00, 29 December 2016
#include "avisynth_c.h"
#include <stdlib.h> // free, malloc
typedef struct Merge {
AVS_Clip* clip2;
double weight;
} Merge;
AVS_VideoFrame* AVSC_CC Merge_get_frame(AVS_FilterInfo* fi, int n)
{
Merge* params = (Merge*) fi->user_data;
AVS_VideoFrame* src = avs_get_frame(fi->child, n);
const BYTE* srcp = avs_get_read_ptr(src);
int src_pitch = avs_get_pitch(src);
AVS_VideoFrame* src2 = avs_get_frame(params->clip2, n);
const BYTE* srcp2 = avs_get_read_ptr(src2);
int src2_pitch = avs_get_pitch(src2);
AVS_VideoFrame* dst = avs_new_video_frame(fi->env, &fi->vi);
BYTE* dstp = avs_get_write_ptr(dst);
int dst_pitch = avs_get_pitch(dst);
int dst_rowsize = avs_get_row_size(dst); // in bytes!
int dst_height = avs_get_height(dst);
int x, y, ch_tot;
double w;
if (avs_is_rgb32(&fi->vi))
ch_tot = 4;
else // rgb24
ch_tot = 3;
w = params->weight;
for (y=0; y<dst_height; ++y) {
for (x=0; x<dst_rowsize; x+=ch_tot) {
dstp[x] = (int)((1-w)*srcp[x] + w*srcp2[x]+0.5); // B
dstp[x+1] = (int)((1-w)*srcp[x+1] + w*srcp2[x+1]+0.5); // G
dstp[x+2] = (int)((1-w)*srcp[x+2] + w*srcp2[x+2]+0.5); // R
}
srcp += src_pitch;
srcp2 += src2_pitch;
dstp += dst_pitch;
}
avs_release_frame(src);
avs_release_frame(src2);
return dst;
}
void AVSC_CC free_Merge(AVS_FilterInfo* fi)
{
Merge* params = (Merge*) fi->user_data;
avs_release_clip(params->clip2);
free(params);
}
AVS_Value AVSC_CC create_Merge(AVS_ScriptEnvironment* env, AVS_Value args, void* user_data)
{
AVS_Value v;
AVS_Value tmp;
AVS_FilterInfo* fi;
const AVS_VideoInfo* vi2;
AVS_Clip* new_clip = avs_new_c_filter(env, &fi, avs_array_elt(args, 0), 1);
Merge *params = (Merge*)malloc(sizeof(Merge));
if (!params)
return avs_void;
if (!avs_is_rgb(&fi->vi)) {
return avs_new_value_error("Input video must be in RGB format!");
}
tmp = avs_array_elt(args, 1);
if (avs_defined(tmp)) {
params->clip2 = avs_take_clip(tmp, env);
vi2 = avs_get_video_info(params->clip2);
if (!avs_has_video(vi2)) {
return avs_new_value_error("Second clip must be a video clip!");
}
else if (!avs_is_color_space(vi2, fi->vi.pixel_type))
{
return avs_new_value_error("Second video must have the same pixel-type as the first clip!");
}
else if (vi2->width != fi->vi.width || vi2->height != fi->vi.height)
{
return avs_new_value_error("Input and second clip sizes must match!");
}
} else {
return avs_new_value_error("Second clip is missing!");
}
tmp = avs_array_elt(args, 2);
if (avs_defined(tmp)) {
params->weight = avs_as_float(tmp);
if ((params->weight<0.0f) || (params->weight>1.0f)) {
return avs_new_value_error("Make sure that '0.0 <= weight <= 1.0'!");
}
} else {
params->weight = 0.5; // default value
}
fi->user_data = (void*) params;
fi->get_frame = Merge_get_frame;
fi->free_filter = free_Merge;
v = avs_new_value_clip(new_clip);
avs_release_clip(new_clip);
return v;
}
const char* AVSC_CC avisynth_c_plugin_init(AVS_ScriptEnvironment* env)
{
avs_add_function(env, "Merge", "cc[weight]f", create_Merge, 0);
return "Merge sample C plugin";
}