private void EmbedWatermark(double[,] data)
        {
            double[,] watermarkData = new double[_watermarkPixels.Width, _watermarkPixels.Height];

            //convet 32*32 watermark picture to black and white only (102->black(0);922->wthite(255))
            for (int x = 0; x < _watermarkPixels.Width; x++)
            {
                for (int y = 0; y < _watermarkPixels.Height; y++)
                {
                    watermarkData[x, y] = _watermarkPixels.R[x, y] > 125 ? 255 : 0;//convert to black or white only
                }
            }

            //test
            //ParallelHaar.FWT(data, 2);
            //var subband = LL2(data);
            var subband = data;

            Parallel.For(0, _watermarkPixels.Height, y =>        //height = 32
            {
                for (int x = 0; x < _watermarkPixels.Width; x++) //width = 32
                {
                    //BlockSize = 4
                    var block = subband.Submatrix(x * BlockSize, x * BlockSize + BlockSize - 1, y * BlockSize, y * BlockSize + BlockSize - 1);

                    CosineTransform.DCT(block);//DCT here

                    var midbandSum = Math.Max(2, Math.Abs(MidBand(block).Sum()));
                    var sigma      = (watermarkData[x, y] > 125 ? 3 : -3);

                    block[1, 2] += midbandSum * sigma;
                    block[2, 0] += midbandSum * sigma;
                    block[2, 1] += midbandSum * sigma;
                    block[2, 2] += midbandSum * sigma;

                    CosineTransform.IDCT(block);

                    for (int i = 0; i < BlockSize; i++)
                    {
                        for (int j = 0; j < BlockSize; j++)
                        {
                            subband[x * BlockSize + i, y * BlockSize + j] = block[i, j];
                        }
                    }
                }
            });

            BackApplySubBand(data, subband);
            ParallelHaar.IWT(data, 2);
        }//end EmbedWatermark
        private void EmbedWatermark(double[,] data)
        {
            double[,] watermarkData = new double[_watermarkPixels.Width, _watermarkPixels.Height];
            for (int x = 0; x < _watermarkPixels.Width; x++)
            {
                for (int y = 0; y < _watermarkPixels.Height; y++)
                {
                    watermarkData[x, y] = _watermarkPixels.R[x, y] > 125 ? 255 : 0;
                }
            }

            ParallelHaar.FWT(data, 2);
            var subband = LL2(data);

            Parallel.For(0, _watermarkPixels.Height, y =>
            {
                for (int x = 0; x < _watermarkPixels.Width; x++)
                {
                    var block = subband.Submatrix(x * BlockSize, x * BlockSize + BlockSize - 1, y * BlockSize, y * BlockSize + BlockSize - 1);

                    CosineTransform.DCT(block);

                    var midbandSum = Math.Max(2, Math.Abs(MidBand(block).Sum()));
                    var sigma      = (watermarkData[x, y] > 125 ? 3 : -3);

                    block[1, 2] += midbandSum * sigma;
                    block[2, 0] += midbandSum * sigma;
                    block[2, 1] += midbandSum * sigma;
                    block[2, 2] += midbandSum * sigma;

                    CosineTransform.IDCT(block);

                    for (int i = 0; i < BlockSize; i++)
                    {
                        for (int j = 0; j < BlockSize; j++)
                        {
                            subband[x * BlockSize + i, y * BlockSize + j] = block[i, j];
                        }
                    }
                }
            });

            BackApplySubBand(data, subband);
            ParallelHaar.IWT(data, 2);
        }