示例#1
0
        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));
                    }
                }
            }
        }
示例#2
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));
                }
            }
        }
示例#3
0
        /// <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);
            }
        }