Example #1
0
		public override unsafe ColorBgra Apply (ColorBgra color, int area, int* hb, int* hg, int* hr, int* ha)
		{
			ColorBgra normalized = GetPercentileOfColor (color, area, hb, hg, hr, ha);
			double lerp = strength * (1 - 0.75 * color.GetIntensity ());

			return ColorBgra.Lerp (color, normalized, lerp);
		}
Example #2
0
        public unsafe override ColorBgra ApplyWithAlpha(ColorBgra src, int area, int sum, int* hb, int* hg, int* hr)
        {
            //each slot of the histgram can contain up to area * 255. This will overflow an int when area > 32k
            if (area < 32768) {
                int b = 0;
                int g = 0;
                int r = 0;

                for (int i = 1; i < 256; ++i) {
                    b += i * hb[i];
                    g += i * hg[i];
                    r += i * hr[i];
                }

                int alpha = sum / area;
                int div = area * 255;

                return ColorBgra.FromBgraClamped (b / div, g / div, r / div, alpha);
            } else {	//use a long if an int will overflow.
                long b = 0;
                long g = 0;
                long r = 0;

                for (long i = 1; i < 256; ++i) {
                    b += i * hb[i];
                    g += i * hg[i];
                    r += i * hr[i];
                }

                int alpha = sum / area;
                int div = area * 255;

                return ColorBgra.FromBgraClamped (b / div, g / div, r / div, alpha);
            }
        }
Example #3
0
        // This isn't really an extension method, since it doesn't use
        // the passed in argument, but it's nice to have the same calling
        // convention as the uncached version.  If you can use this one
        // over the other, it is much faster in tight loops (like effects).
        public static unsafe ColorBgra GetPointUnchecked(this ImageSurface surf, ColorBgra* surfDataPtr, int surfWidth, int x, int y)
        {
            ColorBgra* dstPtr = surfDataPtr;

            dstPtr += (x) + (y * surfWidth);

            return *dstPtr;
        }
Example #4
0
            public unsafe override void Apply(ColorBgra *dst, ColorBgra *src, int length)
            {
		    for (int i = 0; i < length; i++) {
			*dst = *src;
			dst++;
			src++;
		    }
            }
Example #5
0
 public unsafe override void Apply(ColorBgra* dst, ColorBgra* src, int length)
 {
     while (length > 0)
     {
         *dst = setColor;
         ++dst;
         --length;
     }
 }
Example #6
0
 public HistogramRgb()
     : base(3, 256)
 {
     visualColors = new ColorBgra[]{     
                                       ColorBgra.Blue,
                                       ColorBgra.Green,
                                       ColorBgra.Red
                                   };
 }
Example #7
0
        public unsafe void Render(Cairo.ImageSurface dst, Gdk.Point offset)
        {
            if (cr.ScaleFactor > new ScaleFactor (1, 2))
                return;

            int[] d2SLookupX = cr.Dst2SrcLookupX;
            int[] d2SLookupY = cr.Dst2SrcLookupY;
            int[] s2DLookupX = cr.Src2DstLookupX;
            int[] s2DLookupY = cr.Src2DstLookupY;

            ColorBgra[] blackAndWhite = new ColorBgra[2] { ColorBgra.White, ColorBgra.Black };

            // draw horizontal lines
            int dstHeight = dst.Height;
            int dstWidth = dst.Width;
            int dstStride = dst.Stride;
            int sTop = d2SLookupY[offset.Y];
            int sBottom = d2SLookupY[offset.Y + dstHeight];

            for (int srcY = sTop; srcY <= sBottom; ++srcY) {
                int dstY = s2DLookupY[srcY];
                int dstRow = dstY - offset.Y;

                if (dstRow >= 0 && dstRow < dstHeight) {
                    ColorBgra* dstRowPtr = dst.GetRowAddressUnchecked (dstRow);
                    ColorBgra* dstRowEndPtr = dstRowPtr + dstWidth;

                    dstRowPtr += offset.X & 1;

                    while (dstRowPtr < dstRowEndPtr) {
                        *dstRowPtr = ColorBgra.Black;
                        dstRowPtr += 2;
                    }
                }
            }

            // draw vertical lines
            int sLeft = d2SLookupX[offset.X];
            int sRight = d2SLookupX[offset.X + dstWidth];

            for (int srcX = sLeft; srcX <= sRight; ++srcX) {
                int dstX = s2DLookupX[srcX];
                int dstCol = dstX - offset.X;

                if (dstCol >= 0 && dstCol < dstWidth) {
                    byte* dstColPtr = (byte*)dst.GetPointAddress (dstCol, 0);
                    byte* dstColEndPtr = dstColPtr + dstStride * dstHeight;

                    dstColPtr += (offset.Y & 1) * dstStride;

                    while (dstColPtr < dstColEndPtr) {
                        *((ColorBgra*)dstColPtr) = ColorBgra.Black;
                        dstColPtr += 2 * dstStride;
                    }
                }
            }
        }
Example #8
0
 public unsafe override void Apply(ColorBgra* ptr, int length)
 {
     while (length > 0)
     {
         *ptr = setColor;
         ++ptr;
         --length;
     }
 }
Example #9
0
 public unsafe virtual void Apply(ColorBgra* ptr, int length)
 {
     unsafe {
         while (length > 0) {
             *ptr = Apply (*ptr);
             ++ptr;
             --length;
         }
     }
 }
Example #10
0
 public unsafe override void Apply(ColorBgra* dst, ColorBgra* src, int length)
 {
     unsafe {
         while (length > 0) {
             *dst = Apply (*src);
             ++dst;
             ++src;
             --length;
         }
     }
 }
Example #11
0
            public override ColorBgra Apply(ColorBgra color)
            {
                int a = blendColor.A;
                int invA = 255 - a;

                int r = ((color.R * invA) + (blendColor.R * a)) / 256;
                int g = ((color.G * invA) + (blendColor.G * a)) / 256;
                int b = ((color.B * invA) + (blendColor.B * a)) / 256;
                byte a2 = ComputeAlpha(color.A, blendColor.A);

                return ColorBgra.FromBgra((byte)b, (byte)g, (byte)r, a2);
            }
Example #12
0
		public unsafe virtual void Apply (ColorBgra* dst, ColorBgra* lhs, ColorBgra* rhs, int length)
		{
			unsafe {
				while (length > 0) {
					*dst = Apply (*lhs, *rhs);
					++dst;
					++lhs;
					++rhs;
					--length;
				}
			}
		}
Example #13
0
        public unsafe override ColorBgra Apply(ColorBgra src, int area, int* hb, int* hg, int* hr, int* ha)
        {
            int resultB = BlurChannel (src.B, hb);
            int resultG = BlurChannel (src.G, hg);
            int resultR = BlurChannel (src.R, hr);

            // there is no way we can deal with pre-multiplied alphas; the correlation
            // between channels no longer exists by this point in the algorithm...
            // so, just use the alpha from the source pixel.
            ColorBgra result = ColorBgra.FromBgra ((byte)resultB, (byte)resultG, (byte)resultR, src.A);

            return result;
        }
Example #14
0
		public ColorBgra Apply (ColorBgra color, int checkerX, int checkerY)
		{
			int b = color.B;
			int g = color.G;
			int r = color.R;
			int a = ApplyOpacity (color.A);

			int v = ((checkerX ^ checkerY) & 8) * 8 + 191;
			a = a + (a >> 7);
			int vmia = v * (256 - a);

			r = ((r * a) + vmia) >> 8;
			g = ((g * a) + vmia) >> 8;
			b = ((b * a) + vmia) >> 8;

			return ColorBgra.FromUInt32 ((uint)b + ((uint)g << 8) + ((uint)r << 16) + 0xff000000);
		}
Example #15
0
        public static unsafe void FillStencilByColor(ImageSurface surface, IBitVector2D stencil, ColorBgra cmp, int tolerance, out Rectangle boundingBox)
        {
            int top = int.MaxValue;
            int bottom = int.MinValue;
            int left = int.MaxValue;
            int right = int.MinValue;

            stencil.Clear (false);

            for (int y = 0; y < surface.Height; ++y) {
                bool foundPixelInRow = false;
                ColorBgra* ptr = surface.GetRowAddressUnchecked (y);

                for (int x = 0; x < surface.Width; ++x) {
                    if (CheckColor (cmp, *ptr, tolerance)) {
                        stencil.SetUnchecked (x, y, true);

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

                        if (x > right) {
                            right = x;
                        }

                        foundPixelInRow = true;
                    }

                    ++ptr;
                }

                if (foundPixelInRow) {
                    if (y < top) {
                        top = y;
                    }

                    if (y >= bottom) {
                        bottom = y;
                    }
                }
            }

            boundingBox = new Rectangle (left, top, right + 1, bottom + 1);
        }
Example #16
0
		private static unsafe ColorBgra GetPercentileOfColor (ColorBgra color, int area, int* hb, int* hg, int* hr, int* ha)
		{
			int rc = 0;
			int gc = 0;
			int bc = 0;

			for (int i = 0; i < color.R; ++i)
				rc += hr[i];

			for (int i = 0; i < color.G; ++i)
				gc += hg[i];

			for (int i = 0; i < color.B; ++i)
				bc += hb[i];

			rc = (rc * 255) / area;
			gc = (gc * 255) / area;
			bc = (bc * 255) / area;

			return ColorBgra.FromBgr ((byte)bc, (byte)gc, (byte)rc);
		}
Example #17
0
        /// <summary>
        /// Smoothly blends between two colors.
        /// </summary>
        public static ColorBgra Blend(ColorBgra ca, ColorBgra cb, byte cbAlpha)
        {
            uint caA = (uint)Utility.FastScaleByteByByte((byte)(255 - cbAlpha), ca.A);
            uint cbA = (uint)Utility.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);
        }
Example #18
0
 /// <summary>
 /// Performs the actual work of rendering an effect. This overload represent a single pixel of the image.
 /// </summary>
 /// <param name="color">The color of the source surface pixel.</param>
 /// <returns>The color to be used for the destination pixel.</returns>
 protected virtual ColorBgra Render(ColorBgra color)
 {
     return(color);
 }
Example #19
0
 public abstract ColorBgra Apply(ColorBgra color);
Example #20
0
        private void DrawChannel(Context g, ColorBgra color, int channel, long max, float mean)
        {
            Rectangle rect = Allocation.ToCairoRectangle ();
            Histogram histogram = Histogram;

            int l = (int)rect.X;
            int t = (int)rect.Y;
            int r = (int)(rect.X + rect.Width);
            int b = (int)(rect.Y + rect.Height);

            int entries = histogram.Entries;
            long[] hist = histogram.HistogramValues [channel];

            ++max;

            if (FlipHorizontal) {
                Utility.Swap(ref l, ref r);
            }

            if (!FlipVertical) {
                Utility.Swap(ref t, ref b);
            }

            PointD[] points = new PointD[entries + 2];

            points[entries] = new PointD (Utility.Lerp (l, r, -1), Utility.Lerp (t, b, 20));
            points[entries + 1] = new PointD (Utility.Lerp (l, r, -1), Utility.Lerp (b, t, 20));

            for (int i = 0; i < entries; i += entries - 1) {
                points[i] = new PointD (
                    Utility.Lerp (l, r, (float)hist[i] / (float)max),
                    Utility.Lerp (t, b, (float)i / (float)entries));

                CheckPoint (rect, points [i]);
            }

            long sum3 = hist[0] + hist[1];

            for (int i = 1; i < entries - 1; ++i) {
                sum3 += hist[i + 1];

                points[i] = new PointD(
                    Utility.Lerp(l, r, (float)(sum3) / (float)(max * 3.1f)),
                    Utility.Lerp(t, b, (float)i / (float)entries));

                CheckPoint (rect, points [i]);
                sum3 -= hist[i - 1];
            }

            byte intensity = selected[channel] ? (byte)96 : (byte)32;
            ColorBgra pen_color = ColorBgra.Blend (ColorBgra.Black, color, intensity);
            ColorBgra brush_color = color;
               	brush_color.A = intensity;

            g.LineWidth = 1;

            g.Rectangle (rect);
            g.Clip ();
            g.DrawPolygonal (points, pen_color.ToCairoColor ());
            g.FillPolygonal (points, brush_color.ToCairoColor ());
        }
Example #21
0
 private static void ComputeAlphaOnlyValuesFromColors(ColorBgra startColor, ColorBgra endColor, out byte startAlpha, out byte endAlpha)
 {
     startAlpha = startColor.A;
     endAlpha = (byte)(255 - endColor.A);
 }
Example #22
0
        public unsafe static void SetColorBgra(this Cairo.ImageSurface surf, ColorBgra *surfDataPtr, int surfWidth, ColorBgra color, int x, int y)
        {
            ColorBgra *dstPtr = surfDataPtr;

            dstPtr += (x) + (y * surfWidth);

            *dstPtr = color;
        }
Example #23
0
		public static int ColorDifference (ColorBgra a, ColorBgra b)
		{
			return (int)Math.Ceiling (Math.Sqrt (ColorDifferenceSquared (a, b)));
		}
Example #24
0
        public unsafe override ColorBgra Apply(ColorBgra src, int area, int* hb, int* hg, int* hr, int* ha)
        {
            int minCount1 = area * (100 - this.intensity) / 200;
            int minCount2 = area * (100 + this.intensity) / 200;

            int bCount = 0;
            int b1 = 0;

            while (b1 < 255 && hb[b1] == 0)
                ++b1;

            while (b1 < 255 && bCount < minCount1) {
                bCount += hb[b1];
                ++b1;
            }

            int b2 = b1;
            while (b2 < 255 && bCount < minCount2) {
                bCount += hb[b2];
                ++b2;
            }

            int gCount = 0;
            int g1 = 0;
            while (g1 < 255 && hg[g1] == 0)
                ++g1;

            while (g1 < 255 && gCount < minCount1) {
                gCount += hg[g1];
                ++g1;
            }

            int g2 = g1;
            while (g2 < 255 && gCount < minCount2) {
                gCount += hg[g2];
                ++g2;
            }

            int rCount = 0;
            int r1 = 0;
            while (r1 < 255 && hr[r1] == 0)
                ++r1;

            while (r1 < 255 && rCount < minCount1) {
                rCount += hr[r1];
                ++r1;
            }

            int r2 = r1;
            while (r2 < 255 && rCount < minCount2) {
                rCount += hr[r2];
                ++r2;
            }

            int aCount = 0;
            int a1 = 0;
            while (a1 < 255 && hb[a1] == 0)
                ++a1;

            while (a1 < 255 && aCount < minCount1) {
                aCount += ha[a1];
                ++a1;
            }

            int a2 = a1;
            while (a2 < 255 && aCount < minCount2) {
                aCount += ha[a2];
                ++a2;
            }

            return ColorBgra.FromBgra (
                (byte)(255 - (b2 - b1)),
                (byte)(255 - (g2 - g1)),
                (byte)(255 - (r2 - r1)),
                (byte)(a2));
        }
Example #25
0
        public static unsafe void FillStencilByColor(ImageSurface surface, IBitVector2D stencil, ColorBgra cmp, int tolerance, 
		                                              out Rectangle boundingBox, Gdk.Region limitRegion, bool limitToSelection)
        {
            int top = int.MaxValue;
            int bottom = int.MinValue;
            int left = int.MaxValue;
            int right = int.MinValue;
            Gdk.Rectangle[] scans;

            stencil.Clear (false);

            if (limitToSelection) {
                using (Gdk.Region excluded = Gdk.Region.Rectangle (new Gdk.Rectangle (0, 0, stencil.Width, stencil.Height))) {
                    excluded.Xor (limitRegion);
                    scans = excluded.GetRectangles ();
                }
            } else {
                scans = new Gdk.Rectangle[0];
            }

            foreach (Gdk.Rectangle rect in scans)
                stencil.Set (rect, true);

            for (int y = 0; y < surface.Height; ++y) {
                bool foundPixelInRow = false;
                ColorBgra* ptr = surface.GetRowAddressUnchecked (y);

                for (int x = 0; x < surface.Width; ++x) {
                    if (CheckColor (cmp, *ptr, tolerance)) {
                        stencil.SetUnchecked (x, y, true);

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

                        if (x > right) {
                            right = x;
                        }

                        foundPixelInRow = true;
                    }

                    ++ptr;
                }

                if (foundPixelInRow) {
                    if (y < top) {
                        top = y;
                    }

                    if (y >= bottom) {
                        bottom = y;
                    }
                }
            }

            foreach (Gdk.Rectangle rect in scans)
                stencil.Set (rect, false);

            boundingBox = new Rectangle (left, top, right - left + 1, bottom - top + 1);
        }
Example #26
0
 /// <summary>
 /// Returns a new ColorBgra with the same color values but with a new alpha component value.
 /// </summary>
 public ColorBgra NewAlpha(byte newA)
 {
     return(ColorBgra.FromBgra(B, G, R, newA));
 }
Example #27
0
 private static void ComputeAlphaOnlyValuesFromColors(ColorBgra startColor, ColorBgra endColor, out byte startAlpha, out byte endAlpha)
 {
     startAlpha = startColor.A;
     endAlpha   = (byte)(255 - endColor.A);
 }
Example #28
0
        public static unsafe ColorBgra GetBilinearSampleClamped(this ImageSurface src, ColorBgra *srcDataPtr, int srcWidth, int srcHeight, float x, float y)
        {
            if (!Utility.IsNumber(x) || !Utility.IsNumber(y))
            {
                return(ColorBgra.Transparent);
            }

            float u = x;
            float v = y;

            if (u < 0)
            {
                u = 0;
            }
            else if (u > srcWidth - 1)
            {
                u = srcWidth - 1;
            }

            if (v < 0)
            {
                v = 0;
            }
            else if (v > srcHeight - 1)
            {
                v = srcHeight - 1;
            }

            unchecked {
                int  iu        = (int)Math.Floor(u);
                uint sxfrac    = (uint)(256 * (u - (float)iu));
                uint sxfracinv = 256 - sxfrac;

                int  iv        = (int)Math.Floor(v);
                uint syfrac    = (uint)(256 * (v - (float)iv));
                uint syfracinv = 256 - syfrac;

                uint wul = (uint)(sxfracinv * syfracinv);
                uint wur = (uint)(sxfrac * syfracinv);
                uint wll = (uint)(sxfracinv * syfrac);
                uint wlr = (uint)(sxfrac * syfrac);

                int sx    = iu;
                int sy    = iv;
                int sleft = sx;
                int sright;

                if (sleft == (srcWidth - 1))
                {
                    sright = sleft;
                }
                else
                {
                    sright = sleft + 1;
                }

                int stop = sy;
                int sbottom;

                if (stop == (srcHeight - 1))
                {
                    sbottom = stop;
                }
                else
                {
                    sbottom = stop + 1;
                }

                ColorBgra *cul = src.GetPointAddressUnchecked(srcDataPtr, srcWidth, sleft, stop);
                ColorBgra *cur = cul + (sright - sleft);
                ColorBgra *cll = src.GetPointAddressUnchecked(srcDataPtr, srcWidth, sleft, sbottom);
                ColorBgra *clr = cll + (sright - sleft);

                ColorBgra c = ColorBgra.BlendColors4W16IP(*cul, wul, *cur, wur, *cll, wll, *clr, wlr);
                return(c);
            }
        }
Example #29
0
        public static unsafe ColorBgra GetBilinearSampleWrapped(this ImageSurface src, ColorBgra *srcDataPtr, int srcWidth, int srcHeight, float x, float y)
        {
            if (!Utility.IsNumber(x) || !Utility.IsNumber(y))
            {
                return(ColorBgra.Transparent);
            }

            float u = x;
            float v = y;

            unchecked {
                int  iu        = (int)Math.Floor(u);
                uint sxfrac    = (uint)(256 * (u - (float)iu));
                uint sxfracinv = 256 - sxfrac;

                int  iv        = (int)Math.Floor(v);
                uint syfrac    = (uint)(256 * (v - (float)iv));
                uint syfracinv = 256 - syfrac;

                uint wul = (uint)(sxfracinv * syfracinv);
                uint wur = (uint)(sxfrac * syfracinv);
                uint wll = (uint)(sxfracinv * syfrac);
                uint wlr = (uint)(sxfrac * syfrac);

                int sx = iu;
                if (sx < 0)
                {
                    sx = (srcWidth - 1) + ((sx + 1) % srcWidth);
                }
                else if (sx > (srcWidth - 1))
                {
                    sx = sx % srcWidth;
                }

                int sy = iv;
                if (sy < 0)
                {
                    sy = (srcHeight - 1) + ((sy + 1) % srcHeight);
                }
                else if (sy > (srcHeight - 1))
                {
                    sy = sy % srcHeight;
                }

                int sleft = sx;
                int sright;

                if (sleft == (srcWidth - 1))
                {
                    sright = 0;
                }
                else
                {
                    sright = sleft + 1;
                }

                int stop = sy;
                int sbottom;

                if (stop == (srcHeight - 1))
                {
                    sbottom = 0;
                }
                else
                {
                    sbottom = stop + 1;
                }

                ColorBgra cul = src.GetPointUnchecked(srcDataPtr, srcWidth, sleft, stop);
                ColorBgra cur = src.GetPointUnchecked(srcDataPtr, srcWidth, sright, stop);
                ColorBgra cll = src.GetPointUnchecked(srcDataPtr, srcWidth, sleft, sbottom);
                ColorBgra clr = src.GetPointUnchecked(srcDataPtr, srcWidth, sright, sbottom);

                ColorBgra c = ColorBgra.BlendColors4W16IP(cul, wul, cur, wur, cll, wll, clr, wlr);

                return(c);
            }
        }
Example #30
0
 public static ColorBgra ToBgraColor(this Gdk.Color color)
 {
     return(ColorBgra.FromBgr((byte)(color.Blue * 255 / ushort.MaxValue), (byte)(color.Green * 255 / ushort.MaxValue), (byte)(color.Red * 255 / ushort.MaxValue)));
 }
Example #31
0
        public static ColorBgra ParseHexString(string hexString)
        {
            uint value = Convert.ToUInt32(hexString, 16);

            return(ColorBgra.FromUInt32(value));
        }
        private int MaskAvg(ColorBgra before)
        {
            int count = 0, total = 0;

                for (int c = 0; c < 3; c++) {
                    if (mask [c]) {
                        total += before [c];
                        count++;
                    }
                }

                if (count > 0) {
                    return total / count;
                }
                else {
                    return 0;
                }
        }
Example #33
0
        /// <summary>
        /// Blends four colors together based on the given weight values.
        /// </summary>
        /// <returns>The blended color.</returns>
        /// <remarks>
        /// The weights should be 16-bit fixed point numbers that add up to 65536 ("1.0").
        /// 4W16IP means "4 colors, weights, 16-bit integer precision"
        /// </remarks>
        public static ColorBgra BlendColors4W16IP(ColorBgra c1, uint w1, ColorBgra c2, uint w2, ColorBgra c3, uint w3, ColorBgra c4, uint w4)
        {
#if DEBUG
            if ((w1 + w2 + w3 + w4) != 65536)
            {
                throw new ArgumentOutOfRangeException("w1 + w2 + w3 + w4 must equal 65536!");
            }
#endif

            const uint ww = 32768;
            uint       af = (c1.A * w1) + (c2.A * w2) + (c3.A * w3) + (c4.A * w4);
            uint       a  = (af + ww) >> 16;

            uint b;
            uint g;
            uint r;

            if (a == 0)
            {
                b = 0;
                g = 0;
                r = 0;
            }
            else
            {
                b = (uint)((((long)c1.A * c1.B * w1) + ((long)c2.A * c2.B * w2) + ((long)c3.A * c3.B * w3) + ((long)c4.A * c4.B * w4)) / af);
                g = (uint)((((long)c1.A * c1.G * w1) + ((long)c2.A * c2.G * w2) + ((long)c3.A * c3.G * w3) + ((long)c4.A * c4.G * w4)) / af);
                r = (uint)((((long)c1.A * c1.R * w1) + ((long)c2.A * c2.R * w2) + ((long)c3.A * c3.R * w3) + ((long)c4.A * c4.R * w4)) / af);
            }

            return(ColorBgra.FromBgra((byte)b, (byte)g, (byte)r, (byte)a));
        }
Example #34
0
        public static Gdk.Color ToGdkColor(this ColorBgra color)
        {
            Gdk.Color c = new Gdk.Color(color.R, color.G, color.B);

            return(c);
        }
Example #35
0
        // These methods are ported from PDN.
        private static bool CheckColor(ColorBgra a, ColorBgra b, int tolerance)
        {
            int sum = 0;
            int diff;

            diff = a.R - b.R;
            sum += (1 + diff * diff) * a.A / 256;

            diff = a.G - b.G;
            sum += (1 + diff * diff) * a.A / 256;

            diff = a.B - b.B;
            sum += (1 + diff * diff) * a.A / 256;

            diff = a.A - b.A;
            sum += diff * diff;

            return (sum <= tolerance * tolerance * 4);
        }
Example #36
0
        public static unsafe SurfaceDiff Create(ImageSurface original, ImageSurface updated_surf, bool force = false)
        {
            if (original.Width != updated_surf.Width || original.Height != updated_surf.Height)
            {
                // If the surface changed size, only throw an error if the user forced the use of a diff.
                if (force)
                {
                    throw new InvalidOperationException("SurfaceDiff requires surfaces to be same size.");
                }
                else
                {
                    return(null);
                }
            }

            // Cache some pinvokes
            var orig_width  = original.Width;
            var orig_height = original.Height;

#if DEBUG_DIFF
            Console.WriteLine("Original surface size: {0}x{1}", orig_width, orig_height);
            System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
            timer.Start();
#endif

            // STEP 1 - Find the bounds of the changed pixels.
            var orig_ptr    = (int *)original.DataPtr;
            var updated_ptr = (int *)updated_surf.DataPtr;

            DiffBounds diff_bounds      = new DiffBounds(orig_width, orig_height);
            object     diff_bounds_lock = new Object();

            // Split up the work among several threads, each of which processes one row at a time
            // and updates the bounds of the changed pixels it has seen so far. At the end, the
            // results from each thread are merged together to find the overall bounds of the changed
            // pixels.
            Parallel.For <DiffBounds>(0, orig_height, () => new DiffBounds(orig_width, orig_height),
                                      (row, loop, my_bounds) => {
                var offset         = row * orig_width;
                var orig           = orig_ptr + offset;
                var updated        = updated_ptr + offset;
                bool change_in_row = false;

                for (int i = 0; i < orig_width; ++i)
                {
                    if (*(orig++) != *(updated++))
                    {
                        change_in_row   = true;
                        my_bounds.left  = System.Math.Min(my_bounds.left, i);
                        my_bounds.right = System.Math.Max(my_bounds.right, i);
                    }
                }

                if (change_in_row)
                {
                    my_bounds.top    = System.Math.Min(my_bounds.top, row);
                    my_bounds.bottom = System.Math.Max(my_bounds.bottom, row);
                }

                return(my_bounds);
            }, (my_bounds) => {
                lock (diff_bounds_lock) {
                    diff_bounds.Merge(my_bounds);
                }
                return;
            });

            var bounds = new Gdk.Rectangle(diff_bounds.left, diff_bounds.top,
                                           diff_bounds.right - diff_bounds.left + 1,
                                           diff_bounds.bottom - diff_bounds.top + 1);

#if DEBUG_DIFF
            Console.WriteLine("Truncated surface size: {0}x{1}", bounds.Width, bounds.Height);
#endif

            // STEP 2 - Create a bitarray of whether each pixel in the bounds has changed, and count
            // how many changed pixels we need to store.
            var bitmask     = new BitArray(bounds.Width * bounds.Height);
            int index       = 0;
            int num_changed = 0;

            int bottom   = bounds.GetBottom();
            int right    = bounds.GetRight();
            int bounds_x = bounds.X;
            int bounds_y = bounds.Y;

            for (int y = bounds_y; y <= bottom; ++y)
            {
                var offset  = y * orig_width;
                var updated = updated_ptr + offset + bounds_x;
                var orig    = orig_ptr + offset + bounds_x;

                for (int x = bounds_x; x <= right; ++x)
                {
                    bool changed = *(orig++) != *(updated++);
                    bitmask[index++] = changed;
                    if (changed)
                    {
                        num_changed++;
                    }
                }
            }

            var savings = 100 - (float)num_changed / (float)(orig_width * orig_height) * 100;
#if DEBUG_DIFF
            Console.WriteLine("Compressed bitmask: {0}/{1} = {2}%", num_changed, orig_height * orig_width, 100 - savings);
#endif

            if (!force && savings < MINIMUM_SAVINGS_PERCENT)
            {
#if DEBUG_DIFF
                Console.WriteLine("Savings too small, returning null");
#endif
                return(null);
            }

            // Store the old pixels.
            var pixels     = new ColorBgra[num_changed];
            var new_ptr    = (ColorBgra *)original.DataPtr;
            int mask_index = 0;

            fixed(ColorBgra *fixed_ptr = pixels)
            {
                var pixel_ptr = fixed_ptr;

                for (int y = bounds_y; y <= bottom; ++y)
                {
                    var new_pixel_ptr = new_ptr + bounds_x + y * orig_width;

                    for (int x = bounds_x; x <= right; ++x)
                    {
                        if (bitmask[mask_index++])
                        {
                            *pixel_ptr++ = *new_pixel_ptr;
                        }

                        new_pixel_ptr++;
                    }
                }
            }

#if DEBUG_DIFF
            timer.Stop();
            System.Console.WriteLine("SurfaceDiff time: " + timer.ElapsedMilliseconds);
#endif

            return(new SurfaceDiff(bitmask, bounds, pixels));
        }
Example #37
0
		public unsafe override ColorBgra Apply (ColorBgra src, int area, int* hb, int* hg, int* hr, int* ha)
		{
			ColorBgra c = GetPercentile (this.percentile, area, hb, hg, hr, ha);
			return c;
		}
Example #38
0
        private ColorBgra AdjustColorDifference(ColorBgra oldColor, ColorBgra newColor, ColorBgra basisColor)
        {
            ColorBgra returnColor;

            // eliminate testing for the "equal to" case
            returnColor = basisColor;

            returnColor.B = AdjustColorByte (oldColor.B, newColor.B, basisColor.B);
            returnColor.G = AdjustColorByte (oldColor.G, newColor.G, basisColor.G);
            returnColor.R = AdjustColorByte (oldColor.R, newColor.R, basisColor.R);

            return returnColor;
        }
        private ColorBgra UpdateByMask(ColorBgra before, byte val)
        {
            ColorBgra after = before;
                int average = -1, oldaverage = -1;

                if (!(mask [0] || mask [1] || mask [2])) {
                    return before;
                }

                do {
                    float factor;

                    oldaverage = average;
                    average = MaskAvg (after);

                    if (average == 0) {
                        break;
                    }
                    factor = (float)val / average;

                    for (int c = 0; c < 3; c++) {
                        if (mask [c]) {
                            after [c] = (byte)Utility.ClampToByte (after [c] * factor);
                        }
                    }
                } while (average != val && oldaverage != average);

                while (average != val) {
                    average = MaskAvg (after);
                    int diff = val - average;

                    for (int c = 0; c < 3; c++) {
                        if (mask [c]) {
                            after [c] = (byte)Utility.ClampToByte(after [c] + diff);
                        }
                    }
                }

                after.A = 255;
                return after;
        }
Example #40
0
 private bool IsColorInTolerance(ColorBgra colorA, ColorBgra colorB)
 {
     return Utility.ColorDifference (colorA, colorB) <= myTolerance;
 }
Example #41
0
		public static int ColorDifferenceSquared (ColorBgra a, ColorBgra b)
		{
			int diffSq = 0, tmp;

			tmp = a.R - b.R;
			diffSq += tmp * tmp;
			tmp = a.G - b.G;
			diffSq += tmp * tmp;
			tmp = a.B - b.B;
			diffSq += tmp * tmp;

			return diffSq / 3;
		}
Example #42
0
 public abstract ColorBgra Apply(ColorBgra color);