Ejemplo n.º 1
0
 public static bool GetWatermarkDctForBlock(MatrixBase<Color> block, int bitIndex, ZigZagAccessorFactory<double> zigzagAccessorFactory, Double[,] quantizationTable,
     ChannelType channelType, bool log = false)
 {
     var yCbCrColorBlock = block.ToYCbCr();
     var yChannel = yCbCrColorBlock.GetChannel(channelType);
     var shiftetBlock = yChannel - 128;
     var dctBlockTransform = (DiscreteCosineTransform.ForwardDct8Block(shiftetBlock).CrossDivide(quantizationTable)).Round();
     if (log)
     {
         _debugDecodeStringBuilder.AppendLine(dctBlockTransform.ToString());
     }
     var accessor = zigzagAccessorFactory.Access(dctBlockTransform);
     var coefficient = accessor[bitIndex];
     var curentElelement = (int) Math.Round(coefficient);
     bool isEven = curentElelement%2 == 0;
     return isEven;
 }
Ejemplo n.º 2
0
        private static MatrixBase<Color> WatermarkDctBlock(MatrixBase<Color> block, ZigZagAccessorFactory<Double> accessorFactory, double[,] quantizationTable, bool canEncrypt,
            byte[] secretMessage,
            ref int embeddingSecretMessageBitIndex, int byteIndexForEncryption, ChannelType channelType)
        {
            if (!canEncrypt)
            {
                return block;
            }

            var byteIndex = embeddingSecretMessageBitIndex / 8;
            if (embeddingSecretMessageBitIndex % 8 == 0)
            {
                byteIndex = embeddingSecretMessageBitIndex / 8;
                _debugEncodeStringBuilder.AppendLine("Appending byte:" + (byteIndex + 1));
            }

            var correction = 1;
            bool embeddCorrectly;
            MatrixBase<Color> ret;

            //#region Convert block

            var yCbCrColorBlock = block.ToYCbCr();
            var channel = yCbCrColorBlock.GetChannel(channelType);
            channel = channel - 128;
            DoubleMatrix dctBlockTransform = null;

            //#endregion

            do
            {
                // For luminance channel yMax = 127, ymin = -128

                DoubleMatrix stegoBlock;
                bool redo = false;
                var nextSecretBit = MathUtilities.GetBit(secretMessage, embeddingSecretMessageBitIndex);
                bool changed = false;
                dctBlockTransform = DiscreteCosineTransform.ForwardDct8Block(channel);
                dctBlockTransform = (dctBlockTransform.CrossDivide(quantizationTable));
                dctBlockTransform = dctBlockTransform.Round();

                var accessor = accessorFactory.Access(dctBlockTransform);
                var curentElelement = accessor[byteIndexForEncryption];
                bool isEven = ((int) Math.Round(curentElelement))%2 == 0;
                double possibleValue = curentElelement;
                DoubleMatrix oldStegoBlock = null;

                do
                {
                    if ((isEven && nextSecretBit) || (!isEven && !nextSecretBit))
                    {
                        if (!redo)
                        {
                            possibleValue = isEven ? curentElelement - correction : curentElelement + correction;
                        }
                        else
                        {
                            possibleValue = isEven ? curentElelement + correction : curentElelement - correction;
                        }
                        changed = true;
                    }

                    accessor[byteIndexForEncryption] = possibleValue;
                    stegoBlock = dctBlockTransform.CrossProduct(quantizationTable);
                    stegoBlock = DiscreteCosineTransform.InverseDct8Block(stegoBlock);

                    if (!redo && changed)
                    {
                        for (var i = 0; i < 8; i++)
                        {
                            for (var j = 0; j < 8; j++)
                            {
                                var value = Math.Round(stegoBlock[i, j]);
                                if (value < -128 || value > 127)
                                {
                                    redo = true;
                                    oldStegoBlock = stegoBlock;
                                    break;
                                }
                            }
                            if (redo)
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        if (changed)
                        {
                            var maximumValue = oldStegoBlock.MaximumValue;
                            var minimumValue = oldStegoBlock.MinimumValue;
                            var currentMaximumValue = stegoBlock.MaximumValue;
                            var currentMinimumValue = stegoBlock.MinimumValue;

                            if (currentMinimumValue < -128 || currentMaximumValue > 127)
                            {
                                if ((currentMinimumValue < -128 && minimumValue > currentMinimumValue) || (currentMaximumValue > 127 && maximumValue < currentMaximumValue))
                                {
                                    stegoBlock = oldStegoBlock;
                                }
                            }
                       }
                        redo = false;
                    }
                } while (redo);

                stegoBlock = stegoBlock + 128; //
                var tmpyCbCrColorBlock = yCbCrColorBlock.Copy;
                tmpyCbCrColorBlock.UpdateChannel(channelType, stegoBlock);

                ret = tmpyCbCrColorBlock.ToRgb();

                #region Verification (check if embeddding is correctly (rounding problems might occurs))

                if (changed)
                {
                    embeddCorrectly = !GetWatermarkDctForBlock(ret, byteIndexForEncryption, accessorFactory, quantizationTable, channelType) == nextSecretBit;
                    if (!embeddCorrectly)
                    {
                        correction = correction + 2;
                    }
                    else
                    {
                        correction = 1;
                    }
                }
                else
                {
                    embeddCorrectly = true;
                    correction = 1;
                }

                #endregion

            } while (!embeddCorrectly);

            _debugEncodeStringBuilder.AppendLine(dctBlockTransform.ToString());
            embeddingSecretMessageBitIndex++;

            return ret;
        }