Example #1
0
        /// <summary>
        ///   Converts an unmanaged image to an complex image and uses zero padding if required.
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        public static ComplexImage ToComplexImage(this UnmanagedImage image)
        {
            var result = new ComplexImage(image.Width, image.Height);

            ToComplexImageZeroPad(image, result);
            return(result);
        }
Example #2
0
 public static void CheckComparable([NotNull] ComplexImage image1, [NotNull] ComplexImage image2)
 {
     if (image1.Width != image2.Width ||
         image1.Height != image2.Height)
     {
         throw new DimensionMismatchException();
     }
 }
Example #3
0
 public static void Draw(this UnmanagedImage thisImage, ComplexImage srcImage, Rectangle clip) => Draw(
     thisImage,
     srcImage,
     clip.X,
     clip.Y,
     clip.Width,
     clip.Height
     );
Example #4
0
        /// <summary>
        ///   Draws the absolut part of an complex image to the destination image.
        /// </summary>
        /// <param name="thisImage"></param>
        /// <param name="srcImage"></param>
        public static void Draw(this UnmanagedImage thisImage, ComplexImage srcImage)
        {
            var pb = Preferences.Supported.CheckAndGetPixelBytes(thisImage);
            var w  = Math.Min(srcImage.Width, thisImage.Width);
            var h  = Math.Min(srcImage.Height, thisImage.Height);

            DoDraw(thisImage.ImageData, thisImage.Stride, pb, srcImage, 0, w, h);
        }
Example #5
0

        
Example #6
0
        /// <summary>
        ///   Draws the real part of an complex image to the destination image.
        /// </summary>
        /// <param name="thisImage"></param>
        /// <param name="srcImage"></param>
        public static unsafe void DrawReals(this UnmanagedImage thisImage, ComplexImage srcImage)
        {
            const float norm = (float)byte.MaxValue / ComplexImage.MAX_MAGNITUDE;
            var         pb   = Preferences.Supported.CheckAndGetPixelBytes(thisImage);
            var         w    = Math.Min(srcImage.Width, thisImage.Width);
            var         h    = Math.Min(srcImage.Height, thisImage.Height);

            var dstPtr    = (byte *)thisImage.ImageData;
            var dstStride = thisImage.Stride;
            var dstPadd   = dstStride - (w * pb);
            var c0        = srcImage.Channel0;
            var c1        = srcImage.Channel1;
            var c2        = srcImage.Channel2;

            switch (pb)
            {
            case 3:
                for (int i0 = 0,
                     n = srcImage.Width * h;
                     i0 < n;
                     i0 += srcImage.Width, dstPtr += dstPadd)
                {
                    for (int i = i0,
                         m = i0 + w;
                         i < m;
                         i++, dstPtr += pb)
                    {
                        dstPtr[RGB.R] = (c0[i].Real * norm).ClampToByte();
                        dstPtr[RGB.G] = (c1[i].Real * norm).ClampToByte();
                        dstPtr[RGB.B] = (c2[i].Real * norm).ClampToByte();
                    }
                }

                break;

            case 4:
                for (int i0 = 0,
                     n = srcImage.Width * h;
                     i0 < n;
                     i0 += srcImage.Width, dstPtr += dstPadd)
                {
                    for (int i = i0,
                         m = i0 + w;
                         i < m;
                         i++, dstPtr += pb)
                    {
                        dstPtr[RGB.R] = (c0[i].Real * norm).ClampToByte();
                        dstPtr[RGB.G] = (c1[i].Real * norm).ClampToByte();
                        dstPtr[RGB.B] = (c2[i].Real * norm).ClampToByte();
                        dstPtr[RGB.A] = byte.MaxValue;
                    }
                }

                break;
                //default: already caught at the beginning
            }
        }
Example #7
0
        /// <summary>
        ///   Converts an unmanaged image to an complex image and uses zero padding if required.
        /// </summary>
        /// <param name="image"></param>
        /// <param name="dstWidth"></param>
        /// <param name="dstHeight"></param>
        /// <returns></returns>
        public static ComplexImage ToComplexImageZeroPad(this UnmanagedImage image, int dstWidth, int dstHeight)
        {
            if (dstWidth < 1 ||
                dstHeight < 1)
            {
                throw new ArgumentOutOfRangeException(dstWidth < 1 ? nameof(dstWidth) : nameof(dstHeight));
            }

            var result = new ComplexImage(dstWidth, dstHeight);

            ToComplexImageZeroPad(image, result);
            return(result);
        }
Example #8
0
        /// <summary>
        ///   Draws the absolute part of an complex image to the destination image.
        /// </summary>
        /// <param name="dstPtr">pointer of the destination image, points to the first byte to draw.</param>
        /// <param name="stride">stride of the destination image</param>
        /// <param name="pixelBytes">number of byte per pixel of the destination image </param>
        /// <param name="srcImage">source image</param>
        /// <param name="i">start pixel of the source image</param>
        /// <param name="width">width to draw</param>
        /// <param name="height">height to draw</param>
        private static unsafe void DoDraw(IntPtr dstPtr,
                                          int stride,
                                          int pixelBytes,
                                          ComplexImage srcImage,
                                          int i,
                                          int width,
                                          int height)
        {
            const float norm    = (float)byte.MaxValue / ComplexImage.MAX_MAGNITUDE;
            var         srcPadd = ((i % srcImage.Width) + srcImage.Width) - width; // sum left and right padding
            var         dstPadd = stride - (width * pixelBytes);
            var         d       = (byte *)dstPtr;
            var         c0      = srcImage.Channel0;
            var         c1      = srcImage.Channel1;
            var         c2      = srcImage.Channel2;

            switch (pixelBytes)
            {
            case 3:
                for (var iToB = i + (height * srcImage.Width); i < iToB; i += srcPadd, d += dstPadd)
                {
                    for (var iToL = i + width; i < iToL; i++, d += pixelBytes)
                    {
                        d[RGB.R] = (c0[i].Magnitude * norm).ClampToByte();
                        d[RGB.G] = (c1[i].Magnitude * norm).ClampToByte();
                        d[RGB.B] = (c2[i].Magnitude * norm).ClampToByte();
                    }
                }

                break;

            case 4:
                for (var iToB = i + (height * srcImage.Width); i < iToB; i += srcPadd, d += dstPadd)
                {
                    for (var iToL = i + width; i < iToL; i++, d += pixelBytes)
                    {
                        d[RGB.R] = (c0[i].Magnitude * norm).ClampToByte();
                        d[RGB.G] = (c1[i].Magnitude * norm).ClampToByte();
                        d[RGB.B] = (c2[i].Magnitude * norm).ClampToByte();
                        d[RGB.A] = byte.MaxValue;
                    }
                }

                break;
                //default: already caught at the beginning
            }
        }
Example #9
0
        public void CopyTo(ComplexImage destination)
        {
            if (Width != destination.Width ||
                Height != destination.Height)
            {
                throw new ArgumentException(
                          @"different " + (Width != destination.Width ? "width" : "height"),
                          nameof(destination)
                          );
            }

            var n = Width * Height;

            Array.Copy(Channel0, destination.Channel0, n);
            Array.Copy(Channel1, destination.Channel1, n);
            Array.Copy(Channel2, destination.Channel2, n);
        }
Example #10
0
        /// <summary>
        ///   Draws the absolut part of an complex image to the destination image using the clipping bounds (x, y, width, height).
        /// </summary>
        /// <param name="thisImage"></param>
        /// <param name="srcImage"></param>
        /// <param name="x">x of clip</param>
        /// <param name="y">y of clip</param>
        /// <param name="width">width of clip</param>
        /// <param name="height">height of clip</param>
        public static void Draw(this UnmanagedImage thisImage, ComplexImage srcImage, int x, int y, int width, int height)
        {
            //width,height required because of zero padding
            Debug.Assert(srcImage.Width >= width);
            Debug.Assert(srcImage.Height >= height);
            var pb = Preferences.Supported.CheckAndGetPixelBytes(thisImage);

            var dstPtr = thisImage.ImageData;

            //clipping
            if (x + width > thisImage.Width)
            {
                width = thisImage.Width - x; // right clip
            }

            if (y + height > thisImage.Height)
            {
                height = thisImage.Height - y; // bottom clip
            }

            if (x <= 0)
            {
                x = -x; // left clip
            }
            else
            {
                dstPtr += x * pb;
                x       = 0;
            }

            if (y <= 0)
            {
                y = -y; // left clip
            }
            else
            {
                dstPtr += y * thisImage.Stride;
                y       = 0;
            }

            DoDraw(dstPtr, thisImage.Stride, pb, srcImage, (y * srcImage.Width) + x, width, height);
        }
Example #11
0
        public static unsafe void ToComplexImageZeroPad(this UnmanagedImage image, [NotNull] ComplexImage outImage)
        {
            const float norm = ComplexImage.MAX_MAGNITUDE / (float)byte.MaxValue;
            //TODO: zero padding
            var wDst    = outImage.Width;
            var w       = Math.Min(image.Width, wDst);
            var h       = Math.Min(image.Height, outImage.Height);
            var pb      = ComplexImage.Compatible.CheckAndGetPixelBytes(image);
            var srcPadd = image.Stride - (w * pb);
            var dt      = (byte *)image.ImageData;
            var c0Data  = outImage.Channel0;
            var c1Data  = outImage.Channel1;
            var c2Data  = outImage.Channel2;

            for (var i0 = 0; i0 < wDst * h; i0 += wDst, dt += srcPadd)
            {
                for (var i = i0; i < i0 + w; i++, dt += pb)
                {
                    c0Data[i] = dt[RGB.R] * norm;
                    c1Data[i] = dt[RGB.G] * norm;
                    c2Data[i] = dt[RGB.B] * norm;
                }
            }
        }
Example #12
0
 public ComplexImage(ComplexImage image)
 {
     C0 = new Complex2D(image.C0);
     C1 = new Complex2D(image.C1);
     C2 = new Complex2D(image.C2);
 }
Example #13
0
 public void ForEachColumn(Action <Complex[]> action, ComplexImage output)
 {
     C0.ForEachColumn(action, output.C0);
     C1.ForEachColumn(action, output.C1);
     C2.ForEachColumn(action, output.C2);
 }
Example #14
0
        public static unsafe void ToComplexImageSymmetric(this UnmanagedImage image, [NotNull] ComplexImage outImage)
        {
            const float norm = ComplexImage.MAX_MAGNITUDE / (float)byte.MaxValue;
            //TODO: zero padding
            var wDst    = outImage.Width;
            var w       = Math.Min(image.Width, wDst);
            var h       = Math.Min(image.Height, outImage.Height);
            var pb      = ComplexImage.Compatible.CheckAndGetPixelBytes(image);
            var srcPadd = image.Stride - (w * pb);
            var dt      = (byte *)image.ImageData;
            var c0Data  = outImage.Channel0;
            var c1Data  = outImage.Channel1;
            var c2Data  = outImage.Channel2;

            var w2 = w * 2;
            var wr = wDst % w2;
            var i  = 0;

            for (int i0 = 0,
                 i0To = wDst * h;
                 i0 < i0To;
                 i0 += wDst, dt += srcPadd)
            {
                for (; i < i0 + w; i++, dt += pb)
                {
                    c0Data[i] = dt[RGB.R] * norm;
                    c1Data[i] = dt[RGB.G] * norm;
                    c2Data[i] = dt[RGB.B] * norm;
                }

                for (var j = i - 1; j < wDst; i++, j--)
                {
                    c0Data[i] = c0Data[j];
                    c1Data[i] = c1Data[j];
                    c2Data[i] = c2Data[j];
                }

                for (var iTo = (i0 + wDst) - w2; i + w2 < iTo; i += w2)
                {
                    Array.Copy(c0Data, i0, c0Data, i, w2);
                    Array.Copy(c1Data, i0, c1Data, i, w2);
                    Array.Copy(c2Data, i0, c2Data, i, w2);
                }

                if (wr <= 0)
                {
                    continue;
                }

                Array.Copy(c0Data, i0, c0Data, i, wr);
                Array.Copy(c1Data, i0, c1Data, i, wr);
                Array.Copy(c2Data, i0, c2Data, i, wr);
            }

            var lDst = wDst * outImage.Height;
            var l    = h * wDst;
            var l2   = l * 2;

            for (var j = i - wDst; i < lDst; i += wDst, j -= wDst)
            {
                Array.Copy(c0Data, j, c0Data, i, wr);
                Array.Copy(c1Data, j, c1Data, i, wr);
                Array.Copy(c2Data, j, c2Data, i, wr);
            }

            var lr = lDst % l2;

            for (var iTo = i - l2; i < iTo; i += l2)
            {
                Array.Copy(c0Data, 0, c0Data, i, l2);
                Array.Copy(c1Data, 0, c1Data, i, l2);
                Array.Copy(c2Data, 0, c2Data, i, l2);
            }

            if (lr <= 0)
            {
                return;
            }

            Array.Copy(c0Data, 0, c0Data, i, lr);
            Array.Copy(c1Data, 0, c1Data, i, lr);
            Array.Copy(c2Data, 0, c2Data, i, lr);
        }