Modulate() public static method

public static Modulate ( PixelColor a, PixelColor b ) : PixelColor
a PixelColor
b PixelColor
return PixelColor
        // Background downloading and processing
        private unsafe void UpdateThread()
        {
            HttpWebResponse webresponse = null;
            bool            failed      = false;
            string          failmsg     = "";
            Image           downloadimg = null;
            DateTime        starttime   = new DateTime();

            // Make the GET request
            HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(ADDRESS);

            webrequest.Referer     = REFERRER;
            webrequest.Method      = "GET";
            webrequest.KeepAlive   = false;
            webrequest.Timeout     = 5000;
            webrequest.UserAgent   = "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.14) Gecko/2009082707 Firefox/3.0.14 GTB5 (.NET CLR 3.5.30729)";
            webrequest.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);

            try
            {
                // Download!
                webresponse = (HttpWebResponse)webrequest.GetResponse();
            }
            catch (Exception e)
            {
                failed      = true;
                failmsg     = "Failed to update buienradar. Web request " + e.GetType().Name + ": " + e.Message;
                webresponse = null;
            }

            if (!failed)
            {
                try
                {
                    // Make image
                    downloadimg = Image.FromStream(webresponse.GetResponseStream());
                    webresponse.Close();
                }
                catch (Exception e)
                {
                    failed      = true;
                    failmsg     = "Failed to update buienradar. Image read " + e.GetType().Name + ": " + e.Message;
                    downloadimg = null;
                }
            }

            if (!failed)
            {
                // Dispose old images
                if (images != null)
                {
                    for (int i = 0; i < images.Length; i++)
                    {
                        if (images[i] != null)
                        {
                            images[i].Dispose();
                        }
                    }
                }

                images         = null;
                arrowlocations = null;

                //#if !DEBUG
                try
                {
                    //#endif
                    // Time at which the animation starts
                    DateTime now         = DateTime.Now.AddMinutes(ADJUST_TIME_MINUTES);
                    int      nearest5min = (int)(Math.Round((double)now.Minute / (double)5) * (double)5);
                    starttime = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0);
                    starttime = starttime.AddMinutes(nearest5min);

                    // Prepare variables to track the rain
                    DateTime incomingtime    = new DateTime();
                    bool     isincoming      = false;
                    DateTime cleartime       = new DateTime();
                    int      clearframecount = 0;

                    // Disassemble the image into separate images
                    FrameDimension fd        = new FrameDimension(downloadimg.FrameDimensionsList[0]);
                    int            numimages = downloadimg.GetFrameCount(fd);
                    images = new Image[numimages];
                    downloadimg.SelectActiveFrame(fd, 0);
                    Bitmap     firstbmp     = new Bitmap(downloadimg);
                    Size       sz           = firstbmp.Size;
                    BitmapData firstbmpdata = firstbmp.LockBits(new Rectangle(0, 0, sz.Width, sz.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                    for (int i = 0; i < numimages; i++)
                    {
                        downloadimg.SelectActiveFrame(fd, i);
                        Bitmap imgbmp = new Bitmap(downloadimg);
                        Bitmap newbmp = new Bitmap(sz.Width, sz.Height, PixelFormat.Format32bppArgb);

                        // Start processing the image
                        BitmapData  imgbmpdata = imgbmp.LockBits(new Rectangle(0, 0, sz.Width, sz.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                        BitmapData  newbmpdata = newbmp.LockBits(new Rectangle(0, 0, sz.Width, sz.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                        PixelColor *fpixels    = (PixelColor *)(firstbmpdata.Scan0.ToPointer());
                        PixelColor *ipixels    = (PixelColor *)(imgbmpdata.Scan0.ToPointer());
                        PixelColor *npixels    = (PixelColor *)(newbmpdata.Scan0.ToPointer());

                        // Go for all pixels
                        bool wholeframeclear = true;
                        for (int y = 0; y < sz.Height; y++)
                        {
                            for (int x = 0; x < sz.Width; x++)
                            {
                                // We compare the pixel of the first image (no clouds) with
                                // the current image to determine if there are clouds here
                                bool isclear = (ipixels->b == fpixels->b) &&
                                               (ipixels->g == fpixels->g) &&
                                               (ipixels->r == fpixels->r);

                                // Detect rain at current location
                                if (!isclear && (x >= LOCATION_X - LOCATION_RADIUS) && (x <= LOCATION_X + LOCATION_RADIUS) &&
                                    (y >= LOCATION_Y - LOCATION_RADIUS) && (y <= LOCATION_Y + LOCATION_RADIUS) && (i > 0))
                                {
                                    wholeframeclear = false;

                                    if (!isincoming)
                                    {
                                        // Rain!
                                        incomingtime    = starttime.AddMinutes(i * 10);
                                        isincoming      = true;
                                        clearframecount = 0;
                                    }

                                    if (clearframecount < CLEAR_FRAMES)
                                    {
                                        clearframecount = 0;
                                    }
                                }

                                // Clear pixel?
                                if (isclear)
                                {
                                    // This pixel is normal.
                                    PixelColor ds      = PixelColor.Desaturate(*ipixels);
                                    *          npixels = PixelColor.Lerp(ds, *ipixels, 0.1f);
                                    *          npixels = PixelColor.Scale(*npixels, 1.1f);
                                    PixelColor add     = new PixelColor(0, 10, 10, 10);
                                    *          npixels = PixelColor.Add(*npixels, add);
                                }
                                else
                                {
                                    // This pixel is a cloud.
                                    PixelColor mod     = new PixelColor(255, 160, 160, 250);
                                    *          npixels = PixelColor.Modulate(*ipixels, mod);
                                    *          npixels = PixelColor.Scale(*npixels, 1.8f);
                                }

                                // Next pixel
                                fpixels++;
                                ipixels++;
                                npixels++;
                            }
                        }

                        // Whole frame clear of rain at current location?
                        if (wholeframeclear)
                        {
                            // Count this frame as a clear frame
                            clearframecount++;

                            if (clearframecount == CLEAR_FRAMES)
                            {
                                // The clear time is 3 frames ago
                                cleartime = starttime.AddMinutes((i - 3) * 10);
                            }
                        }

                        // Clean up
                        imgbmp.UnlockBits(imgbmpdata);
                        newbmp.UnlockBits(newbmpdata);
                        images[i] = newbmp;
                        imgbmp.Dispose();
                        imgbmp = null;
                    }

                    // Show incoming time
                    if (isincoming)
                    {
                        incomingtext  = incomingtime.Hour + ":" + incomingtime.Minute.ToString("00");
                        flashincoming = true;
                    }
                    else
                    {
                        incomingtext  = "N / A";
                        flashincoming = false;
                    }

                    // Show clear time
                    if (clearframecount >= CLEAR_FRAMES)
                    {
                        cleartext  = cleartime.Hour + ":" + cleartime.Minute.ToString("00");
                        flashclear = true;
                    }
                    else
                    {
                        cleartext  = "N / A";
                        flashclear = false;
                    }

                    // Clean up
                    firstbmp.UnlockBits(firstbmpdata);
                    firstbmp.Dispose();
                    firstbmp = null;
                    downloadimg.Dispose();
                    downloadimg = null;
                    //#if !DEBUG
                }
                catch (Exception e)
                {
                    failed      = true;
                    failmsg     = "Failed to update buienradar. Image processing " + e.GetType().Name + ": " + e.Message;
                    downloadimg = null;
                }
                //#endif

                if (images != null)
                {
                    // Set up some random arrow locations, for decorative reason
                    Random rnd = new Random();
                    arrowlocations = new Size[images.Length];
                    Size offset = new Size(radar.Left + 100 + rnd.Next(radar.Width - movearrow1.Width - 100), radar.Top + 100 + rnd.Next(radar.Height - movearrow1.Height - 100));
                    for (int i = 0; i < images.Length; i++)
                    {
                        arrowlocations[i] = offset + new Size(rnd.Next(100) - 50, rnd.Next(100) - 50);
                    }
                }

                // Done
                firstimagetime  = starttime;
                nextupdatedelay = NORMAL_UPDATE_DELAY;
            }

            // Handle failure
            if (failed)
            {
                HandleFail(failmsg);
            }
            else
            {
                updatefailed = false;
            }

            // We're done updating (either successful or failed)
            UpdateComplete();
        }