Beispiel #1
0
        private static IntPtr Allocate(long bytes, bool allowRetry)
        {
            IntPtr block;

            try
            {
                if (bytes >= largeBlockThreshold)
                {
                    block = PlatformMemory.AllocateLarge((ulong)bytes);
                }
                else
                {
                    block = PlatformMemory.Allocate((ulong)bytes);
                }
            }

            catch (OutOfMemoryException)
            {
                if (allowRetry)
                {
                    PixelUtils.GCFullCollect();
                    return(Allocate(bytes, false));
                }
                else
                {
                    throw;
                }
            }

            return(block);
        }
Beispiel #2
0
            public override void BeforeRender()
            {
                PointF vec = new PointF(EndPoint.X - StartPoint.X, EndPoint.Y - StartPoint.Y);
                float  mag = PixelUtils.Magnitude(vec);

                if (EndPoint.X == StartPoint.X)
                {
                    _dtdx = 0;
                }
                else
                {
                    _dtdx = vec.X / (mag * mag);
                }

                if (EndPoint.Y == StartPoint.Y)
                {
                    _dtdy = 0;
                }
                else
                {
                    _dtdy = vec.Y / (mag * mag);
                }

                base.BeforeRender();
            }
Beispiel #3
0
 internal static string ErrorMessage(
     int sourceWidth, int sourceHeight, PixelFormat sourcePixelFormat,
     int destWidth, int destHeight, PixelFormat destPixelFormat,
     ScaleFlag flags) =>
 string.Format("Impossible to create scale context for the conversion fmt:{0} s:{1}x{2} -> fmt:{3} s:{4}x{5} (sws_flags: {6})",
               PixelUtils.GetPixelFormatName(sourcePixelFormat), sourceWidth, sourceHeight,
               PixelUtils.GetPixelFormatName(destPixelFormat), destWidth, destHeight, flags);
Beispiel #4
0
        /// <summary>
        /// Smoothly blends between two colors.
        /// </summary>
        public static ColorBgra Blend(ColorBgra ca, ColorBgra cb, byte cbAlpha)
        {
            uint caA  = (uint)PixelUtils.FastScaleByteByByte((byte)(255 - cbAlpha), ca.A);
            uint cbA  = (uint)PixelUtils.FastScaleByteByByte(cbAlpha, cb.A);
            uint cbAT = caA + cbA;

            uint r;
            uint g;
            uint b;

            if (cbAT == 0)
            {
                r = 0;
                g = 0;
                b = 0;
            }
            else
            {
                r = ((ca.R * caA) + (cb.R * cbA)) / cbAT;
                g = ((ca.G * caA) + (cb.G * cbA)) / cbAT;
                b = ((ca.B * caA) + (cb.B * cbA)) / cbAT;
            }

            return(ColorBgra.FromBgra((byte)b, (byte)g, (byte)r, (byte)cbAT));
        }
            public ColorBgra Apply(float r, float g, float b)
            {
                ColorBgra ret = new ColorBgra();

                float[] input = new float[] { b, g, r };

                for (int i = 0; i < 3; i++)
                {
                    float v = (input[i] - colorInLow[i]);

                    if (v < 0)
                    {
                        ret[i] = colorOutLow[i];
                    }
                    else if (v + colorInLow[i] >= colorInHigh[i])
                    {
                        ret[i] = colorOutHigh[i];
                    }
                    else
                    {
                        ret[i] = (byte)PixelUtils.Clamp(
                            colorOutLow[i] + (colorOutHigh[i] - colorOutLow[i]) * Math.Pow(v / (colorInHigh[i] - colorInLow[i]), gamma[i]),
                            0.0f,
                            255.0f);
                    }
                }

                return(ret);
            }
            public override ColorBgra Apply(ColorBgra color)
            {
                //adjust saturation
                byte intensity = color.GetIntensityByte();

                color.R = PixelUtils.ClampToByte((intensity * 1024 + (color.R - intensity) * satFactor) >> 10);
                color.G = PixelUtils.ClampToByte((intensity * 1024 + (color.G - intensity) * satFactor) >> 10);
                color.B = PixelUtils.ClampToByte((intensity * 1024 + (color.B - intensity) * satFactor) >> 10);

                HsvColor hsvColor = HsvColor.FromColor(color.ToColor());
                int      hue      = hsvColor.Hue;

                hue += hueDelta;

                while (hue < 0)
                {
                    hue += 360;
                }

                while (hue > 360)
                {
                    hue -= 360;
                }

                hsvColor.Hue = hue;

                ColorBgra newColor = ColorBgra.FromColor(hsvColor.ToColor());

                newColor   = blendOp.Apply(newColor);
                newColor.A = color.A;

                return(newColor);
            }
Beispiel #7
0
 /// <summary>
 /// Creates a new ColorBgra instance with the given color and alpha values.
 /// </summary>
 public static ColorBgra FromBgraClamped(float b, float g, float r, float a)
 {
     return(FromBgra(
                PixelUtils.ClampToByte(b),
                PixelUtils.ClampToByte(g),
                PixelUtils.ClampToByte(r),
                PixelUtils.ClampToByte(a)));
 }
Beispiel #8
0
 /// <summary>
 /// Creates a new ColorBgra instance with the given color and alpha values.
 /// </summary>
 public static ColorBgra FromBgraClamped(int b, int g, int r, int a)
 {
     return(FromBgra(
                PixelUtils.ClampToByte(b),
                PixelUtils.ClampToByte(g),
                PixelUtils.ClampToByte(r),
                PixelUtils.ClampToByte(a)));
 }
Beispiel #9
0
        /// <inheritdoc/>
        public byte[] Decompress(byte[] blockData, int width, int height)
        {
            IBlock self = this;

            byte[] alpha  = new byte[8];
            var    colors = new ImageSharp.PixelFormats.Rgb24[4];

            return(Helper.InMemoryDecode <Dxt5>(blockData, width, height, (stream, data, streamIndex, dataIndex, stride) =>
            {
                streamIndex = Bc5.ExtractGradient(alpha, blockData, streamIndex);

                ulong alphaCodes = blockData[streamIndex++];
                alphaCodes |= (ulong)blockData[streamIndex++] << 8;
                alphaCodes |= (ulong)blockData[streamIndex++] << 16;
                alphaCodes |= (ulong)blockData[streamIndex++] << 24;
                alphaCodes |= (ulong)blockData[streamIndex++] << 32;
                alphaCodes |= (ulong)blockData[streamIndex++] << 40;

                // Colors are stored in a pair of 16 bits.
                ushort color0 = blockData[streamIndex++];
                color0 |= (ushort)(blockData[streamIndex++] << 8);

                ushort color1 = blockData[streamIndex++];
                color1 |= (ushort)(blockData[streamIndex++] << 8);

                // Extract R5G6B5.
                PixelUtils.ExtractR5G6B5(color0, ref colors[0]);
                PixelUtils.ExtractR5G6B5(color1, ref colors[1]);

                colors[2].R = (byte)(((2 * colors[0].R) + colors[1].R) / 3);
                colors[2].G = (byte)(((2 * colors[0].G) + colors[1].G) / 3);
                colors[2].B = (byte)(((2 * colors[0].B) + colors[1].B) / 3);

                colors[3].R = (byte)((colors[0].R + (2 * colors[1].R)) / 3);
                colors[3].G = (byte)((colors[0].G + (2 * colors[1].G)) / 3);
                colors[3].B = (byte)((colors[0].B + (2 * colors[1].B)) / 3);

                for (int alphaShift = 0; alphaShift < 48; alphaShift += 12)
                {
                    byte rowVal = blockData[streamIndex++];
                    for (int j = 0; j < 4; j++)
                    {
                        // 3 bits determine alpha index to use.
                        byte alphaIndex = (byte)((alphaCodes >> (alphaShift + (3 * j))) & 0x07);
                        ImageSharp.PixelFormats.Rgb24 col = colors[(rowVal >> (j * 2)) & 0x03];
                        data[dataIndex++] = col.R;
                        data[dataIndex++] = col.G;
                        data[dataIndex++] = col.B;
                        data[dataIndex++] = alpha[alphaIndex];
                    }

                    dataIndex += self.PixelDepthBytes * (stride - self.DivSize);
                }

                return streamIndex;
            }));
        }
            public void SetGamma(int index, float val)
            {
                if (index < 0 || index >= 3)
                {
                    throw new ArgumentOutOfRangeException("index", index, "Index must be between 0 and 2");
                }

                gamma[index] = PixelUtils.Clamp(val, 0.1f, 10.0f);
                UpdateLookupTable();
            }
Beispiel #11
0
        public Pixel Map(ISourceData data)
        {
            Pixel p = data.GetPixel(0, 0);
            int   r = PixelUtils.Clamp((int)((255.0 * Math.Pow(p.R / 255.0, 1.0 / _gammaCorrection)) + 0.5), 255, 0);
            int   g = PixelUtils.Clamp((int)((255.0 * Math.Pow(p.G / 255.0, 1.0 / _gammaCorrection)) + 0.5), 255, 0);
            int   b = PixelUtils.Clamp((int)((255.0 * Math.Pow(p.B / 255.0, 1.0 / _gammaCorrection)) + 0.5), 255, 0);
            int   a = PixelUtils.Clamp((int)((255.0 * Math.Pow(p.A / 255.0, 1.0 / _gammaCorrection)) + 0.5), 255, 0);

            return(new Pixel(r, g, b, a));
        }
        /// <summary>
        /// Provides the interface for merging two bitmaps together.
        /// </summary>
        /// <param name="bitmapA">The first bitmap for the merge</param>
        /// <param name="bitmapB">The second bitmap for the merge</param>
        /// <returns>The resulting bitmap</returns>
        public Bitmap Merge(Bitmap bitmapA, Bitmap bitmapB)
        {
            // Build the storage for the resulting bitmap
            PixelFormat pixelFormat     = bitmapA.PixelFormat;
            Bitmap      resultingBitmap = new Bitmap(bitmapA.Width, bitmapA.Height, pixelFormat);

            // Perform the merge
            for (int w = 0; w < bitmapA.Width; w++)
            {
                for (int h = 0; h < bitmapA.Height; h++)
                {
                    Color pixelA = bitmapA.GetPixel(w, h);
                    Color pixelB = bitmapB.GetPixel(w, h);

                    if (!PixelUtils.ColorWithinThresholdOfWhite(pixelA, WhiteThreshold))
                    {
                        // Set to the average of the two pixels
                        if (PixelUtils.ColorsAreClose(pixelA, pixelB, LikenessThreshold))
                        {
                            resultingBitmap.SetPixel(w, h, pixelA);
                        }
                        else
                        {
                            int   brightnessA = PixelUtils.GetBrightness(pixelA);
                            int   brightnessB = PixelUtils.GetBrightness(pixelB);
                            Color blendedPixel;

                            // Determine which order to blend the pixels in
                            if (brightnessA > brightnessB)
                            {
                                blendedPixel = BlendPixels(pixelB, pixelA, BlendAmount);
                            }
                            else
                            {
                                blendedPixel = BlendPixels(pixelA, pixelB, BlendAmount);
                            }
                            resultingBitmap.SetPixel(w, h, blendedPixel);
                        }
                    }
                    else if (!PixelUtils.ColorWithinThresholdOfWhite(pixelA, WhiteThreshold))
                    {
                        // PixelA has valid data, copy it
                        resultingBitmap.SetPixel(w, h, pixelA);
                    }
                    else
                    {
                        // Just set this pixel to the value of pixelB
                        resultingBitmap.SetPixel(w, h, pixelB);
                    }
                }
            }

            return(resultingBitmap);
        }
        protected override void InverseTransform(ref TransformData data)
        {
            double x = data.X;
            double y = data.Y;

            // NOTE: when x and y are zero, this will divide by zero and return NaN
            double invertDistance = PixelUtils.Lerp(1d, DefaultRadius2 / ((x * x) + (y * y)), amount);

            data.X = x * invertDistance;
            data.Y = y * invertDistance;
        }
Beispiel #14
0
        /// <summary>
        /// Linearly interpolates between two color values.
        /// </summary>
        /// <param name="from">The color value that represents 0 on the lerp number line.</param>
        /// <param name="to">The color value that represents 1 on the lerp number line.</param>
        /// <param name="frac">A value in the range [0, 1].</param>
        /// <remarks>
        /// This method does a simple lerp on each color value and on the alpha channel. It does
        /// not properly take into account the alpha channel's effect on color blending.
        /// </remarks>
        public static ColorBgra Lerp(ColorBgra from, ColorBgra to, double frac)
        {
            ColorBgra ret = new ColorBgra();

            ret.B = (byte)PixelUtils.ClampToByte(PixelUtils.Lerp(from.B, to.B, frac));
            ret.G = (byte)PixelUtils.ClampToByte(PixelUtils.Lerp(from.G, to.G, frac));
            ret.R = (byte)PixelUtils.ClampToByte(PixelUtils.Lerp(from.R, to.R, frac));
            ret.A = (byte)PixelUtils.ClampToByte(PixelUtils.Lerp(from.A, to.A, frac));

            return(ret);
        }
Beispiel #15
0
            public override float BoundLerp(float t)
            {
                if (t > 1)
                {
                    t -= 2;
                }
                else if (t < -1)
                {
                    t += 2;
                }

                return(PixelUtils.Clamp(Math.Abs(t), 0, 1));
            }
Beispiel #16
0
            public override void BeforeRender()
            {
                float distanceScale = PixelUtils.Distance(this.StartPoint, this.EndPoint);

                if (distanceScale == 0)
                {
                    _invDistanceScale = 0;
                }
                else
                {
                    _invDistanceScale = 1.0f / distanceScale;
                }

                base.BeforeRender();
            }
Beispiel #17
0
        public void Apply(Surface surface, RectangleF[] roiF, int startIndex, int length)
        {
            Rectangle regionBounds = Rectangle.Truncate(PixelUtils.GetRegionBounds(roiF, startIndex, length));

            if (regionBounds != Rectangle.Intersect(surface.Bounds, regionBounds))
            {
                throw new ArgumentOutOfRangeException("roiF", "Region is out of bounds");
            }

            unsafe
            {
                for (int x = startIndex; x < startIndex + length; ++x)
                {
                    ApplyRectangle(surface, Rectangle.Truncate(roiF[x]));
                }
            }
        }
Beispiel #18
0
        /// <summary>
        /// Determines if a tile is complete.
        /// </summary>
        /// <returns>True if complete, else false</returns>
        public bool IsComplete()
        {
            Bitmap tileImage = GetBitmap();
            int width = tileImage.Width;
            int height = tileImage.Height;

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    Color currentPixel = tileImage.GetPixel(x, y);
                    if (PixelUtils.ColorWithinThresholdOfWhite(currentPixel, 5))
                        return false;
                }
            }
            return true;
        }
            public static Level AutoFromLoMdHi(ColorBgra lo, ColorBgra md, ColorBgra hi)
            {
                float[] gamma = new float[3];

                for (int i = 0; i < 3; i++)
                {
                    if (lo[i] < md[i] && md[i] < hi[i])
                    {
                        gamma[i] = (float)PixelUtils.Clamp(Math.Log(0.5, (float)(md[i] - lo[i]) / (float)(hi[i] - lo[i])), 0.1, 10.0);
                    }
                    else
                    {
                        gamma[i] = 1.0f;
                    }
                }

                return(new Level(lo, hi, gamma, ColorBgra.FromColor(Color.Black), ColorBgra.FromColor(Color.White)));
            }
        public void SetParameters(double angle, int distance, bool centered)
        {
            this.angle    = angle;
            this.distance = distance;
            this.centered = centered;


            float start_x = 0, start_y = 0;

            double theta = ((double)(angle + 180) * 2 * Math.PI) / 360.0;
            double alpha = (double)distance;

            float end_x = (float)(alpha * Math.Cos(theta));
            float end_y = (float)(alpha * Math.Sin(theta));

            if (centered)
            {
                start_x = -end_x / 2.0f;
                start_y = -end_y / 2.0f;

                end_x /= 2.0f;
                end_y /= 2.0f;
            }

            this.points = new PointF[((1 + distance) * 3) / 2];

            if (this.points.Length == 1)
            {
                this.points[0] = new PointF(0, 0);
            }
            else
            {
                for (int i = 0; i < this.points.Length; ++i)
                {
                    float frac = (float)i / (float)(this.points.Length - 1);
                    this.points[i] = PixelUtils.Lerp(
                        new PointF(start_x, start_y),
                        new PointF(end_x, end_y),
                        frac);
                }
            }
        }
Beispiel #21
0
        public Pixel Map(ISourceData data)
        {
            double factor = _amount;

            Pixel[,] pixelMatrix = PixelUtils.GetPixelMatrix(data, 1);

            if (factor > 10)
            {
                factor = 10;
            }
            if (factor <= 0)
            {
                factor = 0.1d;
            }

            bias = 2.0;
            int red   = 0;
            int green = 0;
            int blue  = 0;

            int dimLength = pixelMatrix.GetLength(0);

            for (int x = 0; x < dimLength; x++)
            {
                for (int y = 0; y < dimLength; y++)
                {
                    red   += pixelMatrix[x, y].R * filterMatrix[x, y];
                    green += pixelMatrix[x, y].G * filterMatrix[x, y];
                    blue  += pixelMatrix[x, y].B * filterMatrix[x, y];
                }
            }

            int r = PixelUtils.Clamp((int)((factor * red) + bias), 255, 0);
            int g = PixelUtils.Clamp((int)((factor * green) + bias), 255, 0);
            int b = PixelUtils.Clamp((int)((factor * blue) + bias), 255, 0);

            return(new Pixel(r, g, b, pixelMatrix[1, 1].A));
        }
Beispiel #22
0
        private static double Noise(byte ix, byte iy, double x, double y, byte seed)
        {
            double u = Fade(x);
            double v = Fade(y);

            int a  = permuteLookup[ix + seed] + iy;
            int aa = permuteLookup[a];
            int ab = permuteLookup[a + 1];
            int b  = permuteLookup[ix + 1 + seed] + iy;
            int ba = permuteLookup[b];
            int bb = permuteLookup[b + 1];

            double gradAA = Grad(permuteLookup[aa], x, y);
            double gradBA = Grad(permuteLookup[ba], x - 1, y);

            double edge1 = PixelUtils.Lerp(gradAA, gradBA, u);

            double gradAB = Grad(permuteLookup[ab], x, y - 1);
            double gradBB = Grad(permuteLookup[bb], x - 1, y - 1);

            double edge2 = PixelUtils.Lerp(gradAB, gradBB, u);

            return(PixelUtils.Lerp(edge1, edge2, v));
        }
        public void SetParameters(double angle, int distance, bool centered)
        {
            this.angle    = angle;
            this.distance = distance;
            this.centered = centered;
            PointF start = new PointF(0, 0);
            double theta = ((double)(angle + 180) * 2 * Math.PI) / 360.0;
            double alpha = (double)distance;
            double x     = alpha * Math.Cos(theta);
            double y     = alpha * Math.Sin(theta);
            PointF end   = new PointF((float)x, (float)(-y));

            if (centered)
            {
                start.X = -end.X / 2.0f;
                start.Y = -end.Y / 2.0f;

                end.X /= 2.0f;
                end.Y /= 2.0f;
            }

            this.points = new PointF[((1 + distance) * 3) / 2];

            if (this.points.Length == 1)
            {
                this.points[0] = new PointF(0, 0);
            }
            else
            {
                for (int i = 0; i < this.points.Length; ++i)
                {
                    float frac = (float)i / (float)(this.points.Length - 1);
                    this.points[i] = PixelUtils.Lerp(start, end, frac);
                }
            }
        }
Beispiel #24
0
        private static IntPtr Allocate(int width, int height, out IntPtr handle, bool allowRetry)
        {
            IntPtr block;

            try
            {
                block = PlatformMemory.AllocateBitmap(width, height, out handle);
            }

            catch (OutOfMemoryException)
            {
                if (allowRetry)
                {
                    PixelUtils.GCFullCollect();
                    return(Allocate(width, height, out handle, false));
                }
                else
                {
                    throw;
                }
            }

            return(block);
        }
Beispiel #25
0
        public override void Render(Surface src, Surface dest, Rectangle[] rois, int startIndex, int length)
        {
            unsafe
            {
                int    w          = dest.Width;
                int    h          = dest.Height;
                double invH       = 1.0 / h;
                double invZoom    = 1.0 / _zoom;
                double invQuality = 1.0 / _quality;
                double aspect     = (double)h / (double)w;
                int    count      = _quality * _quality + 1;
                double invCount   = 1.0 / (double)count;

                for (int ri = startIndex; ri < startIndex + length; ++ri)
                {
                    Rectangle rect = rois[ri];

                    for (int y = rect.Top; y < rect.Bottom; y++)
                    {
                        ColorBgra *dstPtr = dest.GetPointAddressUnchecked(rect.Left, y);

                        for (int x = rect.Left; x < rect.Right; x++)
                        {
                            int r = 0;
                            int g = 0;
                            int b = 0;
                            int a = 0;

                            for (double i = 0; i < count; i++)
                            {
                                double u = (2.0 * x - w + (i * invCount)) * invH;
                                double v = (2.0 * y - h + ((i * invQuality) % 1)) * invH;

                                double radius  = Math.Sqrt((u * u) + (v * v));
                                double radiusP = radius;
                                double theta   = Math.Atan2(v, u);
                                double thetaP  = theta + _angleTheta;

                                double uP = radiusP * Math.Cos(thetaP);
                                double vP = radiusP * Math.Sin(thetaP);

                                double jX = (uP - vP * aspect) * invZoom;
                                double jY = (vP + uP * aspect) * invZoom;

                                double j = Julia(jX, jY, JR, JI);

                                double c = _factor * j;


                                b += PixelUtils.ClampToByte(c - 768);
                                g += PixelUtils.ClampToByte(c - 512);
                                r += PixelUtils.ClampToByte(c - 256);
                                a += PixelUtils.ClampToByte(c - 0);
                            }

                            *dstPtr = ColorBgra.FromBgra(
                                PixelUtils.ClampToByte(b / count),
                                PixelUtils.ClampToByte(g / count),
                                PixelUtils.ClampToByte(r / count),
                                PixelUtils.ClampToByte(a / count));

                            ++dstPtr;
                        }
                    }
                }
            }
        }
Beispiel #26
0
 public override float BoundLerp(float t)
 {
     return(PixelUtils.Clamp(t, 0, 1));
 }
Beispiel #27
0
 public override float BoundLerp(float t)
 {
     return(PixelUtils.Clamp(Math.Abs(t), 0, 1));
 }
        public override void Render(Surface src, Surface dst, Rectangle[] rois, int startIndex, int length)
        {
            unsafe
            {
                // Glow backgound
                glowRenderer.Render(src, dst, rois, startIndex, length);

                // Create black outlines by finding the edges of objects

                for (int i = startIndex; i < startIndex + length; ++i)
                {
                    Rectangle roi = rois[i];

                    for (int y = roi.Top; y < roi.Bottom; ++y)
                    {
                        int top    = y - radius;
                        int bottom = y + radius + 1;

                        if (top < 0)
                        {
                            top = 0;
                        }

                        if (bottom > dst.Height)
                        {
                            bottom = dst.Height;
                        }

                        ColorBgra *srcPtr = src.GetPointAddress(roi.X, y);
                        ColorBgra *dstPtr = src.GetPointAddress(roi.X, y);

                        for (int x = roi.Left; x < roi.Right; ++x)
                        {
                            int left  = x - radius;
                            int right = x + radius + 1;

                            if (left < 0)
                            {
                                left = 0;
                            }

                            if (right > dst.Width)
                            {
                                right = dst.Width;
                            }

                            int r = 0;
                            int g = 0;
                            int b = 0;

                            for (int v = top; v < bottom; v++)
                            {
                                ColorBgra *pRow = src.GetRowAddress(v);
                                int        j    = v - y + radius;

                                for (int u = left; u < right; u++)
                                {
                                    int i1 = u - x + radius;
                                    int w  = conv[j][i1];

                                    ColorBgra *pRef = pRow + u;

                                    r += pRef->R * w;
                                    g += pRef->G * w;
                                    b += pRef->B * w;
                                }
                            }

                            ColorBgra topLayer = ColorBgra.FromBgr(
                                PixelUtils.ClampToByte(b),
                                PixelUtils.ClampToByte(g),
                                PixelUtils.ClampToByte(r));

                            // Desaturate
                            topLayer = this.desaturateOp.Apply(topLayer);

                            // Adjust Brightness and Contrast
                            if (topLayer.R > (this.inkOutline * 255 / 100))
                            {
                                topLayer = ColorBgra.FromBgra(255, 255, 255, topLayer.A);
                            }
                            else
                            {
                                topLayer = ColorBgra.FromBgra(0, 0, 0, topLayer.A);
                            }

                            // Change Blend Mode to Darken
                            ColorBgra myPixel = this.darkenOp.Apply(topLayer, *dstPtr);
                            *         dstPtr  = myPixel;

                            ++srcPtr;
                            ++dstPtr;
                        }
                    }
                }
            }
        }
        public void SetParameters(int brightness, int contrast)
        {
            this.brightness = brightness;
            this.contrast   = contrast;
            if (this.contrast < 0)
            {
                this.multiply = this.contrast + 100;
                this.divide   = 100;
            }
            else if (this.contrast > 0)
            {
                this.multiply = 100;
                this.divide   = 100 - this.contrast;
            }
            else
            {
                this.multiply = 1;
                this.divide   = 1;
            }

            if (this.rgbTable == null)
            {
                this.rgbTable = new byte[65536];
            }

            if (this.divide == 0)
            {
                for (int intensity = 0; intensity < 256; ++intensity)
                {
                    if (intensity + this.brightness < 128)
                    {
                        this.rgbTable[intensity] = 0;
                    }
                    else
                    {
                        this.rgbTable[intensity] = 255;
                    }
                }
            }
            else if (this.divide == 100)
            {
                for (int intensity = 0; intensity < 256; ++intensity)
                {
                    int shift = (intensity - 127) * this.multiply / this.divide + 127 - intensity + this.brightness;

                    for (int col = 0; col < 256; ++col)
                    {
                        int index = (intensity * 256) + col;
                        this.rgbTable[index] = PixelUtils.ClampToByte(col + shift);
                    }
                }
            }
            else
            {
                for (int intensity = 0; intensity < 256; ++intensity)
                {
                    int shift = (intensity - 127 + this.brightness) * this.multiply / this.divide + 127 - intensity;

                    for (int col = 0; col < 256; ++col)
                    {
                        int index = (intensity * 256) + col;
                        this.rgbTable[index] = PixelUtils.ClampToByte(col + shift);
                    }
                }
            }
        }
Beispiel #30
0
        public override void Render(Surface src, Surface dst, Rectangle[] rois, int startIndex, int length)
        {
            ColorBgra colTransparent = ColorBgra.Transparent;

            unsafe
            {
                int     aaSampleCount = quality * quality;
                PointF *aaPoints      = stackalloc PointF[aaSampleCount];
                PixelUtils.GetRgssOffsets(aaPoints, aaSampleCount, quality);
                ColorBgra *samples = stackalloc ColorBgra[aaSampleCount];

                TransformData td;

                for (int n = startIndex; n < startIndex + length; ++n)
                {
                    Rectangle rect = rois[n];

                    for (int y = rect.Top; y < rect.Bottom; y++)
                    {
                        ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);

                        double relativeY = y - this.yCenterOffset;

                        for (int x = rect.Left; x < rect.Right; x++)
                        {
                            double relativeX = x - this.xCenterOffset;

                            int sampleCount = 0;

                            for (int p = 0; p < aaSampleCount; ++p)
                            {
                                td.X = relativeX + aaPoints[p].X;
                                td.Y = relativeY - aaPoints[p].Y;

                                InverseTransform(ref td);

                                float sampleX = (float)(td.X + this.xCenterOffset);
                                float sampleY = (float)(td.Y + this.yCenterOffset);

                                ColorBgra sample = colPrimary;

                                if (IsOnSurface(src, sampleX, sampleY))
                                {
                                    sample = src.GetBilinearSample(sampleX, sampleY);
                                }
                                else
                                {
                                    switch (this.edgeBehavior)
                                    {
                                    case WarpEdgeBehavior.Clamp:
                                        sample = src.GetBilinearSampleClamped(sampleX, sampleY);
                                        break;

                                    case WarpEdgeBehavior.Wrap:
                                        sample = src.GetBilinearSampleWrapped(sampleX, sampleY);
                                        break;

                                    case WarpEdgeBehavior.Reflect:
                                        sample = src.GetBilinearSampleClamped(
                                            ReflectCoord(sampleX, src.Width),
                                            ReflectCoord(sampleY, src.Height));

                                        break;

                                    case WarpEdgeBehavior.Primary:
                                        sample = colPrimary;
                                        break;

                                    case WarpEdgeBehavior.Secondary:
                                        sample = colSecondary;
                                        break;

                                    case WarpEdgeBehavior.Transparent:
                                        sample = colTransparent;
                                        break;

                                    case WarpEdgeBehavior.Original:
                                        sample = src[x, y];
                                        break;

                                    default:
                                        break;
                                    }
                                }

                                samples[sampleCount] = sample;
                                ++sampleCount;
                            }

                            *dstPtr = ColorBgra.Blend(samples, sampleCount);
                            ++dstPtr;
                        }
                    }
                }
            }
        }