/// <summary> /// Copies a rectangular area specified by /// a pair of coordinates, a width, and a height from the specified <see cref="Image"/> /// to the current <see cref="Image"/> in-place. /// </summary> /// <param name="x">The x-coordinate, in pixels, of the upper-left corner of the destination rectangle.</param> /// <param name="y">The y-coordinate, in pixels, of the upper-left corner of the destination rectangle.</param> /// <param name="width">The width, in pixels, of the destination rectangle.</param> /// <param name="height">The height, in pixels, of the destination rectangle.</param> /// <param name="src">The <see cref="Image"/> to copy from.</param> /// <param name="xsrc">The x-coordinate, in pixels, of the upper-left corner of the source rectangle.</param> /// <param name="ysrc">The y-coordinate, in pixels, 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> public void CopyFrom(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); if (this.BitsPerPixel != src.BitsPerPixel) { throw new ArgumentException(Properties.Resources.E_DepthNotTheSame); } Image.CopyArea(this, x, y, width, height, src, xsrc, ysrc); }
/// <summary> /// Performs logical XAND 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 Xand(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.Xand(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.Xand(count, bitssrc, possrc, bitsdst, posdst); } } }
/// <summary> /// Computes minimum values for each pixel in 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"> /// <para>The depth of <paramref name="src"/> is not the same as the depth of this <see cref="Image"/>.</para> /// </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 MinEvery(int x, int y, int width, int height, Image src, int xsrc, int ysrc) { if (src == null) { throw new ArgumentNullException(nameof(src)); } int bitsPerPixel = this.BitsPerPixel; if (src.BitsPerPixel != bitsPerPixel) { throw new ArgumentException(Properties.Resources.E_DepthNotTheSame); } if (bitsPerPixel == 1) { this.And(x, y, width, height, src, xsrc, ysrc); return; } this.ValidateArea(x, y, width, height); src.ValidateArea(xsrc, ysrc, width, height); unsafe { fixed(ulong *bitsdst = &this.Bits[y * this.Stride], bitssrc = &src.Bits[ysrc *src.Stride]) { int stride8dst = this.Stride8; int stride8src = src.Stride8; switch (bitsPerPixel) { case 8: case 24: case 32: { byte *ptrdst = (byte *)bitsdst + (x * bitsPerPixel / 8); byte *ptrsrc = (byte *)bitssrc + (xsrc * bitsPerPixel / 8); if (x == 0 && xsrc == 0 && width == this.Width && stride8src == stride8dst) { // operation is performed on entire area // do all lines at once Vectors.Min(stride8dst * height, ptrsrc, ptrdst); } else { int count = width * bitsPerPixel / 8; for (int iy = 0; iy < height; iy++, ptrsrc += stride8src, ptrdst += stride8dst) { Vectors.Min(count, ptrsrc, ptrdst); } } } break; case 16: { ushort *ptrdst = (ushort *)bitsdst + x; ushort *ptrsrc = (ushort *)bitssrc + xsrc; int stride16dst = stride8dst / sizeof(ushort); int stride16src = stride8src / sizeof(ushort); if (x == 0 && xsrc == 0 && width == this.Width && stride16src == stride16dst) { // operation is performed on entire area // do all lines at once Vectors.Min(stride16dst * height, ptrsrc, ptrdst); } else { for (int iy = 0; iy < height; iy++, ptrsrc += stride16src, ptrdst += stride16dst) { Vectors.Min(width, ptrsrc, ptrdst); } } } break; default: throw new NotSupportedException(string.Format( CultureInfo.InvariantCulture, Properties.Resources.E_UnsupportedDepth, bitsPerPixel)); } } } }