Advertisement
Guest User

Untitled

a guest
Aug 6th, 2013
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.38 KB | None | 0 0
  1. #include <windows.h>
  2. #include "avisynth.h"
  3.  
  4. static const AVS_Linkage* AVS_linkage = 0;
  5.  
  6. class Footprint {
  7.  
  8.     int index;
  9.     BYTE* map;
  10.     DWORD* xy;
  11.     int width;
  12.     int height;
  13.     const BYTE* altp;
  14.     BYTE* dstp;
  15.     int alt_pitch;
  16.     int dst_pitch;
  17.  
  18. public:
  19.     Footprint(int w, int h, const BYTE* a, BYTE* d, int ap, int dp, IScriptEnvironment* env)
  20.         : width(w), height(h), altp(a), dstp(d), alt_pitch(ap), dst_pitch(dp), index(-1) {
  21.         map = (BYTE*)calloc(width * height, 1);
  22.         xy = (DWORD*)malloc(width * height * sizeof(DWORD));
  23.         if (!map || !xy) {
  24.             env->ThrowError("failed to allocate Footprint.");
  25.         }
  26.     }
  27.  
  28.     ~Footprint() {
  29.         free(map);
  30.         free(xy);
  31.         map = 0;
  32.         xy = 0;
  33.     }
  34.  
  35.     int get_width() {
  36.         return width;
  37.     }
  38.     int get_height() {
  39.         return height;
  40.     }
  41.     void push(int x, int y) {
  42.         map[x + y * width] = 0xFF;
  43.         dstp[x + y * dst_pitch] = altp[x + y * alt_pitch];
  44.         xy[++index] = ((WORD)x << 16) | (WORD)y;
  45.     }
  46.  
  47.     void pop(int* x, int* y) {
  48.         *x = xy[index] >> 16;
  49.         *y = xy[index--] & 0x0000FFFF;
  50.     }
  51.  
  52.     bool is_empty() {
  53.         return index == -1;
  54.     }
  55.  
  56.     int passed(int x, int y) {
  57.         return (int)map[x + y * width];
  58.     }
  59. };
  60.  
  61. class Hysteresis : public GenericVideoFilter {
  62.     PClip child2;
  63.     bool chroma;
  64.     int num_planes;
  65.  
  66. public:
  67.     Hysteresis(PClip c, PClip c2, bool chroma, IScriptEnvironment* env);
  68.     ~Hysteresis() {}
  69.     PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
  70. };
  71.  
  72. Hysteresis::Hysteresis(PClip c, PClip c2, bool ch, IScriptEnvironment* env)
  73.     : GenericVideoFilter(c), child2(c2), chroma(ch)
  74. {
  75.     if (!vi.IsPlanar()) {
  76.         env->ThrowError("not planar format");
  77.     }
  78.     const VideoInfo& vi2 = child2->GetVideoInfo();
  79.     if (vi.IsSameColorspace(vi2) == false) {
  80.         env->ThrowError("not the same csp");
  81.     }
  82.     if (vi.width != vi2.width || vi.height != vi2.height) {
  83.         env->ThrowError("not the same resolution");
  84.     }
  85.     num_planes = vi.IsY8() ? 1 : 3;
  86. }
  87.  
  88. static void proc(Footprint* fp, int x, int y, const BYTE* altp, int alt_pitch)
  89. {
  90.     fp->push(x, y);
  91.  
  92.     int posx, posy;
  93.     while (!fp->is_empty()) {
  94.         fp->pop(&posx, &posy);
  95.  
  96.         int x_min = posx > 0 ? posx - 1 : 0;
  97.         int x_max = posx < fp->get_width() - 1 ? posx + 1 : posx;
  98.         int y_min = posy > 0 ? posy - 1 : 0;
  99.         int y_max = posy < fp->get_height() - 1 ? posy + 1 : posy;
  100.  
  101.         for (int yy = y_min; yy <= y_max; yy++) {
  102.             for (int xx = x_min; xx <= x_max; xx++) {
  103.                 if (altp[xx + yy * alt_pitch] && !fp->passed(xx, yy)) {
  104.                     fp->push(xx, yy);
  105.                 }
  106.             }
  107.         }
  108.     }
  109. }
  110.  
  111. PVideoFrame __stdcall Hysteresis::GetFrame(int n, IScriptEnvironment* env)
  112. {
  113.     const int planes[] = {PLANAR_Y, PLANAR_U, PLANAR_V};
  114.  
  115.     PVideoFrame base = child->GetFrame(n, env);
  116.     PVideoFrame alt = child2->GetFrame(n, env);
  117.     PVideoFrame dst = env->NewVideoFrame(vi);
  118.  
  119.     for (int i = 0; i < num_planes; i++) {
  120.         if (i > 0 && !chroma) {
  121.             return dst;
  122.         }
  123.         int p = planes[i];
  124.         int width = base->GetRowSize(p);
  125.         int height = base->GetHeight(p);
  126.         int base_pitch = base->GetPitch(p);
  127.         int alt_pitch = alt->GetPitch(p);
  128.         int dst_pitch = dst->GetPitch(p);
  129.         const BYTE* basep = base->GetReadPtr(p);
  130.         const BYTE* altp = alt->GetReadPtr(p);
  131.         BYTE* dstp = dst->GetWritePtr(p);
  132.  
  133.         Footprint *fp = new Footprint(width, height, altp, dstp, alt_pitch, dst_pitch, env);
  134.         memset(dstp, 0, dst_pitch * height);
  135.  
  136.         for (int y = 0; y < height; y++) {
  137.             for (int x = 0; x < width; x++) {
  138.                 if (basep[x + y * base_pitch] && altp[x + y * alt_pitch] &&
  139.                     !fp->passed(x, y)) {
  140.                     proc(fp, x, y, altp, alt_pitch);
  141.                 }
  142.             }
  143.         }
  144.         delete fp;
  145.     }
  146.     return dst;
  147. }
  148.  
  149. AVSValue __cdecl
  150. create_hysteresis(AVSValue args, void* user_data, IScriptEnvironment* env)
  151. {
  152.     return new Hysteresis(args[0].AsClip(), args[1].AsClip(),
  153.                            args[2].AsBool(false), env);
  154. }
  155.  
  156. extern "C" __declspec(dllexport) const char* __stdcall
  157. AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors)
  158. {
  159.     AVS_linkage = vectors;
  160.     env->AddFunction("Hysteresis", "cc[chroma]b", create_hysteresis, 0);
  161.     return "hysteresis mask filter";
  162. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement