public DwtDctSvdAlgorithm()
 {
     _imageArrayConverter  = new ImageArrayConverter();
     _stringArrayConverter = new StringToArrayConverter();
     _matrixService        = new MatrixService();
     _dwtHandler           = new DwtPrecisionAlgorithm();
     _svdHandler           = new SvdAlgorithm();
     _iterations           = 1;
     _quarter = QuarterSymbol.HH;
     _channel = EmbeddingChanel.R;
 }
        private Bitmap ExtractQuarter(Bitmap imageToSplit, int iterations, QuarterSymbol quarterSymbol)
        {
            var quarterImage   = new Bitmap(imageToSplit.Width / Convert.ToInt32(Math.Pow(2, _iterations)), imageToSplit.Height / Convert.ToInt32(Math.Pow(2, _iterations)));
            int widthShift     = 0;
            int heightShift    = 0;
            int widthShiftEnd  = imageToSplit.Width / Convert.ToInt32(Math.Pow(2, _iterations));
            int heightShiftEnd = imageToSplit.Width / Convert.ToInt32(Math.Pow(2, _iterations));

            switch (quarterSymbol)
            {
            case QuarterSymbol.HH:
                widthShift     = Convert.ToInt32(Math.Ceiling(imageToSplit.Width / Math.Pow(2, _iterations)));
                heightShift    = Convert.ToInt32(Math.Ceiling(imageToSplit.Height / Math.Pow(2, _iterations)));
                widthShiftEnd  = imageToSplit.Width / Convert.ToInt32(Math.Pow(2, _iterations - 1));
                heightShiftEnd = imageToSplit.Height / Convert.ToInt32(Math.Pow(2, _iterations - 1));
                break;

            case QuarterSymbol.HL:
                widthShift     = imageToSplit.Width / Convert.ToInt32(Math.Pow(2, _iterations));
                heightShift    = 0;
                widthShiftEnd  = imageToSplit.Width / Convert.ToInt32(Math.Pow(2, _iterations - 1));
                heightShiftEnd = imageToSplit.Height / Convert.ToInt32(Math.Pow(2, _iterations - 1));
                break;

            case QuarterSymbol.LH:
                widthShift     = 0;
                heightShift    = imageToSplit.Height / Convert.ToInt32(Math.Pow(2, _iterations));
                widthShiftEnd  = imageToSplit.Width / Convert.ToInt32(Math.Pow(2, _iterations - 1));
                heightShiftEnd = imageToSplit.Height / Convert.ToInt32(Math.Pow(2, _iterations - 1));
                break;

            case QuarterSymbol.LL:
                widthShift     = 0;
                heightShift    = 0;
                widthShiftEnd  = imageToSplit.Width / Convert.ToInt32(Math.Pow(2, _iterations - 1));
                heightShiftEnd = imageToSplit.Height / Convert.ToInt32(Math.Pow(2, _iterations - 1));
                break;
            }

            for (int i = heightShift; i < heightShiftEnd; i++)
            {
                for (int j = widthShift; j < widthShiftEnd; j++)
                {
                    var   width  = j - widthShift;
                    var   height = i - heightShift;
                    Color color  = imageToSplit.GetPixel(j, i);
                    quarterImage.SetPixel(width, height, color);
                }
            }

            return(quarterImage);
        }
 private void SetQuarterFromConfiguration(DwtSvdConfiguration config)
 {
     if (config.QuarterSymbol.Contains(QuarterSymbol.HH))
     {
         _quarter = QuarterSymbol.HH;
     }
     if (config.QuarterSymbol.Contains(QuarterSymbol.LL))
     {
         _quarter = QuarterSymbol.HH;
     }
     if (config.QuarterSymbol.Contains(QuarterSymbol.LH))
     {
         _quarter = QuarterSymbol.HH;
     }
     if (config.QuarterSymbol.Contains(QuarterSymbol.HL))
     {
         _quarter = QuarterSymbol.HL;
     }
 }
        private decimal[][,] MergeQuarter(decimal[][,] matrixToMerge, decimal[][,] originMatrix, int iterations, QuarterSymbol quarterSymbol)
        {
            var countOfMatrix  = originMatrix.GetLength(0);
            var matrixWidth    = originMatrix[0].GetLength(0);
            var matrixHeight   = originMatrix[0].GetLength(1);
            var quarterImage   = new decimal[countOfMatrix][, ];
            int widthShift     = 0;
            int heightShift    = 0;
            int widthShiftEnd  = matrixWidth / Convert.ToInt32(Math.Pow(2, _iterations));
            int heightShiftEnd = matrixHeight / Convert.ToInt32(Math.Pow(2, _iterations));

            switch (quarterSymbol)
            {
            case QuarterSymbol.HH:
                widthShift     = Convert.ToInt32(Math.Ceiling(matrixWidth / Math.Pow(2, _iterations)));
                heightShift    = Convert.ToInt32(Math.Ceiling(matrixHeight / Math.Pow(2, _iterations)));
                widthShiftEnd  = matrixWidth;
                heightShiftEnd = matrixHeight;
                break;

            case QuarterSymbol.HL:
                widthShift     = matrixWidth / Convert.ToInt32(Math.Pow(2, _iterations));
                heightShift    = 0;
                widthShiftEnd  = matrixWidth / Convert.ToInt32(Math.Pow(2, _iterations));
                heightShiftEnd = matrixHeight / Convert.ToInt32(Math.Pow(2, _iterations));
                break;

            case QuarterSymbol.LH:
                widthShift     = 0;
                heightShift    = matrixHeight / Convert.ToInt32(Math.Pow(2, _iterations));
                widthShiftEnd  = matrixWidth / Convert.ToInt32(Math.Pow(2, _iterations));
                heightShiftEnd = matrixHeight / Convert.ToInt32(Math.Pow(2, _iterations));
                break;

            case QuarterSymbol.LL:
                widthShift     = 0;
                heightShift    = 0;
                widthShiftEnd  = matrixWidth / Convert.ToInt32(Math.Pow(2, _iterations));
                heightShiftEnd = matrixHeight / Convert.ToInt32(Math.Pow(2, _iterations));
                break;
            }

            for (int k = 0; k < countOfMatrix; k++)
            {
                for (int j = heightShift; j < heightShiftEnd; j++)
                {
                    for (int i = widthShift; i < widthShiftEnd; i++)
                    {
                        var width  = i - widthShift;
                        var height = j - heightShift;
                        originMatrix[k][i, j] = matrixToMerge[k][width, height];
                    }
                }
            }
            return(originMatrix);
        }
        private decimal[][,] ExtractQuarter(decimal[][,] matrixToSplit, int iterations, QuarterSymbol quarterSymbol)
        {
            decimal[][,] origin = matrixToSplit.DeepClone();
            var countOfMatrix = matrixToSplit.GetLength(0);
            var matrixWidth   = matrixToSplit[0].GetLength(0);
            var matrixHeight  = matrixToSplit[0].GetLength(1);
            //var quarterImage = new decimal[countOfMatrixes][matrixWidth / Convert.ToInt32(Math.Pow(2, _iterations)), matrixHeight / Convert.ToInt32(Math.Pow(2, _iterations))];
            var quarterImage = new decimal[countOfMatrix][, ];

            int widthShift     = 0;
            int heightShift    = 0;
            int widthShiftEnd  = matrixWidth / Convert.ToInt32(Math.Pow(2, iterations));
            int heightShiftEnd = matrixHeight / Convert.ToInt32(Math.Pow(2, iterations));

            for (int i = 0; i < countOfMatrix; i++)
            {
                quarterImage[i] = new decimal[widthShiftEnd, heightShiftEnd];
            }

            switch (quarterSymbol)
            {
            case QuarterSymbol.HH:
                widthShift     = Convert.ToInt32(Math.Ceiling(matrixWidth / Math.Pow(2, iterations)));
                heightShift    = Convert.ToInt32(Math.Ceiling(matrixHeight / Math.Pow(2, iterations)));
                widthShiftEnd  = matrixWidth;
                heightShiftEnd = matrixHeight;
                break;

            case QuarterSymbol.HL:
                widthShift     = matrixWidth / Convert.ToInt32(Math.Pow(2, iterations));
                heightShift    = 0;
                widthShiftEnd  = matrixWidth;
                heightShiftEnd = matrixHeight / Convert.ToInt32(Math.Pow(2, iterations));
                break;

            case QuarterSymbol.LH:
                widthShift     = 0;
                heightShift    = matrixHeight / Convert.ToInt32(Math.Pow(2, iterations));
                widthShiftEnd  = matrixWidth / Convert.ToInt32(Math.Pow(2, iterations));
                heightShiftEnd = matrixHeight;
                break;

            case QuarterSymbol.LL:
                widthShift     = 0;
                heightShift    = 0;
                widthShiftEnd  = matrixWidth / Convert.ToInt32(Math.Pow(2, iterations));
                heightShiftEnd = matrixHeight / Convert.ToInt32(Math.Pow(2, iterations));
                break;
            }

            for (int k = 0; k < countOfMatrix; k++)
            {
                for (int j = heightShift; j < heightShiftEnd; j++)
                {
                    for (int i = widthShift; i < widthShiftEnd; i++)
                    {
                        var width  = i - widthShift;
                        var height = j - heightShift;
                        quarterImage[k][width, height] = origin[k][i, j];
                    }
                }
            }
            return(quarterImage);
        }