/// <summary>
        /// Iterates array and calls specified function for each pixel component.
        /// </summary>
        /// <param name="applyerFunction"></param>
        /// <param name="outputFileName"></param>
        public void PerBitApply(PerPixelApplyerFunc applyerFunction, string outputFileName, int level = 0)
        {
            BitmapDataExtractor bitmapDataExtractor = new BitmapDataExtractor(srcImagePath);

            (int Stride, byte[] imageBytes, int Width, int Height, PixelFormat pixelFormat) = bitmapDataExtractor;

            //Extract data from bitmap

            int PixelComponentCount = Stride / Width;

            int imageBpp = Int32.Parse(Regex.Match(pixelFormat.ToString(), @"\d+").Value);

            // if Alpha value exists then we have 4 pixel components otherwise we have 3

            Log.Debug($"Calculated image bpp size is {imageBpp}");
            Log.Debug($"Calculated pixel compomemt max value is {Math.Pow(2, imageBpp / PixelComponentCount)}");

            // Iterating imageBytes by PixelComponentSize
            for (int i = 0; i < Height; i++)
            {
                for (int a = 0; a < Stride - PixelComponentCount; a = a + PixelComponentCount)
                {
                    applyerFunction(ref imageBytes, i * Stride + a, PixelComponentCount, imageBpp, level);
                }
            }

            BitmapBsSaver.Save(imageBytes, outputFileName, Width, Height, pixelFormat); // Saves bitmap with specified byte array
        }
        /// <summary>
        /// Takes filter matrix and applies it to image bytes.
        /// </summary>
        /// <param name="outputFileName"></param>
        /// <param name="matrix"></param>
        public void ApplyConv3x3(string outputFileName, ConvMatrix matrix)
        {
            //if (matrix.Factor == 0) { return; }

            (int Stride, byte[] imageBytes, int Width, int Height, PixelFormat pixelFormat) = new BitmapDataExtractor(filePath);

            byte[] WorkBytes = new byte[Height * Stride];



            // configuring blue red green color

            int nPixel = 0;

            for (int h = 0; h < Height - 3; h++)
            {
                for (int c = 0; c < Stride; c += 1)
                {
                    // blue
                    nPixel = (((
                                   (imageBytes[h * Stride + c] * matrix.TopLeft) + (imageBytes[h * Stride + c + 3] * matrix.TopMid) + (imageBytes[h * Stride + c + 6] * matrix.TopRight)
                                   + (imageBytes[(h + 1) * Stride + c] * matrix.MidLeft) + (imageBytes[(h + 1) * Stride + c + 3] * matrix.Pixel) + (imageBytes[(h + 1) * Stride + c + 6] * matrix.MidRight) +
                                   (imageBytes[(h + 2) * Stride + c] * matrix.BottomLeft) + (imageBytes[(h + 2) * Stride + c + 3] * matrix.BottomMid) + (imageBytes[(h + 2) * Stride + c + 6] * matrix.BottomRight)) / matrix.Factor) + matrix.Offset);

                    if (nPixel < 0)
                    {
                        nPixel = 0;
                    }
                    if (nPixel > 255)
                    {
                        nPixel = 255;
                    }

                    WorkBytes[(h + 1) * Stride + c + 3] = (byte)nPixel;
                    // green
                    nPixel = (((
                                   (imageBytes[h * Stride + c + 1] * matrix.TopLeft) + (imageBytes[h * Stride + c + 4] * matrix.TopMid) + (imageBytes[h * Stride + c + 7] * matrix.TopRight)
                                   + (imageBytes[(h + 1) * Stride + c + 1] * matrix.MidLeft) + (imageBytes[(h + 1) * Stride + c + 4] * matrix.Pixel) + (imageBytes[(h + 1) * Stride + c + 7] * matrix.MidRight) +
                                   (imageBytes[(h + 2) * Stride + c + 1] * matrix.BottomLeft) + (imageBytes[(h + 2) * Stride + c + 4] * matrix.BottomMid) + (imageBytes[(h + 2) * Stride + c + 7] * matrix.BottomRight)) / matrix.Factor) + matrix.Offset);

                    if (nPixel < 0)
                    {
                        nPixel = 0;
                    }
                    if (nPixel > 255)
                    {
                        nPixel = 255;
                    }

                    WorkBytes[(h + 1) * Stride + c + 4] = (byte)nPixel;
                    // red
                    nPixel = (((
                                   (imageBytes[h * Stride + c + 2] * matrix.TopLeft) + (imageBytes[h * Stride + c + 5] * matrix.TopMid) + (imageBytes[h * Stride + c + 8] * matrix.TopRight)
                                   + (imageBytes[(h + 1) * Stride + c + 2] * matrix.MidLeft) + (imageBytes[(h + 1) * Stride + c + 5] * matrix.Pixel) + (imageBytes[(h + 1) * Stride + c + 8] * matrix.MidRight) +
                                   (imageBytes[(h + 2) * Stride + c + 2] * matrix.BottomLeft) + (imageBytes[(h + 2) * Stride + c + 5] * matrix.BottomMid) + (imageBytes[(h + 2) * Stride + c + 8] * matrix.BottomRight)) / matrix.Factor) + matrix.Offset);

                    if (nPixel < 0)
                    {
                        nPixel = 0;
                    }
                    if (nPixel > 255)
                    {
                        nPixel = 255;
                    }

                    WorkBytes[(h + 1) * Stride + c + 5] = (byte)nPixel;
                }
            }
            BitmapBsSaver.Save(WorkBytes, outputFileName, Width, Height, pixelFormat);
        }