// BlendMap 0.1 // Copyright 2004 Carl Ritson // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit // http://www.gnu.org/copyleft/gpl.html . #include "windows.h" #include "avisynth.h" #include // BlendMap class BlendMap : public GenericVideoFilter { public: BlendMap(bool *_frames, int _no_frames, PClip _child, IScriptEnvironment* env); ~BlendMap(); PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env); private: bool *frames; int no_frames; }; BlendMap::BlendMap(bool *_frames, int _no_frames, PClip _child, IScriptEnvironment* env) : GenericVideoFilter(_child) { if (!vi.IsYV12()) env->ThrowError("BlendMap: requires YV12 source"); frames = _frames; no_frames = _no_frames; vi.num_frames = _no_frames; } BlendMap::~BlendMap() { if(frames) delete frames; } PVideoFrame __stdcall BlendMap::GetFrame(int n, IScriptEnvironment* env) { if(!frames[n] || n == 0 || n >= (vi.num_frames-1)) return child->GetFrame(n, env); PVideoFrame s1Frame = child->GetFrame(n-1, env); PVideoFrame tgFrame = child->GetFrame(n, env); PVideoFrame s2Frame = child->GetFrame(n+1, env); env->MakeWritable(&tgFrame); unsigned char *tgPtr,*s1Ptr,*s2Ptr; int row_size,height,h,w; // Y tgPtr = (unsigned char *) tgFrame->GetWritePtr(PLANAR_Y); s1Ptr = (unsigned char *) s1Frame->GetReadPtr(PLANAR_Y); s2Ptr = (unsigned char *) s2Frame->GetReadPtr(PLANAR_Y); row_size = tgFrame->GetRowSize(PLANAR_Y); height = tgFrame->GetHeight(PLANAR_Y); h,w; for(h = 0; h < height; ++h) { unsigned char *tg = tgPtr + (h * row_size); unsigned char *s1 = s1Ptr + (h * row_size); unsigned char *s2 = s2Ptr + (h * row_size); unsigned char *pEnd = tg + row_size; while(tg < pEnd) { *tg = (*s1 + *s2) / 2; tg++; s1++; s2++; } } // U tgPtr = (unsigned char *) tgFrame->GetWritePtr(PLANAR_U); s1Ptr = (unsigned char *) s1Frame->GetReadPtr(PLANAR_U); s2Ptr = (unsigned char *) s2Frame->GetReadPtr(PLANAR_U); row_size = tgFrame->GetRowSize(PLANAR_U); height = tgFrame->GetHeight(PLANAR_U); for(h = 0; h < height; ++h) { unsigned char *tg = tgPtr + (h * row_size); unsigned char *s1 = s1Ptr + (h * row_size); unsigned char *s2 = s2Ptr + (h * row_size); unsigned char *pEnd = tg + row_size; while(tg < pEnd) { *tg = (*s1 + *s2) / 2; tg++; s1++; s2++; } } // V tgPtr = (unsigned char *) tgFrame->GetWritePtr(PLANAR_V); s1Ptr = (unsigned char *) s1Frame->GetReadPtr(PLANAR_V); s2Ptr = (unsigned char *) s2Frame->GetReadPtr(PLANAR_V); row_size = tgFrame->GetRowSize(PLANAR_V); height = tgFrame->GetHeight(PLANAR_V); for(h = 0; h < height; ++h) { unsigned char *tg = tgPtr + (h * row_size); unsigned char *s1 = s1Ptr + (h * row_size); unsigned char *s2 = s2Ptr + (h * row_size); unsigned char *pEnd = tg + row_size; while(tg < pEnd) { *tg = (*s1 + *s2) / 2; tg++; s1++; s2++; } } return tgFrame; } // DLL Handles AVSValue __cdecl Create_BlendMap(AVSValue args, void*, IScriptEnvironment* env) { FILE *fh; bool *frames; int i,no_frames; fh = fopen(args[1].AsString(""),"r"); if(fh == NULL) env->ThrowError("BlendMap: unable to open file"); if(fscanf(fh,"%d\n\n",&no_frames) < 1 || no_frames <= 0) env->ThrowError("BlendMap: error reading map file"); frames = new bool[no_frames]; for(i = 0; i < no_frames; ++i) frames[i] = false; for(i = 0; i < no_frames; ++i) { float val = 0; int ptr = 0; if(fscanf(fh,"%d\t%f\n",&ptr,&val) < 2) env->ThrowError("BlendMap: invalid map file"); if(ptr > 0) { if(!frames[ptr-1] && val == 0.0) frames[ptr] = true; } } fclose(fh); return new BlendMap(frames, no_frames, args[0].AsClip(), env); } extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) { env->AddFunction("BlendMap", "cs", Create_BlendMap, 0); return "BlendMap filter"; }