/// <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); }
/// <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); } } }