From 315ce3bc0dfc7a950138473f66ac83e0fa119f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiago=20Concei=C3=A7=C3=A3o?= Date: Mon, 18 Jul 2022 23:04:08 +0100 Subject: [PATCH] v3.5.5 - **File formats:** - (Add) `LayerImageType`: Gets the layer image data type used on this file format - (Improvement) jxs, rgb.cws and xml.cws: Improve the layer image read/write performance by a significant amount - (Fix) xml.cws: Wanhao printers need 32 bit png instead of 8 bit png (#514) --- CHANGELOG.md | 7 ++ RELEASE_NOTES.md | 17 ++-- UVtools.Core/FileFormats/CWSFile.cs | 78 +++------------- UVtools.Core/FileFormats/FileFormat.cs | 98 ++++++++++++++++++++- UVtools.Core/FileFormats/JXSFile.cs | 43 +-------- UVtools.Core/UVtools.Core.csproj | 2 +- UVtools.InstallerMM/UVtools.InstallerMM.wxs | 2 +- UVtools.WPF/UVtools.WPF.csproj | 4 +- 8 files changed, 127 insertions(+), 124 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe32973e..e3e9a8c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 18/07/2022 - v3.5.5 + +- **File formats:** + - (Add) `LayerImageType`: Gets the layer image data type used on this file format + - (Improvement) jxs, rgb.cws and xml.cws: Improve the layer image read/write performance by a significant amount + - (Fix) xml.cws: Wanhao printers need 32 bit png instead of 8 bit png (#514) + ## 14/07/2022 - v3.5.4 - **PCB Exposure:** diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 7292e312..762eac8c 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,12 +1,5 @@ -- **PCB Exposure:** - - (Add) Parse of deprecated commands (G70, G71, G90, G91) - - (Fix) Able to have parameterless macro apertures (#503) -- **UI:** - - (Add) Menu -> File -> Free unused RAM: Force the garbage collection of all unused objects within the program to free unused memory (RAM). - It's never required for the end user run this. The program will automatically take care of it when required. - This function is for debug purposes. - - (Improvement) Window title bar: Show elapsed minutes and seconds instead of total seconds minutes and second -- (Fix) Tool - Mask: Loaded image resolution shows as (unloaded) -- (Fix) Applying a large set of modifications in layer depth with pixel editor cause huge memory spike due layer aggregation without disposing, leading to program crash on most cases where RAM is insufficient (#506) -- (Upgrade) AvaloniaUI from 0.10.15 to 0.10.16 -- (Upgrade) .NET from 6.0.6 to 6.0.7 +- **File formats:** + - (Add) `LayerImageType`: Gets the layer image data type used on this file format + - (Improvement) jxs, rgb.cws and xml.cws: Improve the layer image read/write performance by a significant amount + - (Fix) xml.cws: Wanhao printers need 32 bit png instead of 8 bit png (#514) + diff --git a/UVtools.Core/FileFormats/CWSFile.cs b/UVtools.Core/FileFormats/CWSFile.cs index b32d673c..808a8a35 100644 --- a/UVtools.Core/FileFormats/CWSFile.cs +++ b/UVtools.Core/FileFormats/CWSFile.cs @@ -293,6 +293,14 @@ public class Slice public override FileFormatType FileType => FileFormatType.Archive; + public override FileImageType LayerImageType => + Printer switch + { + PrinterType.BeneMono => FileImageType.Png24BgrAA, + PrinterType.Wanhao => FileImageType.Png32, + _ => FileImageType.Png8 + }; + public enum PrinterType : byte { Unknown, @@ -658,49 +666,7 @@ protected override void EncodeInternally(OperationProgress progress) } } - if (Printer == PrinterType.BeneMono) - { - EncodeLayersInZip(outputFile, filename, LayerDigits, IndexStartNumber.Zero, progress, matGenFunc: - (_, mat) => - { - var bgrMat = new Mat(mat.Height, mat.GetRealStep() / 3, DepthType.Cv8U, 3); - var bgrMatSpan = bgrMat.GetDataByteSpan(); - var greySpan = mat.GetDataByteSpan(); - for (int i = 0; i < greySpan.Length; i++) - { - bgrMatSpan[i] = greySpan[i]; - } - - return bgrMat; - }); - /*Parallel.For(0, LayerCount, CoreSettings.GetParallelOptions(progress), - //new ParallelOptions { MaxDegreeOfParallelism = Printer == PrinterType.BeneMono ? 1 : 1 }, - layerIndex => - { - var layer = this[layerIndex]; - var layerImagePath = layer.FormatFileNameWithLayerDigits(filename); - - using var mat = layer.LayerMat; - using var matEncode = new Mat(mat.Height, mat.GetRealStep() / 3, DepthType.Cv8U, 3); - var span = mat.GetDataByteSpan(); - var spanEncode = matEncode.GetDataByteSpan(); - for (int i = 0; i < span.Length; i++) - { - spanEncode[i] = span[i]; - } - - var bytes = matEncode.GetPngByes(); - lock (progress.Mutex) - { - outputFile.PutFileContent(layerImagePath, bytes, ZipArchiveMode.Create); - progress++; - } - });*/ - } - else - { - EncodeLayersInZip(outputFile, filename, LayerDigits, IndexStartNumber.Zero, progress); - } + EncodeLayersInZip(outputFile, filename, LayerDigits, IndexStartNumber.Zero, progress); RebuildGCode(); outputFile.PutFileContent($"{filename}.gcode", GCodeStr, ZipArchiveMode.Create); @@ -861,31 +827,9 @@ protected override void DecodeInternally(OperationProgress progress) } } - if (Printer == PrinterType.BeneMono) - { - DecodeLayersFromZipRegex(inputFile, @"(\d+).png", IndexStartNumber.Zero, progress, - (layerIndex, pngBytes) => - { - using Mat bgrMat = new(); - CvInvoke.Imdecode(pngBytes, ImreadModes.AnyColor, bgrMat); - var greyMat = new Mat(bgrMat.Height, bgrMat.GetRealStep(), DepthType.Cv8U, 1); - var bgrSpan = bgrMat.GetDataByteSpan(); - var greySpan = greyMat.GetDataByteSpan(); - for (int i = 0; i < bgrSpan.Length; i++) - { - greySpan[i] = bgrSpan[i]; - } - - return greyMat; - }); - } - else - { - DecodeLayersFromZipRegex(inputFile, @"(\d+).png", IndexStartNumber.Zero, progress); - } - - GCode.ParseLayersFromGCode(this); + DecodeLayersFromZipRegex(inputFile, @"(\d+).png", IndexStartNumber.Zero, progress); + GCode.ParseLayersFromGCode(this); } public override void RebuildGCode() diff --git a/UVtools.Core/FileFormats/FileFormat.cs b/UVtools.Core/FileFormats/FileFormat.cs index e62310dd..27dce29c 100644 --- a/UVtools.Core/FileFormats/FileFormat.cs +++ b/UVtools.Core/FileFormats/FileFormat.cs @@ -163,6 +163,26 @@ public enum FileDecodeType : byte Partial, } + /// + /// Image data type + /// + public enum FileImageType : byte + { + Custom, + Png8, + Png24, + Png32, + /// + /// eg: Nova Bene4 + /// + Png24BgrAA, + /// + /// eg: Uniformation GKone + /// + Png24RgbAA, + + } + #endregion #region Sub Classes @@ -1022,6 +1042,11 @@ public static int MutateGetIterationChamfer(uint layerIndex, uint startLayerInde /// public abstract FileFormatType FileType { get; } + /// + /// Gets the layer image data type used on this file format + /// + public virtual FileImageType LayerImageType => FileType == FileFormatType.Archive ? FileImageType.Png8 : FileImageType.Custom; + /// /// Gets the valid file extensions for this /// @@ -3416,13 +3441,54 @@ public void EncodeLayersInZip(ZipArchive zipArchive, string prepend, byte padDig progress.Reset(OperationProgress.StatusEncodeLayers, LayerCount); var batches = BatchLayersIndexes(); var pngLayerBytes = new byte[LayerCount][]; + + var layerImageType = LayerImageType; + foreach (var batch in batches) { Parallel.ForEach(batch, CoreSettings.GetParallelOptions(progress), layerIndex => { if (matGenFunc is null) { - pngLayerBytes[layerIndex] = this[layerIndex].CompressedPngBytes!; + switch (layerImageType) + { + case FileImageType.Png24: + { + using var mat = this[layerIndex].LayerMat; + CvInvoke.CvtColor(mat, mat, ColorConversion.Gray2Bgr); + pngLayerBytes[layerIndex] = mat.GetPngByes(); + + break; + } + case FileImageType.Png32: + { + using var mat = this[layerIndex].LayerMat; + CvInvoke.CvtColor(mat, mat, ColorConversion.Gray2Bgra); + pngLayerBytes[layerIndex] = mat.GetPngByes(); + + break; + } + case FileImageType.Png24BgrAA: + { + using var mat = this[layerIndex].LayerMat; + using var outputMat = mat.Reshape(3); + pngLayerBytes[layerIndex] = outputMat.GetPngByes(); + + break; + } + case FileImageType.Png24RgbAA: + { + using var mat = this[layerIndex].LayerMat; + using var outputMat = mat.Reshape(3); + CvInvoke.CvtColor(outputMat, outputMat, ColorConversion.Bgr2Rgb); + pngLayerBytes[layerIndex] = outputMat.GetPngByes(); + + break; + } + default: + pngLayerBytes[layerIndex] = this[layerIndex].CompressedPngBytes!; + break; + } } else { @@ -3461,6 +3527,8 @@ public void DecodeLayersFromZip(ZipArchiveEntry[] layerEntries, OperationProgres progress ??= new OperationProgress(); progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount); + var layerImageType = LayerImageType; + Parallel.For(0, LayerCount, CoreSettings.GetParallelOptions(progress), layerIndex => { byte[] pngBytes; @@ -3472,7 +3540,33 @@ public void DecodeLayersFromZip(ZipArchiveEntry[] layerEntries, OperationProgres if (matGenFunc is null) { - _layers[layerIndex] = new Layer((uint)layerIndex, pngBytes, this); + switch (layerImageType) + { + case FileImageType.Png24BgrAA: + { + using var bgrMat = new Mat(); + CvInvoke.Imdecode(pngBytes, ImreadModes.Color, bgrMat); + using var greyMat = bgrMat.Reshape(1); + + _layers[layerIndex] = new Layer((uint) layerIndex, greyMat, this); + + break; + } + case FileImageType.Png24RgbAA: + { + using Mat rgbMat = new(); + CvInvoke.Imdecode(pngBytes, ImreadModes.Color, rgbMat); + CvInvoke.CvtColor(rgbMat, rgbMat, ColorConversion.Bgr2Rgb); + using var greyMat = rgbMat.Reshape(1); + + _layers[layerIndex] = new Layer((uint)layerIndex, greyMat, this); + + break; + } + default: + _layers[layerIndex] = new Layer((uint)layerIndex, pngBytes, this); + break; + } } else { diff --git a/UVtools.Core/FileFormats/JXSFile.cs b/UVtools.Core/FileFormats/JXSFile.cs index 098042a5..27631c1a 100644 --- a/UVtools.Core/FileFormats/JXSFile.cs +++ b/UVtools.Core/FileFormats/JXSFile.cs @@ -85,6 +85,8 @@ public sealed class JXSControl public override FileFormatType FileType => FileFormatType.Archive; + public override FileImageType LayerImageType => FileImageType.Png24RgbAA; + public override FileExtension[] FileExtensions { get; } = { new(typeof(JXSFile), "jxs", "Uniformation GKone (JXS)") }; @@ -510,27 +512,8 @@ protected override void DecodeInternally(OperationProgress progress) } Init(ConfigFile.LayerCount, DecodeType == FileDecodeType.Partial); - sbyte[] bgrToRgbTable = { - 2, - 0, - -2 - }; - DecodeLayersFromZip(inputFile, IndexStartNumber.Zero, progress, - (layerIndex, pngBytes) => - { - using Mat rgbMat = new(); - CvInvoke.Imdecode(pngBytes, ImreadModes.AnyColor, rgbMat); - var greyMat = new Mat(rgbMat.Height, rgbMat.GetRealStep(), DepthType.Cv8U, 1); - var rgbSpan = rgbMat.GetDataByteSpan(); - var greySpan = greyMat.GetDataByteSpan(); - for (var i = 0; i < rgbSpan.Length; i++) - { - greySpan[i] = rgbSpan[i + bgrToRgbTable[i%3]]; - } - - return greyMat; - }); + DecodeLayersFromZip(inputFile, IndexStartNumber.Zero, progress); GCode!.Clear(); @@ -587,25 +570,7 @@ protected override void EncodeInternally(OperationProgress progress) { using var outputFile = ZipFile.Open(TemporaryOutputFileFullPath, ZipArchiveMode.Create); - sbyte[] bgrToRgbTable = { - 2, - 0, - -2 - }; - EncodeLayersInZip(outputFile, 5, IndexStartNumber.Zero, progress, matGenFunc: - (_, mat) => - { - var rgbMat = new Mat(mat.Height, mat.GetRealStep() / 3, DepthType.Cv8U, 3); - var rgbMatSpan = rgbMat.GetDataByteSpan(); - var greySpan = mat.GetDataByteSpan(); - for (int i = 0; i < greySpan.Length; i++) - { - rgbMatSpan[i + bgrToRgbTable[i % 3]] = greySpan[i]; - } - - return rgbMat; - }); - + EncodeLayersInZip(outputFile, 5, IndexStartNumber.Zero, progress); RebuildFileProperties(); diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj index 11a06679..7cfb01f0 100644 --- a/UVtools.Core/UVtools.Core.csproj +++ b/UVtools.Core/UVtools.Core.csproj @@ -10,7 +10,7 @@ https://github.com/sn4k3/UVtools https://github.com/sn4k3/UVtools MSLA/DLP, file analysis, calibration, repair, conversion and manipulation - 3.5.4 + 3.5.5 Copyright © 2020 PTRTECH UVtools.png AnyCPU;x64 diff --git a/UVtools.InstallerMM/UVtools.InstallerMM.wxs b/UVtools.InstallerMM/UVtools.InstallerMM.wxs index f2273412..c96d2f01 100644 --- a/UVtools.InstallerMM/UVtools.InstallerMM.wxs +++ b/UVtools.InstallerMM/UVtools.InstallerMM.wxs @@ -2,7 +2,7 @@ - + diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj index e7f2cf20..821f61a0 100644 --- a/UVtools.WPF/UVtools.WPF.csproj +++ b/UVtools.WPF/UVtools.WPF.csproj @@ -12,7 +12,7 @@ LICENSE https://github.com/sn4k3/UVtools Git - 3.5.4 + 3.5.5 AnyCPU;x64 UVtools.png README.md @@ -43,7 +43,7 @@ - +