int __stdcall dimzon_avs_getvariable_s(SafeStruct* pstr, const char* name, char* result, int len) { try { pstr->err[0] = 0; try { AVSValue var = pstr->env->GetVar(name); if(var.Defined()) { if(!var.IsString()) { strncpy_s(pstr->err, ERRMSG_LEN, "AviSynthWrapper: Requested variable is not String!", _TRUNCATE); return AVS_VARWRNGTYPE; } strncpy_s(result, len, var.AsString(), len - 1); return 0; } return AVS_VARNDEFINED; } catch(AvisynthError err) { strncpy_s(pstr->err, ERRMSG_LEN, err.msg, _TRUNCATE); return AVS_GERROR; } } catch(IScriptEnvironment::NotFound) { return AVS_VARNFOUND; } }
bool Write::DoEval( IScriptEnvironment* env) { bool keep_this_line = true; int i; AVSValue expr; AVSValue result; for (i=0; i<arrsize; i++) { expr = arglist[i].expression; if ( (linecheck==1) && (i==0)) { try { result = env->Invoke("Eval",expr); if (!result.AsBool(true)) { keep_this_line = false; break; } } catch (AvisynthError) { // env->ThrowError("Write: Can't eval linecheck expression!"); // results in KEEPING the line } } else { try { result = env->Invoke("Eval",expr); result = env->Invoke("string",result); //convert all results to a string arglist[i].string = result.AsString(EMPTY); } catch (AvisynthError error) { arglist[i].string = env->SaveString(error.msg); } } } return keep_this_line; }
AVSValue ExpPlus::Evaluate(IScriptEnvironment* env) { AVSValue x = a->Evaluate(env); AVSValue y = b->Evaluate(env); if (x.IsClip() && y.IsClip()) return new_Splice(x.AsClip(), y.AsClip(), false, env); // UnalignedSplice else if (x.IsInt() && y.IsInt()) return x.AsInt() + y.AsInt(); else if (x.IsFloat() && y.IsFloat()) return x.AsFloat() + y.AsFloat(); else if (x.IsString() && y.IsString()) return env->Sprintf("%s%s", x.AsString(), y.AsString()); else { env->ThrowError("Evaluate: operands of `+' must both be numbers, strings, or clips"); return 0; } }
AVSValue ExpLess::Evaluate(IScriptEnvironment* env) { AVSValue x = a->Evaluate(env); AVSValue y = b->Evaluate(env); if (x.IsInt() && y.IsInt()) { return x.AsInt() < y.AsInt(); } else if (x.IsFloat() && y.IsFloat()) { return x.AsFloat() < y.AsFloat(); } else if (x.IsString() && y.IsString()) { return _stricmp(x.AsString(),y.AsString()) < 0 ? true : false; } else { env->ThrowError("Evaluate: operands of `<' and friends must be string or numeric"); return 0; } }
AVSValue ExpEqual::Evaluate(IScriptEnvironment* env) { AVSValue x = a->Evaluate(env); AVSValue y = b->Evaluate(env); if (x.IsBool() && y.IsBool()) { return x.AsBool() == y.AsBool(); } else if (x.IsInt() && y.IsInt()) { return x.AsInt() == y.AsInt(); } else if (x.IsFloat() && y.IsFloat()) { return x.AsFloat() == y.AsFloat(); } else if (x.IsClip() && y.IsClip()) { return x.AsClip() == y.AsClip(); } else if (x.IsString() && y.IsString()) { return !lstrcmpi(x.AsString(), y.AsString()); } else { env->ThrowError("Evaluate: operands of `==' and `!=' must be comparable"); return 0; } }
AVSValueStruct CAsifScriptEnvironment::Invoke(const char* command) { AVSValueStruct ir; ir.arraysize = 0; ir.errors = false; ir.returnvalue.ival = 0; ir.type = 0; std::vector<const char *> tempargnames(args.size()); for (size_t i = 0; i < tempargnames.size(); i++) tempargnames[i] = (argnames[i].c_str() == "" ? nullptr : argnames[i].c_str()); try { AVSValue ret = envse->Invoke(command, AVSValue(args.data(), args.size()), tempargnames.data()); if (ret.IsClip()) { ir.returnvalue.cval = new CAsifClip(ret.AsClip(), envse); ir.type = 1; } else if (ret.IsBool()) { ir.returnvalue.bval = ret.AsBool(); ir.type = 2; } else if (ret.IsInt()) { ir.returnvalue.ival = ret.AsInt(); ir.type = 3; } else if (ret.IsFloat()) { ir.returnvalue.fval = (float)ret.AsFloat(); ir.type = 4; } else if (ret.IsString()) { ir.returnvalue.sval = ret.AsString(); ir.type = 5; } else if (ret.IsArray()) { // ir.returnvalue.aval=ret. ir.arraysize = ret.ArraySize(); ir.type = 6; } } catch (AvisynthError &e) { ir.type = 100; ir.returnvalue.sval = e.msg; ir.errors = 1; } ResetArgs(); return ir; }
void ConditionalReader::SetFrame(int framenumber, AVSValue v) { if ((framenumber+offset) < 0 || (framenumber+offset) > vi.num_frames-1 ) return; switch (mode) { case MODE_INT: intVal[framenumber+offset] = v.AsInt(); break; case MODE_FLOAT: floatVal[framenumber+offset] = v.AsFloatf(); break; case MODE_BOOL: boolVal[framenumber+offset] = v.AsBool(); break; case MODE_STRING: stringVal[framenumber+offset] = v.AsString(""); break; } }
void ConditionalReader::SetRange(int start_frame, int stop_frame, AVSValue v) { int i; start_frame = max(start_frame+offset, 0); stop_frame = min(stop_frame+offset, vi.num_frames-1); int p; float q; bool r; const char* s; switch (mode) { case MODE_INT: p = v.AsInt(); for (i = start_frame; i <= stop_frame; i++) { intVal[i] = p; } break; case MODE_FLOAT: q = v.AsFloatf(); for (i = start_frame; i <= stop_frame; i++) { floatVal[i] = q; } break; case MODE_BOOL: r = v.AsBool(); for (i = start_frame; i <= stop_frame; i++) { boolVal[i] = r; } break; case MODE_STRING: s = v.AsString(""); for (i = start_frame; i <= stop_frame; i++) { stringVal[i] = s; } break; } }
ConditionalFilter::ConditionalFilter(PClip _child, PClip _source1, PClip _source2, AVSValue _condition1, AVSValue _evaluator, AVSValue _condition2, bool _show, IScriptEnvironment* env) : GenericVideoFilter(_child), source1(_source1), source2(_source2), eval1(_condition1), eval2(_condition2), show(_show) { evaluator = NONE; if (lstrcmpi(_evaluator.AsString(), "equals") == 0 || lstrcmpi(_evaluator.AsString(), "=") == 0 || lstrcmpi(_evaluator.AsString(), "==") == 0) evaluator = EQUALS; if (lstrcmpi(_evaluator.AsString(), "greaterthan") == 0 || lstrcmpi(_evaluator.AsString(), ">") == 0) evaluator = GREATERTHAN; if (lstrcmpi(_evaluator.AsString(), "lessthan") == 0 || lstrcmpi(_evaluator.AsString(), "<") == 0) evaluator = LESSTHAN; if (evaluator == NONE) env->ThrowError("ConditionalFilter: Evaluator could not be recognized!"); VideoInfo vi1 = source1->GetVideoInfo(); VideoInfo vi2 = source2->GetVideoInfo(); if (vi1.height != vi2.height) env->ThrowError("ConditionalFilter: The two sources must have the same height!"); if (vi1.width != vi2.width) env->ThrowError("ConditionalFilter: The two sources must have the same width!"); if (!vi1.IsSameColorspace(vi2)) env->ThrowError("ConditionalFilter: The two sources must be the same colorspace!"); vi.height = vi1.height; vi.width = vi1.width; vi.pixel_type = vi1.pixel_type; vi.num_frames = max(vi1.num_frames,vi2.num_frames); vi.num_audio_samples = vi1.num_audio_samples; vi.audio_samples_per_second = vi1.audio_samples_per_second; vi.image_type = vi1.image_type; vi.fps_denominator = vi1.fps_denominator; vi.fps_numerator = vi1.fps_numerator; vi.nchannels = vi1.nchannels; vi.sample_type = vi1.sample_type; }
void CAviSynth::LoadDll(const char *path) { string s; ok = false; Version25 = false; if (env) delete env; env = NULL; if (avisynth) delete avisynth; avisynth = NULL; if (Version) delete Version; avisynth = new Tdll(path,NULL); avisynth->loadFunction((void**)&CreateScriptEnvironment,"CreateScriptEnvironment"); if (avisynth->ok) { ok = true; env = CreateScriptEnvironment(2); if (!env) { env = CreateScriptEnvironment(1); } else { Version25 = true; } if (!env) { ok = false; } else { AVSValue a; try { AVSValue r = env->Invoke("VersionString", AVSValue(&a,0)); s = r.AsString(); } catch (...) {s = "Version < 2.07; VersionString() not implemented";} Version = strdup(s.c_str()); if (coExternal) delete coExternal; coExternal=NULL; try { AVSValue p = env->GetVar("$PluginFunctions$"); coExternal = strdup(p.AsString()); } catch (...) {;} if (coAll) delete coAll; coAll=NULL; if (coAllScintilla) delete coAllScintilla; coAllScintilla=NULL; int tmpsize = max(strlen(coInternal),(coExternal?strlen(coExternal):0))+1; char *temp; coAll = new char[strlen(coKeywords)+strlen(coInternal)+(coExternal?strlen(coExternal):0)+2]; char *token; char *token2; //string *c; string c; char sci[3]; set<string,less_nocase> AVSToken; set<string,less_nocase> AVSTokenSci; /* strcpy(temp, coKeywords); token = strtok(temp, " "); sprintf(sci, "?%d", ICO_SCI_AVS_KEYWORDS); while (token != NULL) { c = new string; *c = token; AVSToken.insert(*c); *c += sci; AVSTokenSci.insert(*c); token = strtok(NULL, " "); delete c; } */ temp = new char[tmpsize]; strcpy(temp, coKeywords); token = strtok(temp, " "); sprintf(sci, "?%d", ICO_SCI_AVS_KEYWORDS); while (token != NULL) { c = token; AVSToken.insert(c); c += sci; AVSTokenSci.insert(c); token = strtok(NULL, " "); } strcpy(temp, coInternal); token2 = strtok(temp, " "); sprintf(sci, "?%d", ICO_SCI_AVS_INTERNAL); while (token2 != NULL) { c = token2; AVSToken.insert(c); c += sci; AVSTokenSci.insert(c); token2 = strtok(NULL, " "); } if (coExternal) { strcpy(temp, coExternal); token = strtok(temp, " "); sprintf(sci, "?%d", ICO_SCI_AVS_EXTERNAL); while (token != NULL) { c = token; AVSToken.insert(c); c += sci; AVSTokenSci.insert(c); token = strtok(NULL, " "); } } set<string,less_nocase>::iterator walkit; walkit = AVSToken.begin(); strcpy(coAll, walkit->c_str()); for(walkit++; walkit!=AVSToken.end();walkit++) { strcat(coAll, " "); strcat(coAll, walkit->c_str()); } coAllScintilla = new char[strlen(coKeywords)+strlen(coInternal)+(coExternal?strlen(coExternal):0)+2+(AVSTokenSci.size()*2)]; walkit = AVSTokenSci.begin(); strcpy(coAllScintilla, walkit->c_str()); for(walkit++; walkit!=AVSTokenSci.end();walkit++) { strcat(coAllScintilla, " "); strcat(coAllScintilla, walkit->c_str()); } AVSToken.clear(); AVSTokenSci.clear(); delete [] temp; } /* if (env) { env->AddFunction("ffdshow_source","",Tffdshow_source::Create,this); char script[2048]; sprintf(script,"ffdshow_source()\n%s",oldscript); AVSValue eval_args[]={script,"ffdshow_avisynth_script"}; try { AVSValue val=env->Invoke("Eval",AVSValue(eval_args,2)); if (val.IsClip()) { clip=new PClip; *clip=val.AsClip(); framenum=0; } deci->drawOSD(0,50,""); } catch (AvisynthError &err) { deci->drawOSD(0,50,err.msg); } } */ } }
int __stdcall dimzon_avs_invoke(SafeStruct* pstr, char *func, char **arg, int len, AVSDLLVideoInfo *vi, float* func_out) { try { *func_out = -FLT_MAX; pstr->err[0] = 0; const int N = 10; int actual_len = 0; AVSValue args[N] = { }; if (len == 0) args[0] = 0; else if (len > N) len = N; for(int i = 0; i < len; i++) { if (strlen(arg[i]) > 0) { string lower = arg[i]; bool was_letters = false; bool was_digits = false; bool was_spaces = false; //Слишком длинные значения - точно текст for (unsigned int n = 0; n < lower.size() && lower.size() <= 10; n++) { lower[n] = tolower(lower[n]); if (!was_letters && isalpha(lower[n])) was_letters = true; if (!was_digits && isdigit(lower[n])) was_digits = true; if (!was_spaces && isspace(lower[n])) was_spaces = true; } if (i == 0 && was_letters && !was_digits && !was_spaces && lower.compare("last") == 0) { //Clip (last) if(!pstr->clp) throw AvisynthError("AviSynthWrapper: The \"last\" clip was requested, but it doesn't exist!"); args[actual_len] = pstr->clp; //pstr->res->AsClip(); actual_len += 1; //pstr->clp; pstr->res->AsClip(); //С обработкой после прошлых вызовов Invoke //pstr->env->GetVar("last").AsClip(); //"Чистый" выход скрипта } else if (was_letters && !was_digits && !was_spaces && lower.compare("true") == 0) { //Bool (true) args[actual_len] = true; actual_len += 1; } else if (was_letters && !was_digits && !was_spaces && lower.compare("false") == 0) { //Bool (false) args[actual_len] = false; actual_len += 1; } else if (!was_letters && was_digits && !was_spaces && lower.find(".") != string::npos) { //Float (double..) args[actual_len] = atof(arg[i]); actual_len += 1; } else if (!was_letters && was_digits && !was_spaces) { //Integer args[actual_len] = atoi(arg[i]); actual_len += 1; } else { //String args[actual_len] = arg[i]; actual_len += 1; } } } AVSValue res = pstr->env->Invoke(func, AVSValue(args, actual_len)); if (!res.IsClip()) { //Вывод результата if (res.IsBool()) { if(!res.AsBool()) *func_out = 0; else *func_out = FLT_MAX; } else if (res.IsInt()) *func_out = (float)res.AsInt(); else if (res.IsFloat()) *func_out = (float)res.AsFloat(); else if (res.IsString()) { *func_out = FLT_MAX; strncpy_s(pstr->err, ERRMSG_LEN, res.AsString(), _TRUNCATE); } } else { pstr->clp = res.AsClip(); VideoInfo inf = pstr->clp->GetVideoInfo(); if (vi != NULL) { vi->width = inf.width; vi->height = inf.height; vi->raten = inf.fps_numerator; vi->rated = inf.fps_denominator; vi->field_based = (inf.IsFieldBased()) ? 1 : 0; vi->first_field = (inf.IsTFF()) ? 1 : (inf.IsBFF()) ? 2 : 0; vi->num_frames = inf.num_frames; //Или не меняем? if (vi->pixel_type_orig == 0) vi->pixel_type_orig = inf.pixel_type; if (vi->sample_type_orig == 0) vi->sample_type_orig = inf.sample_type; vi->pixel_type = inf.pixel_type; vi->sample_type = inf.sample_type; vi->num_audio_samples = inf.num_audio_samples; vi->audio_samples_per_second = inf.audio_samples_per_second; vi->nchannels = inf.nchannels; } //Нужен ли нам вообще этот res?! if(pstr->res) delete pstr->res; pstr->res = new AVSValue(res); pstr->err[0] = 0; } return 0; } catch(AvisynthError err) { strncpy_s(pstr->err, ERRMSG_LEN, err.msg, _TRUNCATE); return AVS_GERROR; } catch(IScriptEnvironment::NotFound) { strncpy_s(pstr->err, ERRMSG_LEN, "AviSynthWrapper: Wrong function name or invalid parameters was passed to Invoke!", _TRUNCATE); return AVS_VARNFOUND } }