private void HandleDividedArea(Rectangle region, bool updateCounter, Bitmap image)
        {
            if (region.Width > INT_MAX_REGION_WIDTH || region.Height > INT_MAX_REGION_WIDTH)
            {
                List <Rectangle> quarterRegions = new List <Rectangle>();

                // Top left.
                quarterRegions.Add(new Rectangle(region.X, region.Y, Convert.ToInt32(region.Width / 2), Convert.ToInt32(region.Height / 2)));
                // Top right.
                quarterRegions.Add(new Rectangle(region.X + Convert.ToInt32(region.Width / 2), region.Y, Convert.ToInt32(region.Width / 2) + 1, Convert.ToInt32(region.Height / 2)));
                // Bottom left.
                quarterRegions.Add(new Rectangle(region.X, region.Y + Convert.ToInt32(region.Height / 2), Convert.ToInt32(region.Width / 2), Convert.ToInt32(region.Height / 2) + 1));
                // Bottom right.
                quarterRegions.Add(new Rectangle(region.X + Convert.ToInt32(region.Width / 2), region.Y + Convert.ToInt32(region.Height / 2), Convert.ToInt32(region.Width / 2) + 1, Convert.ToInt32(region.Height / 2) + 1));
                foreach (Rectangle quarter in quarterRegions)
                {
                    this.HandleDividedArea(quarter, false, image);
                }
            }
            else
            {
                using (RegionUnpacker unpacker = new RegionUnpacker(image, region, this.backgroundColour.Value))
                {
                    unpacker.UnpackRegion();
                    lock ((this.areaUnpackedLock))
                    {
                        this.areaUnpacked += Convert.ToInt32((double)(region.Width * region.Height) * 0.8f);
                    }

                    this.SetPcComplete(20 + Convert.ToInt32(((double)this.areaUnpacked / (double)this.areaToUnpack) * 75f));

                    lock ((this.boxesLock))
                    {
                        this.boxes.AddRange(unpacker.Boxes);
                    }
                }

                lock ((this.areaUnpackedLock))
                {
                    this.areaUnpacked += Convert.ToInt32((double)(region.Width * region.Height) * 0.2f);
                }

                this.SetPcComplete(20 + Convert.ToInt32(((double)this.areaUnpacked / (double)this.areaToUnpack) * 80f));
            }

            if (updateCounter)
            {
                lock ((this.threadCompleteCounterLock))
                {
                    this.threadCompleteCounter += 1;
                    if (this.areAllThreadsCreated && this.threadCompleteCounter == this.threadCounter)
                    {
                        this.HandleUnpackComplete();
                    }
                }
            }
        }
        private void HandleUnpackComplete()
        {
            using (Bitmap img = this.GetOriginalClone())
            {
                lock ((this.boxesLock))
                {
                    RegionUnpacker.CombineBoxes(ref this.boxes, this.backgroundColour.Value, img);
                }
            }

            this.isUnpackingComplete = true;
            this._isUnpacking        = false;
            this.SetPcComplete(100);
            if (UnpackingComplete != null)
            {
                UnpackingComplete();
            }
        }
        private void HandleDividedArea(Rectangle region, bool updateCounter, Bitmap image)
        {
            if (region.Width > INT_MAX_REGION_WIDTH || region.Height > INT_MAX_REGION_WIDTH)
            {
                List<Rectangle> quarterRegions = new List<Rectangle>();

                // Top left.
                quarterRegions.Add(new Rectangle(region.X, region.Y, Convert.ToInt32(region.Width / 2), Convert.ToInt32(region.Height / 2)));
                // Top right.
                quarterRegions.Add(new Rectangle(region.X + Convert.ToInt32(region.Width / 2), region.Y, Convert.ToInt32(region.Width / 2) + 1, Convert.ToInt32(region.Height / 2)));
                // Bottom left.
                quarterRegions.Add(new Rectangle(region.X, region.Y + Convert.ToInt32(region.Height / 2), Convert.ToInt32(region.Width / 2), Convert.ToInt32(region.Height / 2) + 1));
                // Bottom right.
                quarterRegions.Add(new Rectangle(region.X + Convert.ToInt32(region.Width / 2), region.Y + Convert.ToInt32(region.Height / 2), Convert.ToInt32(region.Width / 2) + 1, Convert.ToInt32(region.Height / 2) + 1));
                foreach (Rectangle quarter in quarterRegions)
                {
                    this.HandleDividedArea(quarter, false, image);
                }
            }
            else
            {
                using (RegionUnpacker unpacker = new RegionUnpacker(image, region, this.backgroundColour.Value))
                {
                    unpacker.UnpackRegion();
                    lock ((this.areaUnpackedLock))
                    {
                        this.areaUnpacked += Convert.ToInt32((double)(region.Width * region.Height) * 0.8f);
                    }

                    this.SetPcComplete(20 + Convert.ToInt32(((double)this.areaUnpacked / (double)this.areaToUnpack) * 75f));

                    lock ((this.boxesLock))
                    {
                        this.boxes.AddRange(unpacker.Boxes);
                    }
                }

                lock ((this.areaUnpackedLock))
                {
                    this.areaUnpacked += Convert.ToInt32((double)(region.Width * region.Height) * 0.2f);
                }

                this.SetPcComplete(20 + Convert.ToInt32(((double)this.areaUnpacked / (double)this.areaToUnpack) * 80f));
            }

            if (updateCounter)
            {
                lock ((this.threadCompleteCounterLock))
                {
                    this.threadCompleteCounter += 1;
                    if (this.areAllThreadsCreated && this.threadCompleteCounter == this.threadCounter)
                    {
                        this.HandleUnpackComplete();
                    }
                }
            }
        }