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)); } } } }
public void SetBitsTest() { const int Size = 3 * 64; ulong[] y = new ulong[3]; for (int count = 1; count < Size; count++) { for (int pos = 0; pos < Size - count; pos++) { y[0] = y[1] = y[2] = 0; BitUtils.SetBits(count, y, pos); Assert.AreEqual(count, BitUtils.CountOneBits(Size, y, 0)); Assert.AreEqual(pos, BitUtils.BitScanOneForward(Size, y, 0)); Assert.AreEqual(pos + count - 1, BitUtils.BitScanOneReverse(Size, y, Size - 1)); Assert.AreEqual(pos + count == Size ? -1 : pos + count, BitUtils.BitScanZeroForward(Size - pos, y, pos)); Assert.AreEqual(pos == 0 ? -1 : pos - 1, BitUtils.BitScanZeroReverse(pos + count, y, pos + count - 1)); } } }
/// <summary> /// Cleans scan border noise from the <see cref="Image"/>. /// </summary> /// <param name="maxNoiseWidth">The maximum width of the noise, in inches.</param> /// <param name="maxNoiseHeight">The maximum height of the noise, in inches.</param> /// <returns> /// A new cleaned <see cref="Image"/>. /// </returns> public Image CleanOverscan(float maxNoiseWidth, float maxNoiseHeight) { int width = this.Width; int height = this.Height; int stride1 = this.Stride1; int stride = this.Stride; Image dst = this.Copy(null, true); ulong[] bits = dst.Bits; int maxwidth = (int)((maxNoiseWidth * this.HorizontalResolution) + 0.5f); if (maxwidth > 0) { ClearLeft(FindLeft(maxwidth)); ClearRight(FindRight(maxwidth)); } int maxheight = (int)((maxNoiseHeight * this.VerticalResolution) + 0.5f); if (maxheight > 0) { ClearTop(FindTop(maxheight)); ClearBottom(FindBottom(maxheight)); } return(dst); int[] FindLeft(int maxlen) { int scanlen = Core.MinMax.Min(width, maxlen); int[] lengths = new int[height]; for (int iy = 0, pos = 0; iy < height; iy++, pos += stride1) { int len = BitUtils.BitScanZeroForward(scanlen, bits, pos); lengths[iy] = len == -1 ? 0 : len - pos + 1; } return(lengths); } int[] FindRight(int maxlen) { int scanlen = Core.MinMax.Min(width, maxlen); int[] lengths = new int[height]; for (int iy = 0, pos = width - 1; iy < height; iy++, pos += stride1) { int len = BitUtils.BitScanZeroReverse(scanlen, bits, pos); lengths[iy] = len == -1 ? 0 : pos - len + 1; } return(lengths); } int[] FindTop(int maxlen) { int scanlen = Core.MinMax.Min(height, maxlen); int[] lengths = Vectors.Create(width, scanlen); for (int ix = 0; ix < width; ix++) { ulong mask = BitUtils.SetBit(0ul, ix & 63); for (int iy = 0, off = ix >> 6; iy < scanlen; iy++, off += stride) { if ((bits[off] & mask) == 0) { lengths[ix] = iy; break; } } } return(lengths); } int[] FindBottom(int maxlen) { int scanlen = Core.MinMax.Min(height, maxlen); int[] lengths = Vectors.Create(width, scanlen); int size = stride * height; for (int ix = 0; ix < width; ix++) { ulong mask = BitUtils.SetBit(0ul, ix & 63); for (int iy = 0, off = size - stride + (ix >> 6); iy < scanlen; iy++, off -= stride) { if ((bits[off] & mask) == 0) { lengths[ix] = iy; break; } } } return(lengths); } void ClearLeft(int[] lengths) { for (int iy = 0, off = 0; iy < height; iy++, off += stride1) { int len = lengths[iy]; if (len != 0) { BitUtils.ResetBits(len, bits, off); } } } void ClearRight(int[] lengths) { for (int iy = 0, off = width; iy < height; iy++, off += stride1) { int len = lengths[iy]; if (len != 0) { BitUtils.ResetBits(len, bits, off - len); } } } void ClearTop(int[] lengths) { for (int ix = 0; ix < width; ix++) { int len = lengths[ix]; if (len != 0) { ulong mask = ~BitUtils.SetBit(0ul, ix & 63); Vectors.AndC(len, mask, bits, ix >> 6, stride); } } } void ClearBottom(int[] lengths) { int size = stride * height; for (int ix = 0; ix < width; ix++) { int len = lengths[ix]; if (len != 0) { ulong mask = ~BitUtils.SetBit(0ul, ix & 63); Vectors.AndC(len, mask, bits, size - (len * stride) + (ix >> 6), stride); } } } }