public void BitsOrTest() { 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] = 0; BitUtils.SetBits(1, x, posx + pos); y[0] = y[1] = y[2] = 0; BitUtils.Or(count, x, posx, y, posy); Assert.AreEqual(posy + pos, BitUtils.BitScanOneForward(Size, y, 0)); } // shift right for (int posx = 0; posx < Size - count; posx++) { x[0] = x[1] = x[2] = 0; BitUtils.SetBits(1, x, posx + pos); int posy = Size - count; y[0] = y[1] = y[2] = 0; BitUtils.Or(count, x, posx, y, posy); Assert.AreEqual(posy + pos, BitUtils.BitScanOneForward(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> /// Returns the area on this <see cref="Image"/> that contains black pixels. /// </summary> /// <returns> /// The <see cref="Rectangle"/> that describes the area of the image that contains black pixels; /// <b>Rectangle.Empty</b> if the image does not have black pixels. /// </returns> /// <exception cref="NotSupportedException"> /// The image is not black-and-white. /// </exception> /// <remarks> /// This method supports black-and-white images only and will throw an exception if called on gray-scale or color images. /// </remarks> public Rectangle BlackArea() { if (this.BitsPerPixel != 1) { throw new NotSupportedException(Properties.Resources.E_UnsupportedDepth_1bpp); } int width = this.Width; int height = this.Height; int stride1 = this.Stride1; int stride = this.Stride; ulong[] bits = this.Bits; // calculate top int top = FindTop(); if (top < 0) { return(Rectangle.Empty); } // calculate bottom int bottom = FindBottom(); if (bottom < top) { throw new InvalidOperationException("Something went wrong."); } // calculate left ulong endMask = this.EndMask; int left = FindLeft(out int leftColumn, out ulong leftMask); if (left == -1) { throw new InvalidOperationException("Something went wrong."); } // calculate right int right = FindRight(); if (right < left) { throw new InvalidOperationException("Something went wrong."); } return(Rectangle.FromLTRB(left, top, right + 1, bottom + 1)); int FindTop() { for (int i = 0, off = 0; i < height; i++, off += stride1) { if (BitUtils.BitScanOneForward(width, bits, off) != -1) { return(i); } } return(-1); } int FindBottom() { for (int i = height - 1, off = i * stride1; i >= 0; i--, off -= stride1) { if (BitUtils.BitScanOneForward(width, bits, off) != -1) { return(i); } } return(-1); } int FindLeft(out int resultColumn, out ulong resultMask) { resultColumn = 0; resultMask = 0; for (int i = 0; i < stride; i++) { ulong mask = ColumnBlackMask(i); if (mask != 0ul) { resultColumn = i; resultMask = mask; return((i * 64) + BitUtils.BitScanOneForward(mask)); } } return(-1); } int FindRight() { for (int i = stride - 1; i >= 0; i--) { ulong mask = i == leftColumn ? leftMask : ColumnBlackMask(i); if (mask != 0ul) { return((i * 64) + BitUtils.BitScanOneReverse(mask)); } } return(-1); } ulong ColumnBlackMask(int column) { ulong mask = 0; for (int i = top, off = (i * stride) + column; i <= bottom; i++, off += stride) { mask |= bits[off]; } if (column == stride - 1) { mask &= endMask; } return(mask); } }