#include "stdafx.h" #include "resource.h" #include "Filter.h" #include "Filter_AviUtl.h" #include "Common.h" #include "MyFilterData.h" #include "ScriptInterpreter.h" #include "ScriptError.h" #include "ScriptValue.h" #include "ConfigDlg.h" /////////////////////////////////////////////////////////////////////////// int VDInitProc(FilterActivation *fa, const FilterFunctions *ff); void VDDeinitProc(FilterActivation *fa, const FilterFunctions *ff); int VDRunProc(const FilterActivation *fa, const FilterFunctions *ff); int VDStartProc(FilterActivation *fa, const FilterFunctions *ff); int VDEndProc(FilterActivation *fa, const FilterFunctions *ff); long VDParamProc(FilterActivation *fa, const FilterFunctions *ff); int VDConfigProc(FilterActivation *fa, const FilterFunctions *ff, HWND hwnd); void VDStringProc(const FilterActivation *fa, const FilterFunctions *ff, char *str); bool VDFssProc(FilterActivation *fa, const FilterFunctions *ff, char *buf, int buflen); void VDScriptConfig(IScriptInterpreter *isi, void *lpVoid, CScriptValue *argv, int argc); /////////////////////////////////////////////////////////////////////////// ScriptFunctionDef VD_func_defs[]={ { (ScriptFunctionPtr)VDScriptConfig, "Config", "0ii" }, { (ScriptFunctionPtr)VDScriptConfig, "Config", "0" }, { NULL }, }; CScriptObject VD_obj={ NULL, VD_func_defs }; struct FilterDefinition filterDef_VD = { NULL, NULL, NULL, // next, prev, module "Picfix 1.04", // name "Picture stablizer for better compression.", // desc "Gabest", // maker NULL, // private_data sizeof(MyFilterData), // inst_data_size VDInitProc, // initProc VDDeinitProc, // deinitProc VDRunProc, // runProc VDParamProc, // paramProc VDConfigProc, // configProc VDStringProc, // stringProc VDStartProc, // startProc VDEndProc, // endProc &VD_obj, // script_obj VDFssProc, // fssProc }; /////////////////////////////////////////////////////////////////////////// extern "C" int __declspec(dllexport) __cdecl VirtualdubFilterModuleInit2(FilterModule *fm, const FilterFunctions *ff, int& vdfd_ver, int& vdfd_compat); extern "C" void __declspec(dllexport) __cdecl VirtualdubFilterModuleDeinit(FilterModule *fm, const FilterFunctions *ff); static FilterDefinition *fd_VD; HMODULE g_hInst; /////////////////////////////////////////////////////////////////////////// int __declspec(dllexport) __cdecl VirtualdubFilterModuleInit2(FilterModule *fm, const FilterFunctions *ff, int& vdfd_ver, int& vdfd_compat) { if(!(fd_VD = ff->addFilter(fm, &filterDef_VD, sizeof(FilterDefinition)))) return 1; g_hInst = fm->hInstModule; vdfd_ver = VIRTUALDUB_FILTERDEF_VERSION; vdfd_compat = VIRTUALDUB_FILTERDEF_COMPATIBLE; return 0; } void __declspec(dllexport) __cdecl VirtualdubFilterModuleDeinit(FilterModule *fm, const FilterFunctions *ff) { ff->removeFilter(fd_VD); } /////////////////////////////////////////////////////////////////////////// __forceinline void ProcessRow(MyPixel* pix, uchar* dst, uchar* end, int dstadd, int delta, int quality) { quality = 1 << quality; uint t, c; uchar dc; for(; dst < end; dst += dstadd, pix++) { for(int x = 0; x < 3; x++) { if(abs(dst[x] - pix->c[x]) >= delta) { pix->n[x] = 1; pix->t[x] = pix->c[x] = dst[x]; pix->dc[x] = 0xff; continue; } t = pix->t[x] + dst[x]; c = (t<<4) / (pix->n[x]+1); dc = abs(c - (pix->c[x]<<4)); if(dc <= quality || dc <= pix->dc[x]) { pix->n[x]++; pix->t[x] = t; pix->c[x] = c>>4; pix->dc[x] = dc; dst[x] = c>>4; } else { pix->n[x] = 1; pix->t[x] = pix->c[x] = dst[x]; pix->dc[x] = 0xff; } } } } /////////////////////////////////////////////////////////////////////////// static bool g_MMXenabled; int VDInitProc(FilterActivation *fa, const FilterFunctions *ff) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); MyFilterData* mfd = (MyFilterData *)fa->filter_data; mfd->img = NULL; mfd->size = CSize(0, 0); mfd->threshold = DEF_THRESHOLD; mfd->quality = DEF_QUALITY; mfd->lastframe = -1; if(AfxGetApp()->GetProfileInt("Config", "LoadSettingsOnNextRun", 0)) { mfd->threshold = AfxGetApp()->GetProfileInt("Config", "Threshold", DEF_THRESHOLD); mfd->quality = AfxGetApp()->GetProfileInt("Config", "Quality", DEF_QUALITY); } return(0); } void VDDeinitProc(FilterActivation *fa, const FilterFunctions *ff) { MyFilterData *mfd = (MyFilterData *)fa->filter_data; if(mfd->img) delete [] mfd->img; } int VDStartProc(FilterActivation *fa, const FilterFunctions *ff) { MyFilterData *mfd = (MyFilterData *)fa->filter_data; g_MMXenabled = ff->isMMXEnabled(); if(mfd->size != CSize(fa->src.w, fa->src.h)) { if(mfd->img) delete [] mfd->img; mfd->img = new MyPixel[fa->src.w * fa->src.h]; if(!mfd->img) return(1); mfd->size = CSize(fa->src.w, fa->src.h); memset(mfd->img, 0, sizeof(MyPixel) * fa->src.w * fa->src.h); } return(0); } int VDRunProc(const FilterActivation *fa, const FilterFunctions *ff) { MyFilterData *mfd = (MyFilterData *)fa->filter_data; if(mfd->lastframe > fa->pfsi->lCurrentFrame) { memset(mfd->img, 0, sizeof(MyPixel) * fa->src.w * fa->src.h); } mfd->lastframe = fa->pfsi->lCurrentFrame; for(int y = 0; y < fa->src.h; y++) { uchar* dst = (uchar*)fa->src.Address32(0, y); ProcessRow(mfd->img + fa->src.w*y, dst, dst + (fa->src.w<<2), 4, mfd->threshold, mfd->quality); } return 0; } int VDEndProc(FilterActivation *fa, const FilterFunctions *ff) { MyFilterData *mfd = (MyFilterData *)fa->filter_data; return 0; } long VDParamProc(FilterActivation *fa, const FilterFunctions *ff) { MyFilterData *mfd = (MyFilterData *)fa->filter_data; // fa->dst.dwFlags = VFBitmap::NEEDS_HDC; fa->dst.offset = fa->src.offset; fa->dst.modulo = fa->src.modulo; fa->dst.pitch = fa->src.pitch; return 0/*FILTERPARAM_NEEDS_LAST*/; } int VDConfigProc(FilterActivation *fa, const FilterFunctions *ff, HWND hwnd) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); MyFilterData *mfd = (MyFilterData *)fa->filter_data; CConfigDlg dlg(mfd->threshold, mfd->quality); return(dlg.DoModal() == IDOK ? mfd->threshold = dlg.m_threshold, mfd->quality = dlg.m_quality, 0 : 1); } void VDStringProc(const FilterActivation *fa, const FilterFunctions *ff, char *str) { MyFilterData *mfd = (MyFilterData *)fa->filter_data; sprintf(str, " (threshold: %i, quality: %i)", mfd->threshold, mfd->quality); } bool VDFssProc(FilterActivation *fa, const FilterFunctions *ff, char *buf, int buflen) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); MyFilterData *mfd = (MyFilterData *)fa->filter_data; _snprintf(buf, buflen, "Config(%d, %d)", mfd->threshold, mfd->quality); return true; } void VDScriptConfig(IScriptInterpreter *isi, void *lpVoid, CScriptValue *argv, int argc) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); FilterActivation *fa = (FilterActivation *)lpVoid; MyFilterData *mfd = (MyFilterData *)fa->filter_data; mfd->img = NULL; mfd->size = CSize(0, 0); mfd->threshold = 0; mfd->quality = 0; mfd->lastframe = -1; if(argc == 2) { mfd->threshold = argv[0].asInt(); mfd->quality = argv[1].asInt(); } } //////////////////////////////// AviUtl ///////////////////////////////////// // Nasty workaround... #define CHECK_N 1 char *check_name[] = {"Configure..."}; int check_default[] = {0}; FILTER_DLL filter_aviutl = { FILTER_FLAG_EX_INFORMATION|FILTER_FLAG_CONFIG_CHECK|FILTER_FLAG_CONFIG_POPUP, // FILTER_FLAG_EX_INFORMATION // FILTER_FLAG_ALWAYS_ACTIVE // FILTER_FLAG_CONFIG_POPUP // FILTER_FLAG_CONFIG_CHECK // FILTER_FLAG_CONFIG_RADIO // FILTER_FLAG_EX_DATA // FILTER_FLAG_PRIORITY_HIGHEST // FILTER_FLAG_PRIORITY_LOWEST // FILTER_FLAG_WINDOW_THICKFRAME // FILTER_FLAG_WINDOW_SIZE // FILTER_FLAG_DISP_FILTER // FILTER_FLAG_EX_INFORMATION // FILTER_FLAG_NO_CONFIG // FILTER_FLAG_AUDIO_FILTER // FILTER_FLAG_RADIO_BUTTON // FILTER_FLAG_WINDOW_HSCROLL // FILTER_FLAG_WINDOW_VSCROLL // FILTER_FLAG_IMPORT // FILTER_FLAG_EXPORT 0,0, // (FILTER_FLAG_WINDOW_SIZE) "Picfix 1.04", 0, NULL, NULL, NULL, NULL, CHECK_N, check_name, check_default, func_proc, func_init, func_exit, func_update, NULL, NULL, NULL, NULL, sizeof(MyFilterData), "Version 1.04 by Gabest", // (FILTER_FLAG_EX_INFORMATION) NULL, NULL, }; extern "C" FILTER_DLL __declspec(dllexport) * __cdecl GetFilterTable(void) { return &filter_aviutl; } BOOL func_init(FILTER *fp) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); MyFilterData *mfd = new MyFilterData; //(MyFilterData *)fp->ex_data_ptr; if(!mfd) return(FALSE); memset(mfd, 0, sizeof(MyFilterData)); fp->ex_data_ptr = mfd; mfd->img = NULL; mfd->size = CSize(0, 0); mfd->threshold = DEF_THRESHOLD; mfd->quality = DEF_QUALITY; mfd->lastframe = -1; if(AfxGetApp()->GetProfileInt("Config", "LoadSettingsOnNextRun", 0)) { mfd->threshold = AfxGetApp()->GetProfileInt("Config", "Threshold", DEF_THRESHOLD); mfd->quality = AfxGetApp()->GetProfileInt("Config", "Quality", DEF_QUALITY); } mfd->aviutlinit = true; mfd->row = NULL; return(TRUE); } BOOL func_exit(FILTER *fp) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); MyFilterData *mfd = (MyFilterData *)fp->ex_data_ptr; if(mfd) { if(mfd->img) delete [] mfd->img; if(mfd->row) delete [] mfd->row; delete mfd; mfd = NULL; } return(TRUE); } BOOL func_update(FILTER *fp) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); MyFilterData *mfd = (MyFilterData *)fp->ex_data_ptr; if(!mfd->aviutlinit) { CConfigDlg dlg(mfd->threshold, mfd->quality); if(dlg.DoModal() == IDOK) { mfd->threshold = dlg.m_threshold; mfd->quality = dlg.m_quality; } } mfd->aviutlinit = false; return(TRUE); } BOOL func_proc(FILTER *fp, FILTER_PROC_INFO *fpip) { MyFilterData *mfd = (MyFilterData *)fp->ex_data_ptr; if(!mfd->img || mfd->size != CSize(fpip->w, fpip->h)) { if(mfd->img) delete [] mfd->img; mfd->img = new MyPixel[fpip->w * fpip->h]; if(!mfd->img) return(FALSE); if(mfd->row) delete [] mfd->row; mfd->row = new uchar[fpip->w*3]; if(!mfd->row) return(FALSE); mfd->size = CSize(fpip->w, fpip->h); memset(mfd->img, 0, sizeof(MyPixel) * fpip->w * fpip->h); } if(mfd->lastframe > fpip->frame) { memset(mfd->img, 0, sizeof(MyPixel) * fpip->w * fpip->h); } mfd->lastframe = fpip->frame; for(int y = 0; y < fpip->h; y++) { PIXEL_YC* dstyc = fpip->ycp_edit + y*fpip->max_w; fp->exfunc->yc2rgb((PIXEL*)mfd->row, dstyc, fpip->w); ProcessRow(mfd->img + fpip->w*y, mfd->row, mfd->row + fpip->w*3, 3, mfd->threshold, mfd->quality); fp->exfunc->rgb2yc(dstyc, (PIXEL*)mfd->row, fpip->w); } return TRUE; }