private static void Pack(NanoPost[] arr, string templatePath, string outputPath) { var packed = NanoPostPackUtil.Pack(arr); var bmp = Bitmap.FromFile(templatePath); var capacity = (bmp.Width * bmp.Height * 3) / 8 - 32; // 32 is for header with hidden bytes count float scale = 1; if (packed.Length > capacity) { scale = (packed.Length / (float)capacity); scale = (float)Math.Sqrt(scale); Console.WriteLine("Warning: scaling image to increase capacity: " + scale.ToString("n2") + "x"); bmp = new Bitmap(bmp, (int)(bmp.Width * scale + 1), (int)(bmp.Height * scale + 1)); } new PngStegoUtil().HideBytesInPng(bmp, outputPath, packed); NotificationHandler.Instance.AddNotification("Контейнер сохранён: " + outputPath); Console.WriteLine( string.Format( "PNG capacity:{0}, posts amount:{1}, packed size:{2}, image scaling: {3:n2}x", capacity, arr.Length, packed.Length, scale)); }
public void SaveToPngContainer(NanoDB db) { db.RewriteDbExceptHidden(); db.ClearDb(); db.ReadPosts(); string[] ext = new[] { ".png", ".jpg", ".jpeg" }; var files = new DirectoryInfo(Strings.Containers).GetFiles().Where(f => ext.Contains(f.Extension.ToLower())).ToArray(); if (files.Length == 0) { NotificationHandler.Instance.AddNotification("Не найдены PNG файлы в папке containers."); return; } else if (files.Length <= 5) { if (!_smaller) { NotificationHandler.Instance.AddNotification("Предупреждение: у вас мало контейнеров."); } } FileInfo file = files[random.Next(files.Length - 1)]; var bmp = new Bitmap(file.FullName); int capacity = (int)(bmp.Width * bmp.Height * 3 / 8) - 32; string sessionPrefix = random.Next().ToString("x8"); sessionPrefix += random.Next().ToString("x8"); var packed = new byte[0]; var posts = new List <NanoPost>(); int i = db.GetPostCount() - 1; while (i >= 0 && posts.Count < FreshPosts) { var p = db.GetPost(i--); if (!db.IsHidden(p.GetHash())) { posts.Add(p); } } var parr = posts.ToArray(); var parents = new List <NanoPost>(); foreach (var post in parr) { var p = db.Get(post.ReplyTo); if (p != null && !db.IsHidden(p.GetHash())) { parents.Add(p); } } foreach (var post in parents) { posts.Add(post); var p = db.Get(post.ReplyTo); if (p != null && !db.IsHidden(p.GetHash())) { posts.Add(p); } } var slice0 = posts.GetRange(0, Math.Max(posts.Count, FreshPostsNotLimitedTo16384Allowed)); var slice1 = posts.GetRange(slice0.Count, posts.Count - slice0.Count); posts.Clear(); posts.AddRange(slice0); posts.AddRange(slice1.ToArray().FilterBySize(16384)); posts.AddRange(db.GetNRandomPosts(RandomPostsLimitedTo8192ALlowed).ExceptHidden(db).FilterBySize(8192)); posts.AddRange(db.GetNRandomPosts(RandomPostsLimitedTo16384Allowed).ExceptHidden(db).FilterBySize(16384)); posts = posts.Distinct().ToList(); packed = NanoPostPackUtil.Pack(posts.ToArray()); float scale = 1; if (packed.Length > capacity) { scale = (packed.Length / (float)capacity); scale = (float)Math.Sqrt(scale); if (scale > 2 && !_smaller) { new PngContainerCreatorNew(4).SaveToPngContainer(db); return; } bmp = new Bitmap(bmp, (int)(bmp.Width * scale + 1), (int)(bmp.Height * scale + 1)); } new PngStegoUtil().HideBytesInPng( bmp, Strings.Upload + Path.DirectorySeparatorChar + sessionPrefix + Strings.PngExt, packed); Console.WriteLine( string.Format( "PNG capacity:{0}, posts amount:{1}, packed size:{2}, image scaling: {3:n2}x", capacity, posts.Count, packed.Length, scale)); Console.WriteLine("Total posts in db: {0}, post length limit (bytes): {1}", db.GetPostCount(), NanoPost.MaxPostByteLength); NotificationHandler.Instance.AddNotification("Контейнер сохранён: " + Strings.Upload + Path.DirectorySeparatorChar + sessionPrefix + Strings.PngExt); }
private byte[] Pack(NanoPost[] posts) { return(NanoPostPackUtil.Pack(posts)); }
public void ReadInbox(NanoDB to) { if (_isReading) { return; } _isReading = true; if (Directory.Exists(Strings.Download)) { string[] files = Directory.GetFiles(Strings.Download); foreach (string f in files) { string pathToPng = f; byte[] packed = null; try { packed = new PngStegoUtil().ReadHiddenBytesFromPng(pathToPng); GC.Collect(); } catch { // invalid container } NanoPost[] posts = null; try { posts = NanoPostPackUtil.Unpack(packed); } catch { // inavlid container } bool any = false; if (posts != null) { foreach (var p in posts) { any |= to.AddPost(p); } } if (any) { NotificationHandler.Instance.AddNotification("Извлечены новые сообщения."); to.WriteNewPosts(false); } } try { foreach (string f in files) { File.Delete(f); } } catch { } } _isReading = false; }