/// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tbar_Threshold_ValueChanged(object sender, EventArgs e)
        {
            if (m_oBitmap == null)
                return;

            byte nValue = (byte)tbar_Transparency.Value;
            byte nThreshold = (byte)tbar_Threshold.Value;

            // Update the associated numeric up down control if the trackbar has focus.
            if (tbar_Threshold.Focused)
                nud_Threshold.Value = nThreshold;

            // Apply the processing.
            using (ImageProcessing oProcessing = new ImageProcessing(m_oBitmap))
            {
                oProcessing.AdjustTransparency(nValue, nThreshold);
                UpdatePreview(oProcessing.GetProcessedImage());
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tbar_Noise_ValueChanged(object sender, EventArgs e)
        {
            // Update the associated numeric up down control if the trackbar has focus.
            if (tbar_Noise.Focused)
                nud_Noise.Value = tbar_Noise.Value;

            // Apply the processing.
            using (ImageProcessing oProcessing = new ImageProcessing(m_oBitmap))
            {
                oProcessing.ApplyNoiseFilter(tbar_Noise.Value);
                UpdatePreview(oProcessing.GetProcessedImage());
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tbar_Gamma_ValueChanged(object sender, EventArgs e)
        {
            if (m_oBitmap == null)
                return;

            double fVal = (double)tbar_Gamma.Value / 100;

            // Update the associated numeric up down control if the trackbar has focus.
            if (tbar_Gamma.Focused)
                nud_Gamma.Value = (decimal)fVal;

            // Apply the processing.
            using (ImageProcessing oProcessing = new ImageProcessing(m_oBitmap))
            {
                oProcessing.AdjustGamma(fVal, fVal, fVal);
                UpdatePreview(oProcessing.GetProcessedImage());
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tbar_Transparancy_ValueChanged(object sender, EventArgs e)
        {
            if (m_oBitmap == null)
                return;

            // Update the associated numeric up down control if the trackbar has focus.
            if (tbar_Transparency.Focused)
                nud_Transparency.Value = (decimal)(100 / (255.0f / (float)tbar_Transparency.Value));

            // Apply the processing.
            using (ImageProcessing oProcessing = new ImageProcessing(m_oBitmap))
            {
                oProcessing.AdjustTransparency((byte)tbar_Transparency.Value, (byte)tbar_Threshold.Value);
                UpdatePreview(oProcessing.GetProcessedImage());
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tbar_Contrast_ValueChanged(object sender, EventArgs e)
        {
            if (m_oBitmap == null)
                return;

            // Update the associated numeric up down control if the trackbar has focus.
            if (tbar_Contrast.Focused)
                nud_Contrast.Value = tbar_Contrast.Value;

            // Apply the processing.
            using (ImageProcessing oProcessing = new ImageProcessing(m_oBitmap))
            {
                // Must call first.
                oProcessing.AdjustContrast(tbar_Contrast.Value);

                // Must call second.
                if (tbar_Brightness.Value != 0)
                    oProcessing.AdjustBrightness(tbar_Brightness.Value);

                UpdatePreview(oProcessing.GetProcessedImage());
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tbar_Blue_ValueChanged(object sender, EventArgs e)
        {
            if (m_oBitmap == null)
                return;

            // Update the associated numeric up down control if the trackbar has focus.
            if (tbar_Blue.Focused)
                nud_Blue.Value = tbar_Blue.Value;

            // Apply the processing.
            using (ImageProcessing oProcessing = new ImageProcessing(m_oBitmap))
            {
                oProcessing.AdjustColour(tbar_Red.Value, tbar_Green.Value, tbar_Blue.Value);
                UpdatePreview(oProcessing.GetProcessedImage());
            }
        }
        /// <summary>
        /// iView.NET subroutine. Shows the processing editor dialog. Allows the user to specifiy the settings
        /// and preview the changes when apply a filter.
        /// </summary>
        /// <param name="nControlSet">Specifies the control set to load when the dialog has been initialized.</param>
        /// <returns></returns>
        private SResult SubShowProcessingEditor(ControlSet nControlSet)
        {
            Image oImage = imgbx_MainImage.ImageBoxImage;

            if (oImage == null)
                return SResult.NullDisplayImage;

            using (ProcessingDialog oForm = new ProcessingDialog(oImage, nControlSet))
            {
                if (oForm.ShowDialog(this) == DialogResult.OK)
                {
                    Cursor.Current = Cursors.WaitCursor;

                    using (ImageProcessing oProcessing = new ImageProcessing(oImage))
                    {
                        // Update the image edited status.
                        ImageHasBeenEdited = true;

                        // No elements in the list? Save the original state first.
                        if (m_oUndoRedo.Count == 0)
                            m_oUndoRedo.Add(imgbx_MainImage.ImageBoxImage);

                        switch (nControlSet)
                        {
                            case ControlSet.BrightnessContrast:
                                if (oForm.Contrast != 0) oProcessing.AdjustContrast(oForm.Contrast);
                                if (oForm.Brightness != 0) oProcessing.AdjustBrightness(oForm.Brightness);
                                break;
                            case ControlSet.ColourBalance:
                                oProcessing.AdjustColour(oForm.Red, oForm.Green, oForm.Blue);
                                break;
                            case ControlSet.Gamma:
                                oProcessing.AdjustGamma(oForm.Gamma, oForm.Gamma, oForm.Gamma);
                                break;
                            case ControlSet.Transparency:
                                oProcessing.AdjustTransparency(oForm.Transparency, oForm.Threshold);
                                break;
                            case ControlSet.Noise:
                                oProcessing.ApplyNoiseFilter(oForm.Noise);
                                break;
                        }

                        // Update the main image.
                        imgbx_MainImage.ImageBoxImage = oProcessing.GetProcessedImage();

                        // Save the current image state.
                        m_oUndoRedo.Add(imgbx_MainImage.ImageBoxImage);
                    }

                    Cursor.Current = Cursors.Default;

                    return SResult.Completed;
                }
            }

            return SResult.Canceled;
        }
        /// <summary>
        /// iView.NET subroutine. Processes the main display image with the specified processing type.
        /// </summary>
        /// <param name="iProcessingType">Specifies the IProcessingType interface </param>
        /// <returns></returns>
        private SResult SubApplyImageProcessing(IProcessingType iProcessingType)
        {
            if (!imgbx_MainImage.IsImageLoaded)
                return SResult.NullDisplayImage;

            // Show image processing visuals.
            Cursor.Current = Cursors.WaitCursor;

            // Process the image in the main imagebox.
            using (ImageProcessing oImageProcess = new ImageProcessing(imgbx_MainImage.ImageBoxImage))
            {
                switch (iProcessingType.StructType)
                {
                    case ProcessingStructType.GreyScaleFilter:
                        oImageProcess.ApplyGreyScaleFilter();
                        break;
                    case ProcessingStructType.InvertFilter:
                        oImageProcess.ApplyInvertFilter();
                        break;
                    case ProcessingStructType.PhotoCopyFilter:
                        oImageProcess.ApplyPhotoCopyFilter();
                        break;
                    case ProcessingStructType.RotateColourFilter:
                        oImageProcess.ApplyRotateColourFilter();
                        break;
                    case ProcessingStructType.ColourFilter:
                        ColourFilterStruct ColourStruct = (ColourFilterStruct)iProcessingType;
                        oImageProcess.ApplyColourFilter(ColourStruct.Channel, ColourStruct.Value);
                        break;
                    case ProcessingStructType.Transparency:
                        TransparencyStruct TransStruct = (TransparencyStruct)iProcessingType;
                        oImageProcess.AdjustTransparency(TransStruct.Value, 255);
                        break;
                    case ProcessingStructType.Brightness:
                        BrightnessStruct BrightStruct = (BrightnessStruct)iProcessingType;
                        oImageProcess.AdjustBrightness(BrightStruct.Value);
                        break;
                    case ProcessingStructType.Contrast:
                        ContrastStruct ContStruct = (ContrastStruct)iProcessingType;
                        oImageProcess.AdjustContrast(ContStruct.Value);
                        break;
                    case ProcessingStructType.Gamma:
                        GammaStruct GammStruct = (GammaStruct)iProcessingType;
                        oImageProcess.AdjustGamma(GammStruct.Red, GammStruct.Green, GammStruct.Blue);
                        break;
                }

                // Update the image edited status.
                ImageHasBeenEdited = true;

                // No elements in the list? Save the original state first.
                if (m_oUndoRedo.Count == 0)
                    m_oUndoRedo.Add(imgbx_MainImage.ImageBoxImage);

                // Update the main imagebox with the processed image.
                imgbx_MainImage.ImageBoxImage = oImageProcess.GetProcessedImage();

                // Save the current image state.
                m_oUndoRedo.Add(imgbx_MainImage.ImageBoxImage);

                // Reset the cursor.
                Cursor.Current = Cursors.Default;
            }

            return SResult.Completed;
        }
        /// <summary>
        /// iView.NET subroutine. Allows the user to remove or reduce the red eye from the specified region within the specified image.
        /// </summary>
        /// <param name="nX"></param>
        /// <param name="nY"></param>
        /// <returns></returns>
        private SResult SubRedEyeCorrectionTool(int nX, int nY)
        {
            if (!imgbx_MainImage.IsImageLoaded)
                return SResult.NullDisplayImage;

            int nImageWidth = imgbx_MainImage.ImageBoxImage.Width;
            int nImageHeight = imgbx_MainImage.ImageBoxImage.Height;
            int nBoxWidth = imgbx_MainImage.ImageBoxWidth;
            int nBoxHeight = imgbx_MainImage.ImageBoxHeight;

            // Translate the current x position.
            float fXPercent = 100 / ((float)nBoxWidth / (float)nX);
            float fX = (fXPercent / 100) * nImageWidth;

            // Translate the current y position.
            float fYPercent = 100 / ((float)nBoxHeight / (float)nY);
            float fY = (fYPercent / 100) * nImageHeight;

            int nPos = (m_oRedEyePanel.PupilSize / 2);
            Rectangle Rect = new Rectangle((int)fX - nPos, (int)fY - nPos,
                m_oRedEyePanel.PupilSize, m_oRedEyePanel.PupilSize);

            // Update the image edited status.
            ImageHasBeenEdited = true;

            // No elements in the list? Save the original state first.
            if (m_oUndoRedo.Count == 0)
                m_oUndoRedo.Add(imgbx_MainImage.ImageBoxImage);

            // Process the image.
            using (ImageProcessing oProcess = new ImageProcessing(imgbx_MainImage.ImageBoxImage))
            {
                // Apply the red eye correction.
                oProcess.RedEyeCorrection(Rect, 1.5f);

                // Update the main display image with the edited image.
                imgbx_MainImage.ImageBoxImage = oProcess.GetProcessedImage();
            }

            // Save the current image state.
            m_oUndoRedo.Add(imgbx_MainImage.ImageBoxImage);

            // Reset the current tool and cursor.
            m_nCurrentTool = Tool.None;
            imgbx_MainImage.Cursor = Cursors.Default;

            return SResult.Completed;
        }