⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 script.cpp

📁 avisynth-source-0.3.zip,avi edit src
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Avisynth v0.3.  Copyright 2000 Ben Rudiak-Gould.  For distribution
// conditions, please see http://www.math.berkeley.edu/~benrg/avisynth.html .


#include "avisynth.h"
#include "internal-filters.h"

#include <stdio.h>


#define MAX_IDENTIFIER_LENGTH 50


// types: 'c' = clip; 's' = string; 'i' = int; 'f' = float; 'z' = filter; 


const char* Sprintf(const char* fmt, ...) {
  va_list val;
  va_start(val, fmt);
  static char buf[1024];
  wvsprintf(buf, fmt, val);
  va_end(val);
  return buf;
}


bool TypeMatch(const char* param_types, const char* arg_types, bool strict) {
  for (;;) {
    if (*param_types == *arg_types) {
      // perfect match
      if (*param_types == 0)
        return true;
      ++param_types; ++arg_types;
    } else if (*param_types == '*') {
      // var-args
      return true;
    } else if (*param_types == '+') {
      // var-args: eat args of this type
      while (*arg_types == param_types[-1])
        ++arg_types;
      ++param_types;
    } else if (!strict && *param_types == 'f' && *arg_types == 'i') {
      // non-strict match
      ++param_types; ++arg_types;
    } else {
      // complete failure
      return false;
    }
  }
}


int num_filter_sets = 5;
FilterInfo* filter_sets[64] = { edit_filters, effects_filters, misc_filters, source_filters, text_filters };


const char* SearchForFilterName(const char* search_name) {
  for (int i=num_filter_sets-1; i>=0; --i)
    for (FilterInfo* j = filter_sets[i]; j->name; ++j)
      if (!lstrcmpi(j->name, search_name))
        return j->name;
  return 0;
}


FilterInfo* __cdecl SearchForMatchingFilter(const char* search_name, const char* arg_types) {
  for (int strict = 1; strict >= 0; --strict)
    for (int i=num_filter_sets-1; i>=0; --i)
      for (FilterInfo* j = filter_sets[i]; j->name; ++j)
        if (!lstrcmpi(j->name, search_name) && TypeMatch(j->param_types, arg_types, strict&1))
          return j;
  return 0;
}


void __cdecl LoadPlugin(const char* filename) {
  if (num_filter_sets == sizeof(filter_sets) / sizeof(filter_sets[0]))
    throw FilterChainError(Sprintf("#loadplugin: Too many plugins loaded already", filename));

  HMODULE hmodule = LoadLibrary(filename);
  if (!hmodule)
    throw FilterChainError(Sprintf("#loadplugin: Unable to load \"%s\"", filename));

  typedef FilterInfo* (__stdcall *pPluginFunc)(const PluginCallbacks*);
  pPluginFunc AvisynthPluginGetInfo = (pPluginFunc)GetProcAddress(hmodule, "AvisynthPluginGetInfo");
  if (!AvisynthPluginGetInfo) {
    FreeLibrary(hmodule);
    throw FilterChainError(Sprintf("#loadplugin: \"%s\" does not seem to be an Avisynth 0.3 plugin", filename));
  }

  static const PluginCallbacks callbacks = { sizeof(callbacks), SearchForMatchingFilter };

  FilterInfo* filter_info = AvisynthPluginGetInfo(&callbacks);

  // avoid reloading the same plugin more than once
  for (int i=0; i<num_filter_sets; ++i)
    if (filter_sets[i] == filter_info) {
      FreeLibrary(hmodule);
      return;
    }

  filter_sets[num_filter_sets++] = filter_info;
}


// Variable lookup.  No point doing anything fancy with hash tables;
// this doesn't need to be fast.
class VarTable {
public:
  struct Variable {
    Variable* const next;
    char name[MAX_IDENTIFIER_LENGTH+1];
    PVideoFilter val;
    Variable(const char* _name, Variable* _next) : next(_next) {
      lstrcpy(name, _name);
    }
  };

  VarTable() : variables(0) {}

  Variable* Lookup(const char* name) {
    for (Variable* v = variables; v; v = v->next)
      if (!lstrcmpi(name, v->name))
        return v;
    variables = new Variable(name, variables);
    return variables;
  }

  PVideoFilter GetValue(const char* name) { return Lookup(name)->val; }

private:
  Variable* variables;
};


// Tokenizer.
class Tokenizer {
  char* next_char;
  char* old_next_char;
  int type;   // 'x', 's', 'i', 'f', '+', '++', '.', ',', '(', ')', 0=eoln
  union {
    char identifier[MAX_IDENTIFIER_LENGTH+1];
    char* string;
    int integer;
    float floating_pt;
  };

  void GetNumber();

public:
  Tokenizer() {
    old_next_char = next_char = "";
    type = 0;
  }
  void Reset(char* s) {
    next_char = s;
    while (isspace(*next_char))
      ++next_char;
    NextToken();
  }

  void NextToken();
  int GetType() { return type; }
  const char* GetAsIdentifier() { return identifier; }
  const char* GetAsString() { return string; }
  int GetAsInt() { return integer; }
  float GetAsFloat() { return floating_pt; }

  char* NextCharPointer() { return next_char; }
  char* CurCharPointer() { return old_next_char; }
};


void Tokenizer::GetNumber() {
  // start by assuming an int and switch to float if necessary
  type = 'i';
  integer=0;
  bool negate = false;
  if (*next_char == '-') {
    ++next_char;
    negate = true;
  }
  do {
    if (*next_char == '.') {
      type = 'f';
      floating_pt = float(integer);
      float place = 1;
      ++next_char;
      while (isdigit(*next_char)) {
        place /= 10;
        floating_pt += place * (*next_char - '0');
        ++next_char;
      }
      break;
    } else {
      integer = integer*10 + (*next_char - '0');
    }
    ++next_char;
  } while (isdigit(*next_char) || *next_char == '.');
  if (negate) {
    if (type == 'i')
      integer = -integer;
    else
      floating_pt = -floating_pt;
  }
}


void Tokenizer::NextToken() {
  old_next_char = next_char;
  switch (*next_char) {
    case 0:
      type=0;
      break;
    case '.':
      // a '.' followed by a digit is a number, otherwise it's an operator
      if (isdigit(next_char[1]))
        GetNumber();
      else {
        ++next_char;
        type = '.';
      }
      break;
    case '+':
      // a '+' followed by a digit is a number, otherwise it's an operator
      ++next_char;
      if (isdigit(*next_char)) {
        GetNumber();
      } else if (*next_char == '+') {
        ++next_char;
        type = '++';
      } else {
        type = '+';
      }
      break;
    case ',':
      ++next_char;
      type = ',';
      break;
    case '(':
      ++next_char;
      type = '(';
      break;
    case ')':
      ++next_char;
      type = ')';
      break;
    case '#':
      // comment
      type = 0;
      break;
    case '$':
      // hexadecimal number
      type = 'i';
      integer = 0;
      ++next_char;
      do {
        if (*next_char >= '0' && *next_char <= '9')
          integer = integer*16 + (*next_char - '0');
        else if (*next_char >= 'a' && *next_char <= 'f')
          integer = integer*16 + (*next_char - 'a' + 10);
        else if (*next_char >= 'A' && *next_char <= 'F')
          integer = integer*16 + (*next_char - 'A' + 10);
        else
          throw FilterChainError(Sprintf("$ must be followed by a hexadecimal number"));
      } while (isalnum(*++next_char));
      break;
    case '"':
    {
      // string
      char* eos = strchr(next_char+1, '"');
      if (!eos)
        throw FilterChainError("string missing closing quotation mark");
      *eos = 0;
      type = 's';
      string = next_char+1;
      next_char = eos+1;
      break;
    }
    default:
      if (isdigit(*next_char) || *next_char == '-') {
        // number
        GetNumber();
      } else if (*next_char == '_' || isalnum(*next_char)) {
        // identifier
        type = 'x';
        memset(identifier, 0, sizeof(identifier));
        int i=0;
        do {
          if (i == sizeof(identifier)-1)
            throw FilterChainError(Sprintf("identifier too long: \"%s...\"",  identifier));
          identifier[i++] = *next_char++;
        } while (*next_char == '_' || isalnum(*next_char));
      } else if (next_char[0] == '`' && next_char[1] == '`') {
        // string
        char* eos = strstr(next_char+2, "''");
        if (!eos)
          throw FilterChainError("string missing closing double-apostrophe");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -