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

📄 effects.cpp

📁 avisynth-source-0.3.zip,avi edit src
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// 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"


class VerticalReduceBy2 : public GenericVideoFilter {
  unsigned char *mybuffer;
public:
  VerticalReduceBy2(PVideoFilter _child);
  void GetFrame(int n, unsigned char* buf);
  void GetVideoInfo(VideoInfo* pvi);
  ~VerticalReduceBy2();

  static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char*) { return new VerticalReduceBy2(args[0].clip); }
};


class HorizontalReduceBy2 : public GenericVideoFilter {
  unsigned char *mybuffer;
public:
  HorizontalReduceBy2(PVideoFilter _child);
  void GetFrame(int n, unsigned char* buf);
  void GetVideoInfo(VideoInfo* pvi);
  ~HorizontalReduceBy2();

  static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char*) { return new HorizontalReduceBy2(args[0].clip); }
};


static PVideoFilter __cdecl Create_ReduceBy2(const FilterInfo*, const Arg* args, const char*) {
  return new VerticalReduceBy2(new HorizontalReduceBy2(args[0].clip));
}


class Crop : public GenericVideoFilter {
  /*const*/ int left, top, width, height;
  unsigned char* mybuffer;
public:
  Crop(int _left, int _top, int _width, int _height, PVideoFilter _child);
  void GetFrame(int n, unsigned char* buf);
  void GetVideoInfo(VideoInfo* pvi);
  ~Crop();

  static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char*) {
    return new Crop(args[0].integer, args[1].integer, args[2].integer, args[3].integer, args[4].clip);
  }
};


class AddBorders : public GenericVideoFilter {
  /*const*/ int left, top, right, bot;
  unsigned char* mybuffer;
public:
  AddBorders(int _left, int _top, int _right, int _bot, PVideoFilter _child);
  void GetFrame(int n, unsigned char* buf);
  void GetVideoInfo(VideoInfo* pvi);

  static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char*) {
    return new AddBorders(args[0].integer, args[1].integer, args[2].integer, args[3].integer, args[4].clip);
  }
};


class Letterbox : public GenericVideoFilter {
  const int top, bot;
public:
  Letterbox(int _top, int _bot, PVideoFilter _child);
  void GetFrame(int n, unsigned char* buf);

  static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char*) {
    return new Letterbox(args[0].integer, args[1].integer, args[2].clip);
  }
};


class FixLuminance : public GenericVideoFilter {
  const int vertex, slope;
public:
  FixLuminance(int _vertex, int _slope, PVideoFilter _child);
  void GetFrame(int n, unsigned char* buf);

  static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char*) {
    return new FixLuminance(args[0].integer, int(args[1].floating_pt*16), args[2].clip);
  }
};


class PeculiarBlend : public GenericVideoFilter {
  const int cutoff;
  unsigned char *frame;
  int frame_num;
public:
  PeculiarBlend(int _cutoff, PVideoFilter _child);
  void GetFrame(int n, unsigned char* buf);
  ~PeculiarBlend();

  static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char*) {
    return new PeculiarBlend(args[0].integer, args[1].clip);
  }
};


/********************************************************************
********************************************************************/

#include <math.h>

class ResamplingFunction {
public:
  virtual double f(double x) = 0;
  virtual double support() = 0;
};


class TriangleFilter : public ResamplingFunction {
public:
  double f(double x) {
    x = fabs(x);
    return (x<1.0) ? 1.0-x : 0.0;
  }
  double support() { return 1.0; }
};


class MitchellNetravaliFilter : public ResamplingFunction {
  double p0,p2,p3,q0,q1,q2,q3;
public:
  MitchellNetravaliFilter(double b=1./3., double c=1./3.) {
    p0 = (  6. -  2.*b        ) / 6.;
    p2 = (-18. + 12.*b +  6.*c) / 6.;
    p3 = ( 12. -  9.*b -  6.*c) / 6.;
    q0 = (	     8.*b + 24.*c) / 6.;
    q1 = (	  - 12.*b - 48.*c) / 6.;
    q2 = (	     6.*b + 30.*c) / 6.;
    q3 = (     -     b -  6.*c) / 6.;
  }
  double f(double x) {
    x = fabs(x);
    return (x<1) ? (p0+x*x*(p2+x*p3)) : (x<2) ? (q0+x*(q1+x*(q2+x*q3))) : 0.0;
  }
  double support() { return 2.0; }
};


// This function returns a resampling "program" which is interpreted by the
// FilteredResize filters.  It handles edge conditions so FilteredResize
// doesn't have to.

static int* GetResamplingPattern(int original_width, double subrange_start, double subrange_width, int target_width, ResamplingFunction* func) {
  double scale = double(target_width) / subrange_width;
  double filter_step = min(scale, 1.0);
  double filter_support = func->support() / filter_step;
  int fir_filter_size = int(ceil(filter_support*2));
  int* result = new int[1 + target_width*(1+fir_filter_size)];

  int* cur = result;
  *cur++ = fir_filter_size;

  double pos_step = subrange_width / target_width;
  // the following translates such that the image center remains fixed
  double pos = subrange_start + ((subrange_width - target_width) / (target_width*2));

  for (int i=0; i<target_width; ++i) {
    int end_pos = int(pos + filter_support);
    if (end_pos > original_width-1)
      end_pos = original_width-1;
    int start_pos = end_pos - fir_filter_size + 1;
    if (start_pos < 0)
      start_pos = 0;
    *cur++ = start_pos;
    // the following code ensures that the coefficients add to exactly 65536
    double total = 0.0;
    for (int j=0; j<fir_filter_size; ++j)
      total += func->f((start_pos+j - pos) * filter_step);
    double total2 = 0.0;
    for (int k=0; k<fir_filter_size; ++k) {
      double total3 = total2 + func->f((start_pos+k - pos) * filter_step) / total;
      *cur++ = int(total3*65536+0.5) - int(total2*65536+0.5);
      total2 = total3;
    }
    pos += pos_step;
  }

  return result;
}


class FilteredResizeH : public GenericVideoFilter {
  const int target_width;
  int* /*const*/ pattern_luma;
  int* /*const*/ pattern_chroma;
  unsigned char* srcbuffer;
public:
  FilteredResizeH(double subrange_left, double subrange_width, int _target_width, ResamplingFunction* func, PVideoFilter _child)
   : GenericVideoFilter(_child), target_width(_target_width)
  {
    pattern_chroma = 0;
    if (vi.IsYUY2()) {
      if (target_width&1)
        throw FilterChainError("Resize: YUY2 width must be even");
      pattern_chroma = GetResamplingPattern(vi.width>>1, subrange_left/2, subrange_width/2, target_width>>1, func);
    }
    pattern_luma = GetResamplingPattern(vi.width, subrange_left, subrange_width, target_width, func);
    srcbuffer = new unsigned char[vi.ImageSize()];
  }

  void GetFrame(int n, unsigned char* buf) {
    child->GetFrame(n, srcbuffer);
    unsigned char* base = srcbuffer;
    unsigned char* out = buf;
    int src_row_size = vi.RowSize();
    if (vi.IsYUY2()) {
      int dst_row_size = target_width*2;
      for (int y=0; y<vi.height; ++y) {
        int* cur = pattern_luma+1;
        for (int x=0; x<target_width; ++x) {
          int total = 0;
          int ofs = *cur++;
          for (int a=0; a<pattern_luma[0]; ++a)
            total += base[(ofs+a)*2] * (*cur++);
          out[x*2] = ScaledPixelClip(total);
        }
        cur = pattern_chroma+1;
        for (int xx=0; xx<target_width; xx+=2) {
          int utotal = 0, vtotal = 0;
          int ofs = *cur++;
          for (int a=0; a<pattern_chroma[0]; ++a) {
            utotal += base[(ofs+a)*4+1] * (*cur);
            vtotal += base[(ofs+a)*4+3] * (*cur);
            ++cur;
          }
          out[xx*2+1] = ScaledPixelClip(utotal);
          out[xx*2+3] = ScaledPixelClip(vtotal);
        }
        base += src_row_size;
        out += dst_row_size;
      }
    } else {
      int dst_row_size = target_width*3;
      for (int y=0; y<vi.height; ++y) {
        int* cur = pattern_luma+1;
        for (int x=0; x<target_width; ++x) {
          int btotal = 0, gtotal = 0, rtotal = 0;
          int ofs = *cur++;
          for (int a=0; a<pattern_luma[0]; ++a) {
            btotal += base[(ofs+a)*3] * (*cur);
            gtotal += base[(ofs+a)*3+1] * (*cur);
            rtotal += base[(ofs+a)*3+2] * (*cur);
            ++cur;
          }
          out[x*3] = ScaledPixelClip(btotal);
          out[x*3+1] = ScaledPixelClip(gtotal);
          out[x*3+2] = ScaledPixelClip(rtotal);
        }
        base += src_row_size;
        out += dst_row_size;
      }
    }
  }

  void GetVideoInfo(VideoInfo* pvi) {
    *pvi = vi;
    pvi->width = target_width;
  }

  ~FilteredResizeH() {
    if (pattern_luma) delete[] pattern_luma;
    if (pattern_chroma) delete[] pattern_chroma;
    if (srcbuffer) delete[] srcbuffer;
  }
};


class FilteredResizeV : public GenericVideoFilter {
  const int target_height;
  int* /*const*/ resampling_pattern;
  unsigned char* srcbuffer;
public:
  FilteredResizeV(double subrange_top, double subrange_height, int _target_height, ResamplingFunction* func, PVideoFilter _child)
   : GenericVideoFilter(_child), target_height(_target_height)
  {
    if (vi.IsRGB())
      subrange_top = vi.height - subrange_top - subrange_height;
    resampling_pattern = GetResamplingPattern(vi.height, subrange_top, subrange_height, target_height, func);
    srcbuffer = new unsigned char[vi.ImageSize()];
  }

  void GetFrame(int n, unsigned char* buf) {
    child->GetFrame(n, srcbuffer);
    int* cur = resampling_pattern;
    int fir_filter_width = *cur++;
    int row_size = vi.RowSize();
    unsigned char* out = buf;
    for (int y=0; y<target_height; ++y) {
      unsigned char* base = srcbuffer + row_size * (*cur++);
      for (int x=0; x<row_size; ++x) {
        int total = 0;
        unsigned char* base2 = base+x;
        for (int b=0; b<fir_filter_width; ++b) {
          total += *base2 * cur[b];
          base2 += row_size;
        }
        *out++ = ScaledPixelClip(total);
      }
      cur += fir_filter_width;
    }
  }

  void GetVideoInfo(VideoInfo* pvi) {
    *pvi = vi;
    pvi->height = target_height;
  }

  ~FilteredResizeV() {
    if (resampling_pattern) delete[] resampling_pattern;
    if (srcbuffer) delete[] srcbuffer;
  }
};


static PVideoFilter CreateResizeH(double subrange_left, double subrange_width, int target_width, ResamplingFunction* func, PVideoFilter clip) {
  if (subrange_width == target_width) {
    VideoInfo vi;
    clip->GetVideoInfo(&vi);
    if (subrange_left == 0 && subrange_width == vi.width)
      return clip;
    else
      return new Crop(int(subrange_left), 0, int(subrange_width), vi.height, clip);
  } else {
    return new FilteredResizeH(subrange_left, subrange_width, target_width, func, clip);
  }
}


static PVideoFilter CreateResizeV(double subrange_top, double subrange_height, int target_height, ResamplingFunction* func, PVideoFilter clip) {
  if (subrange_height == target_height) {
    VideoInfo vi;
    clip->GetVideoInfo(&vi);
    if (subrange_top == 0 && subrange_height == vi.height)
      return clip;
    else
      return new Crop(0, int(subrange_top), vi.width, int(subrange_height), clip);
  } else {
    return new FilteredResizeV(subrange_top, subrange_height, target_height, func, clip);
  }
}


static PVideoFilter CreateResize(const Arg* args, const char* arg_types, ResamplingFunction* f) {
  if (strlen(arg_types) == 3) {
    VideoInfo vi;
    args[2].clip->GetVideoInfo(&vi);

⌨️ 快捷键说明

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