Example #1
0
        /// <summary>
        /// Performs logical AND operation on this <see cref="Image"/> and the specified <see cref="Image"/>.
        /// </summary>
        /// <param name="dst">The destination <see cref="Image"/>. Can be <b>null</b>.</param>
        /// <param name="src">The right-side operand of this operation.</param>
        /// <returns>
        /// The destination <see cref="Image"/>.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <para><paramref name="src"/> is <b>null</b>.</para>
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The images have a different depth.
        /// The <see cref="Image{T}.BitsPerPixel"/> properties of <paramref name="src"/> and this <see cref="Image"/> are not the same.
        /// </exception>
        /// <remarks>
        /// <para>
        /// <paramref name="src"/> and this <see cref="Image"/> do not have to have the same width and height.
        /// If image sizes are different, the operation is performed in this <see cref="Image"/> upper-left corner.
        /// </para>
        /// </remarks>
        public Image And(Image dst, Image src)
        {
            if (src == null)
            {
                throw new ArgumentNullException(nameof(src));
            }

            int bitsPerPixel = this.BitsPerPixel;

            if (src.BitsPerPixel != bitsPerPixel)
            {
                throw new ArgumentException(Properties.Resources.E_DepthNotTheSame);
            }

            int width  = Math.Min(this.Width, src.Width);
            int height = Math.Min(this.Height, src.Height);

            // copy this image to destination
            dst = this.Copy(dst, true);

            ulong[] bitssrc = src.Bits;
            ulong[] bitsdst = dst.Bits;

            if (width == dst.Width && src.Stride == dst.Stride)
            {
                // operation is performed on entire image
                // do all lines at once
                Vectors.And(dst.Stride * height, bitssrc, 0, bitsdst, 0);
            }
            else
            {
                int stridesrc = src.Stride1;
                int stridedst = dst.Stride1;
                int count     = width * bitsPerPixel;
                for (int iy = 0, possrc = 0, posdst = 0; iy < height; iy++, possrc += stridesrc, posdst += stridedst)
                {
                    BitUtils.And(count, bitssrc, possrc, bitsdst, posdst);
                }
            }

            return(dst);
        }
Example #2
0
        /// <summary>
        /// Performs logical AND operation on a rectangular block of pixels from this <see cref="Image"/> and the specified <see cref="Image"/>.
        /// </summary>
        /// <param name="x">The x-coordinate of the upper-left corner of the destination rectangle.</param>
        /// <param name="y">The y-coordinate of the upper-left corner of the destination rectangle.</param>
        /// <param name="width">The width of the source and destination rectangles.</param>
        /// <param name="height">The height of the source and destination rectangles.</param>
        /// <param name="src">The right-side operand of this operation.</param>
        /// <param name="xsrc">The x-coordinate of the upper-left corner of the source rectangle.</param>
        /// <param name="ysrc">The y-coordinate of the upper-left corner of the source rectangle.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="src"/> is <b>null</b>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The images have a different depth.
        /// The <see cref="Image{T}.BitsPerPixel"/> properties of <paramref name="src"/> and this <see cref="Image"/> are not the same.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <para>The rectangular area described by <paramref name="x"/>, <paramref name="y"/>, <paramref name="width"/> and <paramref name="height"/> is outside of this <see cref="Image"/> bounds.</para>
        /// <para>-or-</para>
        /// <para>The rectangular area described by <paramref name="xsrc"/>, <paramref name="ysrc"/>, <paramref name="width"/> and <paramref name="height"/> is outside of <paramref name="src"/> bounds.</para>
        /// </exception>
        public void And(int x, int y, int width, int height, Image src, int xsrc, int ysrc)
        {
            if (src == null)
            {
                throw new ArgumentNullException(nameof(src));
            }

            this.ValidateArea(x, y, width, height);
            src.ValidateArea(xsrc, ysrc, width, height);

            int bitsPerPixel = this.BitsPerPixel;

            if (src.BitsPerPixel != bitsPerPixel)
            {
                throw new ArgumentException(Properties.Resources.E_DepthNotTheSame);
            }

            int stridedst = this.Stride1;
            int stridesrc = src.Stride1;

            ulong[] bitsdst = this.Bits;
            ulong[] bitssrc = src.Bits;

            int posdst = (y * stridedst) + (x * bitsPerPixel);
            int possrc = (ysrc * stridesrc) + (xsrc * bitsPerPixel);

            if (x == 0 && xsrc == 0 && width == this.Width && stridesrc == stridedst)
            {
                // operation is performed on entire area
                // do all lines at once
                Vectors.And(stridedst * height / 64, bitssrc, possrc / 64, bitsdst, posdst / 64);
            }
            else
            {
                int count = width * bitsPerPixel;
                for (int iy = 0; iy < height; iy++, possrc += stridesrc, posdst += stridedst)
                {
                    BitUtils.And(count, bitssrc, possrc, bitsdst, posdst);
                }
            }
        }
Example #3
0
        public void BitsAndTest()
        {
            const int Size = 3 * 64;

            ulong[] x = new ulong[3];
            ulong[] y = new ulong[3];

            for (int count = 1; count < Size; count++)
            {
                for (int pos = 0; pos < count; pos++)
                {
                    // shift left
                    for (int posy = 0; posy < Size - count; posy++)
                    {
                        int posx = Size - count;
                        x[0] = x[1] = x[2] = ulong.MaxValue;
                        BitUtils.ResetBits(1, x, posx + pos);

                        y[0] = y[1] = y[2] = ulong.MaxValue;
                        BitUtils.And(count, x, posx, y, posy);

                        Assert.AreEqual(posy + pos, BitUtils.BitScanZeroForward(Size, y, 0));
                    }

                    // shift right
                    for (int posx = 0; posx < Size - count; posx++)
                    {
                        x[0] = x[1] = x[2] = ulong.MaxValue;
                        BitUtils.ResetBits(1, x, posx + pos);

                        int posy = Size - count;
                        y[0] = y[1] = y[2] = ulong.MaxValue;
                        BitUtils.And(count, x, posx, y, posy);

                        Assert.AreEqual(posy + pos, BitUtils.BitScanZeroForward(Size, y, 0));
                    }
                }
            }
        }
Example #4
0
 public void AndTest()
 {
     Assert.Equal <uint>(0x0, BitUtils.And(0x0, 0x0, 0x0));
     Assert.Equal <uint>(0x80000008, BitUtils.And(0x80080008, 0x80000008));
     Assert.Equal <uint>(0x0, BitUtils.And(Enumerable.Range(0, 32).Select(val => (uint)0x1 << val).ToArray()));
 }