- moved all plugin-related classes to Eithne.Plugin namespace
[FaRetSys.git] / Plugins / FFT / FFT.cs
blobd5d67c8526328a4cfc6299acf363eb4251e4cf30
1 using System;
2 using System.Xml;
3 using Mono.Unix;
5 namespace Eithne
7 public class FFTInfo : IInfo
9 public override string Name
11 get { return Catalog.GetString("Fast Fourier Transform"); }
14 public override string ShortName
16 get { return "FFT"; }
19 public override string Author
21 get { return "Bartosz Taudul"; }
24 public override string Description
26 get { return Catalog.GetString("This plugin performs fast fourier transform."); }
30 public class FFTFactory : IFactory
32 IInfo _info = new FFTInfo();
33 public IInfo Info
35 get { return _info; }
38 public IType Type
40 get { return IType.ImgProc; }
43 public void Initialize()
47 public Plugin.Base Create()
49 return new FFTPlugin();
53 public class FFTPlugin : Plugin.ImgProc
55 private bool zero = true;
56 private float progress = 0;
58 public FFTPlugin()
60 _info = new FFTInfo();
63 public override XmlNode Config
65 get { return GetConfig(); }
66 set { LoadConfig(value); }
69 private void UpdateValue(bool z)
71 zero = z;
72 _block.SlotsChanged();
75 public override void Setup()
77 new FFTSetup(zero, UpdateValue, false);
80 public override void Work()
82 progress = 0;
84 ICommImage socket = _in[0] as ICommImage;
85 IImage[] img = socket.Images;
86 IImage[] res = new IImage[img.Length];
87 _out = new CommSocket(1);
89 PreparePlan(img[0].W, img[0].H);
91 for(int i=0; i<img.Length; i++)
93 res[i] = FFT(img[i]);
94 progress = (float)i/img.Length;
97 _out[0] = new ICommImage(res, socket.OriginalImages, socket.Categories);
99 FFTW.Cleanup();
101 _workdone = true;
104 // this function does nothing, but without it, when first plan is created using real images, for some parameters
105 // the first output image is empty and the rest is fine, so it's better to create here this no-use plan just
106 // to be sure that everything works
107 private void PreparePlan(int w, int h)
109 double[] d1 = new double[w * h * 2];
110 double[] d2 = new double[w * h * 2];
112 IntPtr plan = FFTW.PlanDFT2D(h, w, d1, d2, FFTW.Direction.Forward, 0);
114 FFTW.DestroyPlan(plan);
117 private IImage FFT(IImage img)
119 double[] datain = new double[img.W * img.H * 2];
120 double[] dataout = new double[img.W * img.H * 2];
122 for(int y=0; y<img.H; y++)
123 for(int x=0; x<img.W; x++)
125 datain[(x + y*img.W) * 2] = (byte)img[x, y];
126 datain[(x + y*img.W) * 2 + 1] = 0;
129 IntPtr plan = FFTW.PlanDFT2D(img.H, img.W, datain, dataout, FFTW.Direction.Forward, 0);
131 FFTW.Execute(plan);
133 FFTW.DestroyPlan(plan);
135 IImage ret = new IImage(BPP.Float, img.W, img.H);
137 for(int y=0; y<img.H; y++)
138 for(int x=0; x<img.W; x++)
140 double re = dataout[(x + y*img.W) * 2];
141 double im = dataout[(x + y*img.W) * 2 + 1];
142 double val = Math.Sqrt(re * re + im * im);
144 int newx = (x + img.W/2)%img.W;
145 int newy = (y + img.H/2)%img.H;
147 ret[newx, newy] = (float)val/255f;
150 if(zero)
151 ret[img.W/2, img.H/2] = 0f;
153 return ret;
156 public override void Lock()
158 FFTW.mutex.WaitOne();
161 public override void Unlock()
163 FFTW.mutex.ReleaseMutex();
166 private XmlNode GetConfig()
168 XmlNode root = _xmldoc.CreateNode(XmlNodeType.Element, "config", "");
170 if(zero)
171 root.InnerText = "1";
172 else
173 root.InnerText = "0";
175 return root;
178 private void LoadConfig(XmlNode root)
180 if(root.InnerText == "1")
181 UpdateValue(true);
182 else
183 UpdateValue(false);
186 public override int NumIn { get { return 1; } }
187 public override int NumOut { get { return 1; } }
189 public override string DescIn(int n)
191 return Catalog.GetString("Input image.");
194 public override string DescOut(int n)
196 return Catalog.GetString("FFT of image.");
199 private static string[] matchin = new string[] { "image/grayscale" };
200 private static string[] matchout = new string[] { "image/float" };
202 public override string[] MatchIn { get { return matchin; } }
203 public override string[] MatchOut { get { return matchout; } }
205 public override float Progress { get { return progress; } }