From 4e735ad8f34b0d5ca3ec436d62eadde23c4b7cab Mon Sep 17 00:00:00 2001
From: 7H3LaughingMan <7H3LaughingMan@proton.me>
Date: Tue, 29 Apr 2025 14:24:13 -0500
Subject: [PATCH 1/3] Add ZstdSharp Reference
---
src/DotTiled/DotTiled.csproj | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/DotTiled/DotTiled.csproj b/src/DotTiled/DotTiled.csproj
index d8d83a5..837264e 100644
--- a/src/DotTiled/DotTiled.csproj
+++ b/src/DotTiled/DotTiled.csproj
@@ -26,4 +26,8 @@
+
+
+
+
From 2388af6b523402984e08e0ae050953108ee7c526 Mon Sep 17 00:00:00 2001
From: 7H3LaughingMan <7H3LaughingMan@proton.me>
Date: Tue, 29 Apr 2025 14:24:45 -0500
Subject: [PATCH 2/3] ZStd Support
---
src/DotTiled/Serialization/Helpers.cs | 6 ++++++
src/DotTiled/Serialization/Tmj/TmjReaderBase.Data.cs | 2 +-
src/DotTiled/Serialization/Tmj/TmjReaderBase.TileLayer.cs | 1 +
src/DotTiled/Serialization/Tmx/TmxReaderBase.Data.cs | 2 +-
4 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/DotTiled/Serialization/Helpers.cs b/src/DotTiled/Serialization/Helpers.cs
index 28d6aec..0e7e51c 100644
--- a/src/DotTiled/Serialization/Helpers.cs
+++ b/src/DotTiled/Serialization/Helpers.cs
@@ -46,6 +46,12 @@ internal static partial class Helpers
return ReadMemoryStreamAsInt32Array(decompressedStream);
}
+ internal static uint[] DecompressZStd(MemoryStream stream)
+ {
+ using var decompressedStream = new ZstdSharp.DecompressionStream(stream);
+ return ReadMemoryStreamAsInt32Array(decompressedStream);
+ }
+
internal static uint[] ReadBytesAsInt32Array(byte[] bytes)
{
var intArray = new uint[bytes.Length / 4];
diff --git a/src/DotTiled/Serialization/Tmj/TmjReaderBase.Data.cs b/src/DotTiled/Serialization/Tmj/TmjReaderBase.Data.cs
index 904321b..9d1e5db 100644
--- a/src/DotTiled/Serialization/Tmj/TmjReaderBase.Data.cs
+++ b/src/DotTiled/Serialization/Tmj/TmjReaderBase.Data.cs
@@ -61,7 +61,7 @@ public abstract partial class TmjReaderBase
{
DataCompression.GZip => Helpers.DecompressGZip(stream),
DataCompression.ZLib => Helpers.DecompressZLib(stream),
- DataCompression.ZStd => throw new NotSupportedException("ZStd compression is not supported."),
+ DataCompression.ZStd => Helpers.DecompressZStd(stream),
_ => throw new InvalidOperationException($"Unsupported compression '{compression}'.")
};
diff --git a/src/DotTiled/Serialization/Tmj/TmjReaderBase.TileLayer.cs b/src/DotTiled/Serialization/Tmj/TmjReaderBase.TileLayer.cs
index 862df4d..22d65b6 100644
--- a/src/DotTiled/Serialization/Tmj/TmjReaderBase.TileLayer.cs
+++ b/src/DotTiled/Serialization/Tmj/TmjReaderBase.TileLayer.cs
@@ -16,6 +16,7 @@ public abstract partial class TmjReaderBase
{
"zlib" => DataCompression.ZLib,
"gzip" => DataCompression.GZip,
+ "zstd" => DataCompression.ZStd,
"" => Optional.Empty,
_ => throw new JsonException($"Unsupported compression '{s}'.")
});
diff --git a/src/DotTiled/Serialization/Tmx/TmxReaderBase.Data.cs b/src/DotTiled/Serialization/Tmx/TmxReaderBase.Data.cs
index e60f641..a01a582 100644
--- a/src/DotTiled/Serialization/Tmx/TmxReaderBase.Data.cs
+++ b/src/DotTiled/Serialization/Tmx/TmxReaderBase.Data.cs
@@ -77,7 +77,7 @@ public abstract partial class TmxReaderBase
{
DataCompression.GZip => Helpers.DecompressGZip(bytes),
DataCompression.ZLib => Helpers.DecompressZLib(bytes),
- DataCompression.ZStd => throw new NotSupportedException("ZStd compression is not supported."),
+ DataCompression.ZStd => Helpers.DecompressZStd(bytes),
_ => throw new XmlException("Invalid compression")
};
From 9c446239d73584dca067b8e5228f43656458ad02 Mon Sep 17 00:00:00 2001
From: 7H3LaughingMan <7H3LaughingMan@proton.me>
Date: Tue, 29 Apr 2025 14:24:58 -0500
Subject: [PATCH 3/3] ZStd Testing
---
.../default-map-base64-zstd.cs | 52 +++++++++++++++++++
.../default-map-base64-zstd.tmj | 30 +++++++++++
.../default-map-base64-zstd.tmx | 8 +++
.../UnitTests/Serialization/TestData.cs | 1 +
4 files changed, 91 insertions(+)
create mode 100644 src/DotTiled.Tests/TestData/Maps/default-map-base64-zstd/default-map-base64-zstd.cs
create mode 100644 src/DotTiled.Tests/TestData/Maps/default-map-base64-zstd/default-map-base64-zstd.tmj
create mode 100644 src/DotTiled.Tests/TestData/Maps/default-map-base64-zstd/default-map-base64-zstd.tmx
diff --git a/src/DotTiled.Tests/TestData/Maps/default-map-base64-zstd/default-map-base64-zstd.cs b/src/DotTiled.Tests/TestData/Maps/default-map-base64-zstd/default-map-base64-zstd.cs
new file mode 100644
index 0000000..5aa5401
--- /dev/null
+++ b/src/DotTiled.Tests/TestData/Maps/default-map-base64-zstd/default-map-base64-zstd.cs
@@ -0,0 +1,52 @@
+namespace DotTiled.Tests;
+
+public partial class TestData
+{
+ public static Map DefaultMapBase64ZStd() => new Map
+ {
+ Class = "",
+ Orientation = MapOrientation.Orthogonal,
+ Width = 5,
+ Height = 5,
+ TileWidth = 32,
+ TileHeight = 32,
+ Infinite = false,
+ ParallaxOriginX = 0,
+ ParallaxOriginY = 0,
+ RenderOrder = RenderOrder.RightDown,
+ CompressionLevel = -1,
+ BackgroundColor = new TiledColor { R = 0, G = 0, B = 0, A = 0 },
+ Version = "1.10",
+ TiledVersion = "1.11.2",
+ NextLayerID = 2,
+ NextObjectID = 1,
+ Layers = [
+ new TileLayer
+ {
+ ID = 1,
+ Name = "Tile Layer 1",
+ Width = 5,
+ Height = 5,
+ Data = new Data
+ {
+ Encoding = DataEncoding.Base64,
+ Compression = DataCompression.ZStd,
+ GlobalTileIDs = new Optional([
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0
+ ]),
+ FlippingFlags = new Optional([
+ FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None,
+ FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None,
+ FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None,
+ FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None,
+ FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None
+ ])
+ }
+ }
+ ]
+ };
+}
diff --git a/src/DotTiled.Tests/TestData/Maps/default-map-base64-zstd/default-map-base64-zstd.tmj b/src/DotTiled.Tests/TestData/Maps/default-map-base64-zstd/default-map-base64-zstd.tmj
new file mode 100644
index 0000000..49e6a43
--- /dev/null
+++ b/src/DotTiled.Tests/TestData/Maps/default-map-base64-zstd/default-map-base64-zstd.tmj
@@ -0,0 +1,30 @@
+{ "compressionlevel":-1,
+ "height":5,
+ "infinite":false,
+ "layers":[
+ {
+ "compression":"zstd",
+ "data":"KLUv\/SBkRQAACAABAIDUCQE=",
+ "encoding":"base64",
+ "height":5,
+ "id":1,
+ "name":"Tile Layer 1",
+ "opacity":1,
+ "type":"tilelayer",
+ "visible":true,
+ "width":5,
+ "x":0,
+ "y":0
+ }],
+ "nextlayerid":2,
+ "nextobjectid":1,
+ "orientation":"orthogonal",
+ "renderorder":"right-down",
+ "tiledversion":"1.11.2",
+ "tileheight":32,
+ "tilesets":[],
+ "tilewidth":32,
+ "type":"map",
+ "version":"1.10",
+ "width":5
+}
\ No newline at end of file
diff --git a/src/DotTiled.Tests/TestData/Maps/default-map-base64-zstd/default-map-base64-zstd.tmx b/src/DotTiled.Tests/TestData/Maps/default-map-base64-zstd/default-map-base64-zstd.tmx
new file mode 100644
index 0000000..a8a069a
--- /dev/null
+++ b/src/DotTiled.Tests/TestData/Maps/default-map-base64-zstd/default-map-base64-zstd.tmx
@@ -0,0 +1,8 @@
+
+
diff --git a/src/DotTiled.Tests/UnitTests/Serialization/TestData.cs b/src/DotTiled.Tests/UnitTests/Serialization/TestData.cs
index 2256f83..55e5291 100644
--- a/src/DotTiled.Tests/UnitTests/Serialization/TestData.cs
+++ b/src/DotTiled.Tests/UnitTests/Serialization/TestData.cs
@@ -37,6 +37,7 @@ public static partial class TestData
[GetMapPath("default-map-base64"), (string f) => DefaultMapBase64(), Array.Empty()],
[GetMapPath("default-map-base64-gzip"), (string f) => DefaultMapBase64GZip(), Array.Empty()],
[GetMapPath("default-map-base64-zlib"), (string f) => DefaultMapBase64ZLib(), Array.Empty()],
+ [GetMapPath("default-map-base64-zstd"), (string f) => DefaultMapBase64ZStd(), Array.Empty()],
[GetMapPath("map-duplicate-object-id-bug"), (string f) => MapDuplicateObjectIdBug(f), Array.Empty()],
[GetMapPath("map-with-common-props"), (string f) => MapWithCommonProps(), Array.Empty()],
[GetMapPath("map-with-custom-type-props"), (string f) => MapWithCustomTypeProps(), MapWithCustomTypePropsCustomTypeDefinitions()],