/// <summary> /// Counts available space for data hiding of all supported avi stream types /// </summary> /// <param name="avifh">.avi file handler</param> /// <returns>(Junk available size, Audio available size, Compressed video available size, Uncompressed video available size)</returns> public static (int, int, int, int) GetStreamsAvailableChunksSize(AVIFileHandler avifh) { Int32 junkSize = 0, vidsCompressSize = 0, vidsUncompressedSize = 0, audsSize = 0; Dictionary <Int32, CHUNK> chunkType; if (avifh.Chunks.TryGetValue(AVIFileHandler.JUNK_CHUNK, out chunkType)) { junkSize = GetAvailableSize(chunkType); } if (avifh.Chunks.TryGetValue(AVIFileHandler.AUDIO_CHUNK, out chunkType)) { audsSize = GetAvailableSize(chunkType); } if (avifh.Chunks.TryGetValue(AVIFileHandler.VIDEO_CHUNK_COMPRESSED, out chunkType)) { vidsCompressSize = GetAvailableSize(chunkType); } if (avifh.Chunks.TryGetValue(AVIFileHandler.VIDEO_CHUNK_UNCOMPRESSED, out chunkType)) { vidsUncompressedSize = GetAvailableSize(chunkType); } return(junkSize, vidsUncompressedSize, vidsCompressSize, audsSize); }
/// <summary> /// Command line parser success handler /// <see href="https://github.com/commandlineparser/commandline.git"></see> /// </summary> /// <param name="options">Parsed options</param> public static void RunOptionsAndReturnExitCode(Options options) { if (options.Action == Options.Actions.hide && options.Message == null) { IOUtils.ConsolePrintFailure(); Console.WriteLine("Message has to be specified in hide mode."); Exit(-1); } string message; if (options.Message.StartsWith("file:")) { message = IOUtils.LoadMessage(options.Message.Split(':')[1]); } else { message = options.Message; } if (message == null) { IOUtils.ConsolePrintFailure(); Console.WriteLine("Message cannot be empty."); Exit(-1); } byte[] avi = IOUtils.LoadAvi(options.FilePath); if (avi == null) { Exit(-1); } AVIFileHandler avifh = new AVIFileHandler(avi); if (options.Action == Options.Actions.extract) { string hiddenMessage = StenogrpahyUtils.ExtractMessage(avifh, options.Used); IOUtils.ConsolePrintSuccess(); Console.WriteLine($"Hidden message is: {hiddenMessage}"); } else { if (StenogrpahyUtils.HideMessage(avifh, message, options.Force, options.Used)) { IOUtils.ConsolePrintSuccess(); Console.WriteLine("Hiding data."); IOUtils.SaveAvi(options.OutputFilePath, avifh.Avi); } else { IOUtils.ConsolePrintFailure(); Console.WriteLine("Message hidding failed."); } } }
/// <summary> /// Hides message into .avi file /// </summary> /// <param name="avifh">.avi file handler</param> /// <param name="message">String to hide</param> /// <param name="force">Hide into compressed streams</param> /// <param name="hideTo">List of streams the message will be hidden into (in given order)</param> /// <returns>True if message was hide successfuly else false</returns> public static bool HideMessage(AVIFileHandler avifh, string message, bool force, IEnumerable <Options.DataTypes> hideTo) { message += MESSAGE_END; if (!CheckAvailableSpace(avifh, message, hideTo)) { IOUtils.ConsolePrintFailure(); Console.WriteLine("There is not enough space for message"); return(false); } else { IOUtils.ConsolePrintSuccess(); Console.WriteLine("Space check."); } foreach (Options.DataTypes type in hideTo) { Dictionary <Int32, CHUNK> chunks; if (CheckCompression(avifh.IsStreamUncompressed(type), force, type)) { if (avifh.Chunks.TryGetValue(AVIFileHandler.GetChunkName(type), out chunks)) { foreach (KeyValuePair <Int32, CHUNK> kvp in chunks) { message = HideData(avifh.Avi, kvp.Key, kvp.Value.ckSize, message); if (message == String.Empty) { return(true); } } } } } return(false); }
/// <summary> /// Extracts hidden message from .avi file /// </summary> /// <param name="avifh">.avi file handler</param> /// <param name="extractFrom">List of streams the message will be extracted from (in given order)</param> /// <returns>Extracted message</returns> public static string ExtractMessage(AVIFileHandler avifh, IEnumerable <Options.DataTypes> extractFrom) { string message = ""; bool EndReached = false; foreach (Options.DataTypes type in extractFrom) { Dictionary <Int32, CHUNK> chunks; if (avifh.Chunks.TryGetValue(AVIFileHandler.GetChunkName(type), out chunks)) { foreach (KeyValuePair <Int32, CHUNK> kvp in chunks) { EndReached = ExtractData(avifh.Avi, kvp.Key, kvp.Value.ckSize, ref message); if (EndReached) { return(message); } } } } return(null); }
/// <summary> /// Checks if there is enough free space to hide message /// </summary> /// <param name="avifh">.avi file handler</param> /// <param name="message">Message to hide</param> /// <param name="streams">List of stream for message hiding</param> /// <returns>true if there is enough space for message hiding else false</returns> private static bool CheckAvailableSpace(AVIFileHandler avifh, string message, IEnumerable <Options.DataTypes> streams) { (Int32, Int32, Int32, Int32)chunkSizes = GetStreamsAvailableChunksSize(avifh); IOUtils.ConsolePrintInfo(); Console.WriteLine($"Available free junk space: {chunkSizes.Item1}B"); IOUtils.ConsolePrintInfo(); Console.WriteLine($"Available free video space: {chunkSizes.Item2 + chunkSizes.Item3}B"); IOUtils.ConsolePrintInfo(); Console.WriteLine($"Available free audio space: {chunkSizes.Item4}B"); int[] sizes = new int[3] { chunkSizes.Item1, chunkSizes.Item2 + chunkSizes.Item3, chunkSizes.Item4 }; int size = 0; foreach (int type in streams) { size += sizes[type]; } return(size / 8 > message.Length); }