Example #1
0
        private protected void AllocateBits(int width, int height, int bitsPerPixel)
        {
            if (width <= 0)
            {
                throw new ArgumentException(Properties.Resources.E_InvalidWidth, nameof(width));
            }

            if (height <= 0)
            {
                throw new ArgumentException(Properties.Resources.E_InvalidHeight, nameof(height));
            }

            if (this.Width == width && this.Height == height && this.BitsPerPixel == bitsPerPixel)
            {
                // nothing to do
                // already allocated
                return;
            }

            this.Width        = width;
            this.Height       = height;
            this.BitsPerPixel = bitsPerPixel;
            this.Stride       = Image <T> .CalculateStride(width, bitsPerPixel);

            int length = this.Stride * height;

            if (this.Bits?.Length != length)
            {
                this.Bits = new T[length];
            }
        }
Example #2
0
 public void SetColor(uint color)
 {
     if (this.BitsPerPixel == 24)
     {
         byte bcolor = (byte)(color & 0xff);
         if (bcolor == (byte)((color >> 8) & 0xff) && bcolor == (byte)((color >> 16) & 0xff))
         {
             // all components are the same - set bytes
             unsafe
             {
                 fixed(ulong *bits = this.Bits)
                 {
                     Vectors.Set(this.Height * this.Stride8, bcolor, (byte *)bits);
                 }
             }
         }
         else
         {
             ulong[] colors = this.ColorScanline(Image.CalculateStride(this.Width, 24), color);
             Vectors.Tile(this.Stride, this.Height, colors, 0, this.Bits, 0);
         }
     }
     else
     {
         Vectors.Set(this.Bits.Length, this.ColorBits(color), this.Bits, 0);
     }
 }
Example #3
0
        public void DrawRectangle(int x, int y, int width, int height, uint color)
        {
            this.ValidateArea(x, y, width, height);

            if (width == 0 || height == 0)
            {
                // nothing to draw
                return;
            }

            ulong[] bits         = this.Bits;
            int     bitsPerPixel = this.BitsPerPixel;

            if (bitsPerPixel == 24)
            {
                ulong[] colors  = this.ColorScanline(Image.CalculateStride(width, 24), color);
                int     stride8 = this.Stride8;

                unsafe
                {
                    fixed(ulong *ubits = &bits[y * this.Stride], ucolors = colors)
                    {
                        byte *ptrcolors = (byte *)ucolors;
                        byte *ptrbits   = (byte *)ubits + (x * 3);

                        // draw top
                        Vectors.Copy(width * 3, ptrcolors, ptrbits);
                        ptrbits += stride8;

                        // draw left and right
                        for (int i = 1, ii = height - 1; i < ii; i++, ptrbits += stride8)
                        {
                            Vectors.Copy(3, ptrcolors, ptrbits);
                            Vectors.Copy(3, ptrcolors, ptrbits + (width * 3));
                        }

                        // draw bottom
                        Vectors.Copy(width * 3, ptrcolors, ptrbits);
                    }
                }
            }
            else
            {
                int   stride1   = this.Stride1;
                ulong colorbits = this.ColorBits(color);

                // draw top
                int pos = (y * stride1) + (x * bitsPerPixel);
                BitUtils.SetBits(width * bitsPerPixel, colorbits, bits, pos);
                pos += stride1;

                // draw left and right
                int posend = pos + (width * bitsPerPixel);
                for (int i = 1, ii = height - 1; i < ii; i++, pos += stride1, posend += stride1)
                {
                    BitUtils.SetBits(bitsPerPixel, colorbits, bits, pos);
                    BitUtils.SetBits(bitsPerPixel, colorbits, bits, posend);
                }

                // draw bottom
                BitUtils.SetBits(width * bitsPerPixel, colorbits, bits, pos);
            }
        }
Example #4
0
        public void SetBorder(int x, int y, int width, int height, BorderType borderType, uint borderValue)
        {
            this.ValidateArea(x, y, width, height);

            if (x == 0 && y == 0 && width == this.Width && height == this.Height)
            {
                // nothing to set
                return;
            }

            if (borderType == BorderType.BorderRepl)
            {
                if (width == 0 || height == 0)
                {
                    // if border occupies entire image - set entire image to color of the pixel at specified origin
                    this.SetColor(this.GetPixel(x, y));
                    return;
                }

                ulong[] bits         = this.Bits;
                int     stride       = this.Stride;
                int     stride1      = this.Stride1;
                int     bitsPerPixel = this.BitsPerPixel;

                if (bitsPerPixel == 24)
                {
                    // fill left and right sides
                    int x2 = x + width;
                    if (x > 0 || x2 < this.Width)
                    {
                        unsafe
                        {
                            fixed(ulong *ubits = &bits[y *stride])
                            {
                                byte *bbits = (byte *)ubits;

                                for (int i = 0, count2 = this.Width - x2, stride8 = this.Stride8; i < height; i++, bbits += stride8)
                                {
                                    if (x > 0)
                                    {
                                        Vectors.Tile(3, x, bbits + (x * 3), bbits);
                                    }

                                    if (count2 > 0)
                                    {
                                        Vectors.Tile(3, count2, bbits + (x2 * 3) - 3, bbits + (x2 * 3));
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    // fill left side
                    if (x > 0)
                    {
                        // sets all pixels on the left to first row pixel within the area
                        int count = x * bitsPerPixel;
                        for (int i = y, ii = y + height, pos = y * stride1; i < ii; i++, pos += stride1)
                        {
                            ulong ucolor = this.ColorBits(this.GetPixel(x, i));
                            BitUtils.SetBits(count, ucolor, bits, pos);
                        }
                    }

                    // fill right side
                    int x2 = x + width;
                    if (x2 < this.Width)
                    {
                        // sets all pixels on the left to last row pixel within the area
                        int count = (this.Width - x2) * bitsPerPixel;
                        for (int i = y, ii = y + height, pos = (y * stride1) + (x2 * bitsPerPixel); i < ii; i++, pos += stride1)
                        {
                            ulong ucolor = this.ColorBits(this.GetPixel(x2 - 1, i));
                            BitUtils.SetBits(count, ucolor, bits, pos);
                        }
                    }
                }

                // fill top
                if (y > 0)
                {
                    // copy first area row to all rows above
                    Vectors.Tile(stride, y, bits, y * stride, bits, 0);
                }

                // fill bottom
                int y2 = y + height;
                if (y2 < this.Height)
                {
                    // copy last area row to all rows below
                    Vectors.Tile(stride, this.Height - y2, bits, (y2 - 1) * stride, bits, y2 * stride);
                }
            }
            else if (borderType == BorderType.BorderConst)
            {
                if (width == 0 || height == 0)
                {
                    // if border occupies entire image - set entire image to specified color
                    this.SetColor(borderValue);
                    return;
                }

                ulong[] bits         = this.Bits;
                int     stride       = this.Stride;
                int     bitsPerPixel = this.BitsPerPixel;

                if (bitsPerPixel == 24)
                {
                    ulong[] colors = this.ColorScanline(Image.CalculateStride(this.Width, 24), borderValue);

                    // fill top
                    if (y > 0)
                    {
                        Vectors.Tile(stride, y, colors, 0, bits, 0);
                    }

                    // fill left and right
                    int x2 = x + width;
                    if (x > 0 || x2 < this.Width)
                    {
                        unsafe
                        {
                            fixed(ulong *ubits = &bits[y *stride], ucolors = colors)
                            {
                                byte *bbits   = (byte *)ubits;
                                byte *bcolors = (byte *)ucolors;

                                for (int i = 0, count1 = x * 3, count2 = (this.Width - x2) * 3, stride8 = this.Stride8; i < height; i++, bbits += stride8)
                                {
                                    if (count1 > 0)
                                    {
                                        Vectors.Copy(count1, bcolors, bbits);
                                    }

                                    if (count2 > 0)
                                    {
                                        Vectors.Copy(count2, bcolors + (x2 * 3), bbits + (x2 * 3));
                                    }
                                }
                            }
                        }
                    }

                    // fill bottom
                    int y2 = y + height;
                    if (y2 < this.Height)
                    {
                        Vectors.Tile(stride, this.Height - y2, colors, 0, bits, y2 * stride);
                    }
                }
                else
                {
                    int   stride1 = this.Stride1;
                    ulong color   = this.ColorBits(borderValue);

                    int x2 = x + width;
                    int y2 = y + height;

                    // fill top area and the left part of first partial stride
                    int count = (y * stride1) + (x * bitsPerPixel);
                    int pos   = 0;
                    if (count > 0)
                    {
                        BitUtils.SetBits(count, color, bits, pos);
                    }

                    // fill partial strides (together right part and left part of the next line)
                    if (height > 1)
                    {
                        count = stride1 - (width * bitsPerPixel);
                        if (count > 0)
                        {
                            pos = (y * stride1) + (x2 * bitsPerPixel);
                            for (int i = 1; i < height; i++, pos += stride1)
                            {
                                BitUtils.SetBits(count, color, bits, pos);
                            }
                        }
                    }

                    // fill bottom area and the right part of last partial stride
                    pos   = ((y2 - 1) * stride1) + (x2 * bitsPerPixel);
                    count = (this.Height * stride1) - pos;
                    if (count > 0)
                    {
                        BitUtils.SetBits(count, color, bits, pos);
                    }
                }
            }
        }
Example #5
0
        public void SetColor(int x, int y, int width, int height, uint color)
        {
            this.ValidateArea(x, y, width, height);

            if (this.BitsPerPixel == 24)
            {
                byte bcolor = (byte)(color & 0xff);
                if (bcolor == (byte)((color >> 8) & 0xff) && bcolor == (byte)((color >> 16) & 0xff))
                {
                    // all components are the same - set bytes
                    unsafe
                    {
                        fixed(ulong *bits = &this.Bits[y * this.Stride])
                        {
                            byte *bbits = (byte *)bits;

                            if (x == 0 && width == this.Width)
                            {
                                // set multiple scan lines at once
                                // if entire image width has to be set
                                Vectors.Set(height * this.Stride8, bcolor, bbits);
                            }
                            else
                            {
                                bbits += x * 3;
                                for (int i = 0, count = width * 3, stride8 = this.Stride8; i < height; i++, bbits += stride8)
                                {
                                    Vectors.Set(count, bcolor, bbits);
                                }
                            }
                        }
                    }
                }
                else
                {
                    ulong[] colors = this.ColorScanline(Image.CalculateStride(width, 24), color);

                    if (x == 0 && width == this.Width)
                    {
                        // set multiple scan lines at once
                        // if entire image width has to be set
                        Vectors.Tile(this.Stride, height, colors, 0, this.Bits, y * this.Stride);
                    }
                    else
                    {
                        unsafe
                        {
                            fixed(ulong *bits = &this.Bits[y * this.Stride], ucolors = colors)
                            {
                                byte *bbits   = (byte *)bits + (x * 3);
                                byte *bcolors = (byte *)ucolors;

                                for (int i = 0, count = width * 3, stride8 = this.Stride8; i < height; i++, bbits += stride8)
                                {
                                    Vectors.Copy(count, bcolors, bbits);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                ulong   colorbits = this.ColorBits(color);
                ulong[] bits      = this.Bits;

                if (x == 0 && width == this.Width)
                {
                    // set multiple scan lines at once
                    // if entire image width has to be set
                    Vectors.Set(height * this.Stride, colorbits, bits, y * this.Stride);
                }
                else
                {
                    int stride1 = this.Stride1;
                    int count   = width * this.BitsPerPixel;
                    int off     = (y * stride1) + (x * this.BitsPerPixel);

                    if (colorbits == 0)
                    {
                        for (int i = 0; i < height; i++, off += stride1)
                        {
                            BitUtils.ResetBits(count, bits, off);
                        }
                    }
                    else if (colorbits == ulong.MaxValue)
                    {
                        for (int i = 0; i < height; i++, off += stride1)
                        {
                            BitUtils.SetBits(count, bits, off);
                        }
                    }
                    else
                    {
                        for (int i = 0; i < height; i++, off += stride1)
                        {
                            BitUtils.SetBits(count, colorbits, bits, off);
                        }
                    }
                }
            }
        }
Example #6
0
        public void MinC(int x, int y, int width, int height, uint color)
        {
            color &= this.MaxColor;
            if (color == this.MaxColor)
            {
                // nothing to set
                return;
            }

            if (color == 0)
            {
                // set to maximum value
                this.SetToZero(x, y, width, height);
                return;
            }

            this.ValidateArea(x, y, width, height);

            if (width == 0 || height == 0)
            {
                // nothing to set
                return;
            }

            unsafe
            {
                fixed(ulong *bits = &this.Bits[y * this.Stride])
                {
                    switch (this.BitsPerPixel)
                    {
                    case 8:
                    {
                        byte *ptr     = (byte *)bits + x;
                        int   stride8 = this.Stride8;

                        if (x == 0 && width == this.Width)
                        {
                            Vectors.MinC(height * stride8, (byte)color, ptr);
                        }
                        else
                        {
                            for (int i = 0; i < height; i++, ptr += stride8)
                            {
                                Vectors.MinC(width, (byte)color, ptr);
                            }
                        }
                    }

                    break;

                    case 16:
                    {
                        ushort *ptr      = (ushort *)bits + x;
                        int     stride16 = this.Stride8 / sizeof(ushort);

                        if (x == 0 && width == this.Width)
                        {
                            Vectors.MinC(height * stride16, (ushort)color, ptr);
                        }
                        else
                        {
                            for (int i = 0; i < height; i++, ptr += stride16)
                            {
                                Vectors.MinC(width, (ushort)color, ptr);
                            }
                        }
                    }

                    break;

                    case 24:
                    case 32:
                    {
                        int   bytesPerPixel = this.BitsPerPixel / 8;
                        byte *ptr           = (byte *)bits + (x * bytesPerPixel);
                        int   stride8       = this.Stride8;

                        fixed(ulong *mask = this.ColorScanline(Image.CalculateStride(width, this.BitsPerPixel), color))
                        {
                            for (int i = 0, count = width * bytesPerPixel; i < height; i++, ptr += stride8)
                            {
                                Vectors.Min(count, (byte *)mask, ptr);
                            }
                        }
                    }

                    break;

                    default:
                        throw new NotSupportedException(string.Format(
                                                            CultureInfo.InvariantCulture,
                                                            Properties.Resources.E_UnsupportedDepth,
                                                            this.BitsPerPixel));
                    }
                }
            }
        }