diff --git a/LiveScanClient/KinectClient.vcxproj b/LiveScanClient/KinectClient.vcxproj
index cfff532..9c01116 100644
--- a/LiveScanClient/KinectClient.vcxproj
+++ b/LiveScanClient/KinectClient.vcxproj
@@ -91,7 +91,7 @@
truec:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Lib\x86\;D:\opencv\build\x86\vc12\lib;$(KINECTSDK20_DIR)\lib\x86;$(SolutionDir)lib
- opencv_highgui248d.lib;opencv_calib3d248d.lib;opencv_imgproc248d.lib;opencv_core248d.lib;kinect20.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ opencv_highgui248d.lib;opencv_calib3d248d.lib;opencv_imgproc248d.lib;opencv_core248d.lib;kinect20.lib;kernel32.lib;libzstdd.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)NotSet
@@ -111,7 +111,7 @@
truetruetrue
- opencv_highgui248.lib;opencv_calib3d248.lib;opencv_imgproc248.lib;opencv_core248.lib;kinect20.lib;%(AdditionalDependencies)
+ opencv_highgui248.lib;opencv_calib3d248.lib;opencv_imgproc248.lib;opencv_core248.lib;kinect20.lib;libzstd.lib;%(AdditionalDependencies)c:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Lib\x86\;D:\opencv\build\x86\vc12\lib;$(KINECTSDK20_DIR)\lib\x86;$(SolutionDir)lib
diff --git a/LiveScanServer/KinectSettings.cs b/LiveScanServer/KinectSettings.cs
index 5366760..f5ed1d8 100644
--- a/LiveScanServer/KinectSettings.cs
+++ b/LiveScanServer/KinectSettings.cs
@@ -35,6 +35,7 @@ namespace KinectServer
public bool bStreamOnlyBodies = false;
public bool bShowSkeletons = true;
+ public int iCompressionLevel = 2; // 0 for no compression, 2 is recommended
public int nNumICPIterations = 10;
public int nNumRefineIters = 2;
@@ -96,6 +97,9 @@ namespace KinectServer
else
lData.Add(0);
+ bTemp = BitConverter.GetBytes(iCompressionLevel);
+ lData.AddRange(bTemp);
+
return lData;
}
}
diff --git a/LiveScanServer/KinectSocket.cs b/LiveScanServer/KinectSocket.cs
index b962ba9..39b8d6d 100644
--- a/LiveScanServer/KinectSocket.cs
+++ b/LiveScanServer/KinectSocket.cs
@@ -42,7 +42,7 @@ namespace KinectServer
public List lFrameRGB = new List();
public List lFrameVerts = new List();
- public List lBodies = new List();
+ public List lBodies = new List();
public event SocketChangedHandler eChanged;
@@ -165,19 +165,16 @@ namespace KinectServer
return;
}
- oSocket.Receive(buffer, 4, SocketFlags.None);
-
- //string result = System.Text.Encoding.UTF8.GetString(buffer);
- //n_to_read = Int32.Parse(result);
-
+ oSocket.Receive(buffer, 8, SocketFlags.None);
nToRead = BitConverter.ToInt32(buffer, 0);
+ int iCompressed = BitConverter.ToInt32(buffer, 4);
if (nToRead == -1)
{
bNoMoreStoredFrames = true;
return;
}
-
+
buffer = new byte[nToRead];
int nAlreadyRead = 0;
@@ -192,6 +189,12 @@ namespace KinectServer
nAlreadyRead += oSocket.Receive(buffer, nAlreadyRead, nToRead - nAlreadyRead, SocketFlags.None);
}
+
+
+
+ if (iCompressed == 1)
+ buffer = ZSTDDecompressor.Decompress(buffer);
+
//Receive depth and color data
int startIdx = 0;
diff --git a/LiveScanServer/LiveScanServer.csproj b/LiveScanServer/LiveScanServer.csproj
index 18c2276..a86cd5a 100644
--- a/LiveScanServer/LiveScanServer.csproj
+++ b/LiveScanServer/LiveScanServer.csproj
@@ -32,7 +32,10 @@
4
-
+
+ False
+ ..\bin\OpenTK.dll
+
@@ -68,8 +71,10 @@
+ MainWindowForm.cs
+ DesignerResXFileCodeGenerator
diff --git a/LiveScanServer/SettingsForm.Designer.cs b/LiveScanServer/SettingsForm.Designer.cs
index ef9c06c..0a4a91b 100644
--- a/LiveScanServer/SettingsForm.Designer.cs
+++ b/LiveScanServer/SettingsForm.Designer.cs
@@ -34,7 +34,7 @@
this.txtICPIters = new System.Windows.Forms.TextBox();
this.grClient = new System.Windows.Forms.GroupBox();
this.grBody = new System.Windows.Forms.GroupBox();
- this.label1 = new System.Windows.Forms.Label();
+ this.chSkeletons = new System.Windows.Forms.CheckBox();
this.chBodyData = new System.Windows.Forms.CheckBox();
this.grMarkers = new System.Windows.Forms.GroupBox();
this.lbX2 = new System.Windows.Forms.Label();
@@ -77,7 +77,8 @@
this.rAsciiPly = new System.Windows.Forms.RadioButton();
this.txtRefinIters = new System.Windows.Forms.TextBox();
this.lbOuterIters = new System.Windows.Forms.Label();
- this.chSkeletons = new System.Windows.Forms.CheckBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.cbCompressionLevel = new System.Windows.Forms.ComboBox();
this.grClient.SuspendLayout();
this.grBody.SuspendLayout();
this.grMarkers.SuspendLayout();
@@ -89,18 +90,20 @@
// lbMerge
//
this.lbMerge.AutoSize = true;
- this.lbMerge.Location = new System.Drawing.Point(6, 49);
+ this.lbMerge.Location = new System.Drawing.Point(7, 69);
+ this.lbMerge.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbMerge.Name = "lbMerge";
- this.lbMerge.Size = new System.Drawing.Size(69, 13);
+ this.lbMerge.Size = new System.Drawing.Size(99, 20);
this.lbMerge.TabIndex = 22;
this.lbMerge.Text = "Scan saving:";
//
// chMerge
//
this.chMerge.AutoSize = true;
- this.chMerge.Location = new System.Drawing.Point(98, 48);
+ this.chMerge.Location = new System.Drawing.Point(156, 70);
+ this.chMerge.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.chMerge.Name = "chMerge";
- this.chMerge.Size = new System.Drawing.Size(86, 17);
+ this.chMerge.Size = new System.Drawing.Size(126, 24);
this.chMerge.TabIndex = 23;
this.chMerge.Text = "merge scans";
this.chMerge.UseVisualStyleBackColor = true;
@@ -109,17 +112,19 @@
// lbICPIters
//
this.lbICPIters.AutoSize = true;
- this.lbICPIters.Location = new System.Drawing.Point(6, 26);
+ this.lbICPIters.Location = new System.Drawing.Point(7, 34);
+ this.lbICPIters.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbICPIters.Name = "lbICPIters";
- this.lbICPIters.Size = new System.Drawing.Size(86, 13);
+ this.lbICPIters.Size = new System.Drawing.Size(128, 20);
this.lbICPIters.TabIndex = 24;
this.lbICPIters.Text = "Num of ICP iters:";
//
// txtICPIters
//
- this.txtICPIters.Location = new System.Drawing.Point(98, 23);
+ this.txtICPIters.Location = new System.Drawing.Point(156, 31);
+ this.txtICPIters.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtICPIters.Name = "txtICPIters";
- this.txtICPIters.Size = new System.Drawing.Size(38, 20);
+ this.txtICPIters.Size = new System.Drawing.Size(55, 26);
this.txtICPIters.TabIndex = 25;
this.txtICPIters.TextChanged += new System.EventHandler(this.txtICPIters_TextChanged);
//
@@ -129,9 +134,11 @@
this.grClient.Controls.Add(this.grMarkers);
this.grClient.Controls.Add(this.grBounding);
this.grClient.Controls.Add(this.grFiltering);
- this.grClient.Location = new System.Drawing.Point(12, 12);
+ this.grClient.Location = new System.Drawing.Point(18, 18);
+ this.grClient.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.grClient.Name = "grClient";
- this.grClient.Size = new System.Drawing.Size(632, 327);
+ this.grClient.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.grClient.Size = new System.Drawing.Size(948, 447);
this.grClient.TabIndex = 43;
this.grClient.TabStop = false;
this.grClient.Text = "KinectClient settings";
@@ -139,30 +146,35 @@
// grBody
//
this.grBody.Controls.Add(this.chSkeletons);
- this.grBody.Controls.Add(this.label1);
this.grBody.Controls.Add(this.chBodyData);
- this.grBody.Location = new System.Drawing.Point(9, 211);
+ this.grBody.Location = new System.Drawing.Point(14, 325);
+ this.grBody.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.grBody.Name = "grBody";
- this.grBody.Size = new System.Drawing.Size(249, 110);
+ this.grBody.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.grBody.Size = new System.Drawing.Size(374, 101);
this.grBody.TabIndex = 47;
this.grBody.TabStop = false;
this.grBody.Text = "Body data";
//
- // label1
+ // chSkeletons
//
- this.label1.AutoSize = true;
- this.label1.Location = new System.Drawing.Point(8, 61);
- this.label1.Name = "label1";
- this.label1.Size = new System.Drawing.Size(187, 13);
- this.label1.TabIndex = 20;
- this.label1.Text = "More features will be added here soon";
+ this.chSkeletons.AutoSize = true;
+ this.chSkeletons.Location = new System.Drawing.Point(16, 63);
+ this.chSkeletons.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.chSkeletons.Name = "chSkeletons";
+ this.chSkeletons.Size = new System.Drawing.Size(220, 24);
+ this.chSkeletons.TabIndex = 21;
+ this.chSkeletons.Text = "show skeletons in live view";
+ this.chSkeletons.UseVisualStyleBackColor = true;
+ this.chSkeletons.CheckedChanged += new System.EventHandler(this.chSkeletons_CheckedChanged);
//
// chBodyData
//
this.chBodyData.AutoSize = true;
- this.chBodyData.Location = new System.Drawing.Point(11, 19);
+ this.chBodyData.Location = new System.Drawing.Point(16, 29);
+ this.chBodyData.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.chBodyData.Name = "chBodyData";
- this.chBodyData.Size = new System.Drawing.Size(113, 17);
+ this.chBodyData.Size = new System.Drawing.Size(167, 24);
this.chBodyData.TabIndex = 19;
this.chBodyData.Text = "stream only bodies";
this.chBodyData.UseVisualStyleBackColor = true;
@@ -186,9 +198,11 @@
this.grMarkers.Controls.Add(this.txtTranslationX);
this.grMarkers.Controls.Add(this.lisMarkers);
this.grMarkers.Controls.Add(this.txtTranslationY);
- this.grMarkers.Location = new System.Drawing.Point(271, 19);
+ this.grMarkers.Location = new System.Drawing.Point(406, 29);
+ this.grMarkers.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.grMarkers.Name = "grMarkers";
- this.grMarkers.Size = new System.Drawing.Size(353, 185);
+ this.grMarkers.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.grMarkers.Size = new System.Drawing.Size(530, 285);
this.grMarkers.TabIndex = 45;
this.grMarkers.TabStop = false;
this.grMarkers.Text = "Calibration markers";
@@ -196,17 +210,19 @@
// lbX2
//
this.lbX2.AutoSize = true;
- this.lbX2.Location = new System.Drawing.Point(230, 19);
+ this.lbX2.Location = new System.Drawing.Point(345, 29);
+ this.lbX2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbX2.Name = "lbX2";
- this.lbX2.Size = new System.Drawing.Size(14, 13);
+ this.lbX2.Size = new System.Drawing.Size(20, 20);
this.lbX2.TabIndex = 49;
this.lbX2.Text = "X";
//
// btRemove
//
- this.btRemove.Location = new System.Drawing.Point(233, 127);
+ this.btRemove.Location = new System.Drawing.Point(350, 195);
+ this.btRemove.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.btRemove.Name = "btRemove";
- this.btRemove.Size = new System.Drawing.Size(92, 23);
+ this.btRemove.Size = new System.Drawing.Size(138, 35);
this.btRemove.TabIndex = 59;
this.btRemove.Text = "Remove marker";
this.btRemove.UseVisualStyleBackColor = true;
@@ -214,68 +230,76 @@
//
// txtOrientationZ
//
- this.txtOrientationZ.Location = new System.Drawing.Point(305, 38);
+ this.txtOrientationZ.Location = new System.Drawing.Point(458, 58);
+ this.txtOrientationZ.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtOrientationZ.Name = "txtOrientationZ";
- this.txtOrientationZ.Size = new System.Drawing.Size(38, 20);
+ this.txtOrientationZ.Size = new System.Drawing.Size(55, 26);
this.txtOrientationZ.TabIndex = 48;
this.txtOrientationZ.TextChanged += new System.EventHandler(this.txtOrientationZ_TextChanged);
//
// txtId
//
- this.txtId.Location = new System.Drawing.Point(217, 93);
+ this.txtId.Location = new System.Drawing.Point(326, 143);
+ this.txtId.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtId.Name = "txtId";
- this.txtId.Size = new System.Drawing.Size(38, 20);
+ this.txtId.Size = new System.Drawing.Size(55, 26);
this.txtId.TabIndex = 58;
this.txtId.TextChanged += new System.EventHandler(this.txtId_TextChanged);
//
// lbY2
//
this.lbY2.AutoSize = true;
- this.lbY2.Location = new System.Drawing.Point(274, 19);
+ this.lbY2.Location = new System.Drawing.Point(411, 29);
+ this.lbY2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbY2.Name = "lbY2";
- this.lbY2.Size = new System.Drawing.Size(14, 13);
+ this.lbY2.Size = new System.Drawing.Size(20, 20);
this.lbY2.TabIndex = 50;
this.lbY2.Text = "Y";
//
// txtOrientationY
//
- this.txtOrientationY.Location = new System.Drawing.Point(261, 38);
+ this.txtOrientationY.Location = new System.Drawing.Point(392, 58);
+ this.txtOrientationY.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtOrientationY.Name = "txtOrientationY";
- this.txtOrientationY.Size = new System.Drawing.Size(38, 20);
+ this.txtOrientationY.Size = new System.Drawing.Size(55, 26);
this.txtOrientationY.TabIndex = 47;
this.txtOrientationY.TextChanged += new System.EventHandler(this.txtOrientationY_TextChanged);
//
// lbId
//
this.lbId.AutoSize = true;
- this.lbId.Location = new System.Drawing.Point(132, 96);
+ this.lbId.Location = new System.Drawing.Point(198, 148);
+ this.lbId.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbId.Name = "lbId";
- this.lbId.Size = new System.Drawing.Size(54, 13);
+ this.lbId.Size = new System.Drawing.Size(78, 20);
this.lbId.TabIndex = 57;
this.lbId.Text = "Marker id:";
//
// lbZ2
//
this.lbZ2.AutoSize = true;
- this.lbZ2.Location = new System.Drawing.Point(317, 19);
+ this.lbZ2.Location = new System.Drawing.Point(476, 29);
+ this.lbZ2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbZ2.Name = "lbZ2";
- this.lbZ2.Size = new System.Drawing.Size(14, 13);
+ this.lbZ2.Size = new System.Drawing.Size(19, 20);
this.lbZ2.TabIndex = 51;
this.lbZ2.Text = "Z";
//
// txtOrientationX
//
- this.txtOrientationX.Location = new System.Drawing.Point(217, 38);
+ this.txtOrientationX.Location = new System.Drawing.Point(326, 58);
+ this.txtOrientationX.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtOrientationX.Name = "txtOrientationX";
- this.txtOrientationX.Size = new System.Drawing.Size(38, 20);
+ this.txtOrientationX.Size = new System.Drawing.Size(55, 26);
this.txtOrientationX.TabIndex = 46;
this.txtOrientationX.TextChanged += new System.EventHandler(this.txtOrientationX_TextChanged);
//
// btAdd
//
- this.btAdd.Location = new System.Drawing.Point(135, 127);
+ this.btAdd.Location = new System.Drawing.Point(202, 195);
+ this.btAdd.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.btAdd.Name = "btAdd";
- this.btAdd.Size = new System.Drawing.Size(92, 23);
+ this.btAdd.Size = new System.Drawing.Size(138, 35);
this.btAdd.TabIndex = 56;
this.btAdd.Text = "Add marker";
this.btAdd.UseVisualStyleBackColor = true;
@@ -284,51 +308,58 @@
// lbTranslation
//
this.lbTranslation.AutoSize = true;
- this.lbTranslation.Location = new System.Drawing.Point(132, 68);
+ this.lbTranslation.Location = new System.Drawing.Point(198, 105);
+ this.lbTranslation.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbTranslation.Name = "lbTranslation";
- this.lbTranslation.Size = new System.Drawing.Size(62, 13);
+ this.lbTranslation.Size = new System.Drawing.Size(91, 20);
this.lbTranslation.TabIndex = 52;
this.lbTranslation.Text = "Translation:";
//
// lbOrientation
//
this.lbOrientation.AutoSize = true;
- this.lbOrientation.Location = new System.Drawing.Point(132, 41);
+ this.lbOrientation.Location = new System.Drawing.Point(198, 63);
+ this.lbOrientation.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbOrientation.Name = "lbOrientation";
- this.lbOrientation.Size = new System.Drawing.Size(61, 13);
+ this.lbOrientation.Size = new System.Drawing.Size(91, 20);
this.lbOrientation.TabIndex = 45;
this.lbOrientation.Text = "Orientation:";
//
// txtTranslationZ
//
- this.txtTranslationZ.Location = new System.Drawing.Point(305, 65);
+ this.txtTranslationZ.Location = new System.Drawing.Point(458, 100);
+ this.txtTranslationZ.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtTranslationZ.Name = "txtTranslationZ";
- this.txtTranslationZ.Size = new System.Drawing.Size(38, 20);
+ this.txtTranslationZ.Size = new System.Drawing.Size(55, 26);
this.txtTranslationZ.TabIndex = 55;
this.txtTranslationZ.TextChanged += new System.EventHandler(this.txtTranslationZ_TextChanged);
//
// txtTranslationX
//
- this.txtTranslationX.Location = new System.Drawing.Point(217, 65);
+ this.txtTranslationX.Location = new System.Drawing.Point(326, 100);
+ this.txtTranslationX.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtTranslationX.Name = "txtTranslationX";
- this.txtTranslationX.Size = new System.Drawing.Size(38, 20);
+ this.txtTranslationX.Size = new System.Drawing.Size(55, 26);
this.txtTranslationX.TabIndex = 53;
this.txtTranslationX.TextChanged += new System.EventHandler(this.txtTranslationX_TextChanged);
//
// lisMarkers
//
this.lisMarkers.FormattingEnabled = true;
- this.lisMarkers.Location = new System.Drawing.Point(6, 41);
+ this.lisMarkers.ItemHeight = 20;
+ this.lisMarkers.Location = new System.Drawing.Point(9, 63);
+ this.lisMarkers.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.lisMarkers.Name = "lisMarkers";
- this.lisMarkers.Size = new System.Drawing.Size(120, 108);
+ this.lisMarkers.Size = new System.Drawing.Size(178, 164);
this.lisMarkers.TabIndex = 43;
this.lisMarkers.SelectedIndexChanged += new System.EventHandler(this.lisMarkers_SelectedIndexChanged);
//
// txtTranslationY
//
- this.txtTranslationY.Location = new System.Drawing.Point(261, 65);
+ this.txtTranslationY.Location = new System.Drawing.Point(392, 100);
+ this.txtTranslationY.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtTranslationY.Name = "txtTranslationY";
- this.txtTranslationY.Size = new System.Drawing.Size(38, 20);
+ this.txtTranslationY.Size = new System.Drawing.Size(55, 26);
this.txtTranslationY.TabIndex = 54;
this.txtTranslationY.TextChanged += new System.EventHandler(this.txtTranslationY_TextChanged);
//
@@ -345,9 +376,11 @@
this.grBounding.Controls.Add(this.lbZ);
this.grBounding.Controls.Add(this.lbY);
this.grBounding.Controls.Add(this.lbX);
- this.grBounding.Location = new System.Drawing.Point(9, 19);
+ this.grBounding.Location = new System.Drawing.Point(14, 29);
+ this.grBounding.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.grBounding.Name = "grBounding";
- this.grBounding.Size = new System.Drawing.Size(249, 91);
+ this.grBounding.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.grBounding.Size = new System.Drawing.Size(374, 140);
this.grBounding.TabIndex = 46;
this.grBounding.TabStop = false;
this.grBounding.Text = "Bounding box";
@@ -355,93 +388,104 @@
// lbMin
//
this.lbMin.AutoSize = true;
- this.lbMin.Location = new System.Drawing.Point(8, 38);
+ this.lbMin.Location = new System.Drawing.Point(12, 58);
+ this.lbMin.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbMin.Name = "lbMin";
- this.lbMin.Size = new System.Drawing.Size(65, 13);
+ this.lbMin.Size = new System.Drawing.Size(95, 20);
this.lbMin.TabIndex = 13;
this.lbMin.Text = "Min bounds:";
//
// txtMaxZ
//
- this.txtMaxZ.Location = new System.Drawing.Point(181, 62);
+ this.txtMaxZ.Location = new System.Drawing.Point(272, 95);
+ this.txtMaxZ.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtMaxZ.Name = "txtMaxZ";
- this.txtMaxZ.Size = new System.Drawing.Size(38, 20);
+ this.txtMaxZ.Size = new System.Drawing.Size(55, 26);
this.txtMaxZ.TabIndex = 23;
this.txtMaxZ.TextChanged += new System.EventHandler(this.txtMaxZ_TextChanged);
//
// txtMaxY
//
- this.txtMaxY.Location = new System.Drawing.Point(137, 62);
+ this.txtMaxY.Location = new System.Drawing.Point(206, 95);
+ this.txtMaxY.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtMaxY.Name = "txtMaxY";
- this.txtMaxY.Size = new System.Drawing.Size(38, 20);
+ this.txtMaxY.Size = new System.Drawing.Size(55, 26);
this.txtMaxY.TabIndex = 22;
this.txtMaxY.TextChanged += new System.EventHandler(this.txtMaxY_TextChanged);
//
// txtMinX
//
- this.txtMinX.Location = new System.Drawing.Point(93, 35);
+ this.txtMinX.Location = new System.Drawing.Point(140, 54);
+ this.txtMinX.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtMinX.Name = "txtMinX";
- this.txtMinX.Size = new System.Drawing.Size(38, 20);
+ this.txtMinX.Size = new System.Drawing.Size(55, 26);
this.txtMinX.TabIndex = 14;
this.txtMinX.TextChanged += new System.EventHandler(this.txtMinX_TextChanged);
//
// txtMaxX
//
- this.txtMaxX.Location = new System.Drawing.Point(93, 62);
+ this.txtMaxX.Location = new System.Drawing.Point(140, 95);
+ this.txtMaxX.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtMaxX.Name = "txtMaxX";
- this.txtMaxX.Size = new System.Drawing.Size(38, 20);
+ this.txtMaxX.Size = new System.Drawing.Size(55, 26);
this.txtMaxX.TabIndex = 21;
this.txtMaxX.TextChanged += new System.EventHandler(this.txtMaxX_TextChanged);
//
// txtMinY
//
- this.txtMinY.Location = new System.Drawing.Point(137, 35);
+ this.txtMinY.Location = new System.Drawing.Point(206, 54);
+ this.txtMinY.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtMinY.Name = "txtMinY";
- this.txtMinY.Size = new System.Drawing.Size(38, 20);
+ this.txtMinY.Size = new System.Drawing.Size(55, 26);
this.txtMinY.TabIndex = 15;
this.txtMinY.TextChanged += new System.EventHandler(this.txtMinY_TextChanged);
//
// lbMax
//
this.lbMax.AutoSize = true;
- this.lbMax.Location = new System.Drawing.Point(8, 65);
+ this.lbMax.Location = new System.Drawing.Point(12, 100);
+ this.lbMax.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbMax.Name = "lbMax";
- this.lbMax.Size = new System.Drawing.Size(68, 13);
+ this.lbMax.Size = new System.Drawing.Size(99, 20);
this.lbMax.TabIndex = 20;
this.lbMax.Text = "Max bounds:";
//
// txtMinZ
//
- this.txtMinZ.Location = new System.Drawing.Point(181, 35);
+ this.txtMinZ.Location = new System.Drawing.Point(272, 54);
+ this.txtMinZ.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtMinZ.Name = "txtMinZ";
- this.txtMinZ.Size = new System.Drawing.Size(38, 20);
+ this.txtMinZ.Size = new System.Drawing.Size(55, 26);
this.txtMinZ.TabIndex = 16;
this.txtMinZ.TextChanged += new System.EventHandler(this.txtMinZ_TextChanged);
//
// lbZ
//
this.lbZ.AutoSize = true;
- this.lbZ.Location = new System.Drawing.Point(193, 16);
+ this.lbZ.Location = new System.Drawing.Point(290, 25);
+ this.lbZ.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbZ.Name = "lbZ";
- this.lbZ.Size = new System.Drawing.Size(14, 13);
+ this.lbZ.Size = new System.Drawing.Size(19, 20);
this.lbZ.TabIndex = 19;
this.lbZ.Text = "Z";
//
// lbY
//
this.lbY.AutoSize = true;
- this.lbY.Location = new System.Drawing.Point(150, 16);
+ this.lbY.Location = new System.Drawing.Point(225, 25);
+ this.lbY.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbY.Name = "lbY";
- this.lbY.Size = new System.Drawing.Size(14, 13);
+ this.lbY.Size = new System.Drawing.Size(20, 20);
this.lbY.TabIndex = 18;
this.lbY.Text = "Y";
//
// lbX
//
this.lbX.AutoSize = true;
- this.lbX.Location = new System.Drawing.Point(106, 16);
+ this.lbX.Location = new System.Drawing.Point(159, 25);
+ this.lbX.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbX.Name = "lbX";
- this.lbX.Size = new System.Drawing.Size(14, 13);
+ this.lbX.Size = new System.Drawing.Size(20, 20);
this.lbX.TabIndex = 17;
this.lbX.Text = "X";
//
@@ -452,27 +496,31 @@
this.grFiltering.Controls.Add(this.lbFilterNeighbors);
this.grFiltering.Controls.Add(this.lbFilterDistance);
this.grFiltering.Controls.Add(this.txtFilterDistance);
- this.grFiltering.Location = new System.Drawing.Point(9, 116);
+ this.grFiltering.Location = new System.Drawing.Point(14, 178);
+ this.grFiltering.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.grFiltering.Name = "grFiltering";
- this.grFiltering.Size = new System.Drawing.Size(249, 88);
+ this.grFiltering.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.grFiltering.Size = new System.Drawing.Size(374, 135);
this.grFiltering.TabIndex = 45;
this.grFiltering.TabStop = false;
this.grFiltering.Text = "Filtering";
//
// txtFilterNeighbors
//
- this.txtFilterNeighbors.Location = new System.Drawing.Point(93, 39);
+ this.txtFilterNeighbors.Location = new System.Drawing.Point(140, 60);
+ this.txtFilterNeighbors.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtFilterNeighbors.Name = "txtFilterNeighbors";
- this.txtFilterNeighbors.Size = new System.Drawing.Size(38, 20);
+ this.txtFilterNeighbors.Size = new System.Drawing.Size(55, 26);
this.txtFilterNeighbors.TabIndex = 20;
this.txtFilterNeighbors.TextChanged += new System.EventHandler(this.txtFilterNeighbors_TextChanged);
//
// chFilter
//
this.chFilter.AutoSize = true;
- this.chFilter.Location = new System.Drawing.Point(93, 16);
+ this.chFilter.Location = new System.Drawing.Point(140, 25);
+ this.chFilter.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.chFilter.Name = "chFilter";
- this.chFilter.Size = new System.Drawing.Size(100, 17);
+ this.chFilter.Size = new System.Drawing.Size(147, 24);
this.chFilter.TabIndex = 18;
this.chFilter.Text = "filtering enabled";
this.chFilter.UseVisualStyleBackColor = true;
@@ -481,31 +529,36 @@
// lbFilterNeighbors
//
this.lbFilterNeighbors.AutoSize = true;
- this.lbFilterNeighbors.Location = new System.Drawing.Point(8, 42);
+ this.lbFilterNeighbors.Location = new System.Drawing.Point(12, 65);
+ this.lbFilterNeighbors.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbFilterNeighbors.Name = "lbFilterNeighbors";
- this.lbFilterNeighbors.Size = new System.Drawing.Size(67, 13);
+ this.lbFilterNeighbors.Size = new System.Drawing.Size(98, 20);
this.lbFilterNeighbors.TabIndex = 19;
this.lbFilterNeighbors.Text = "N neighbors:";
//
// lbFilterDistance
//
this.lbFilterDistance.AutoSize = true;
- this.lbFilterDistance.Location = new System.Drawing.Point(8, 68);
+ this.lbFilterDistance.Location = new System.Drawing.Point(12, 105);
+ this.lbFilterDistance.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbFilterDistance.Name = "lbFilterDistance";
- this.lbFilterDistance.Size = new System.Drawing.Size(73, 13);
+ this.lbFilterDistance.Size = new System.Drawing.Size(106, 20);
this.lbFilterDistance.TabIndex = 21;
this.lbFilterDistance.Text = "Max distance:";
//
// txtFilterDistance
//
- this.txtFilterDistance.Location = new System.Drawing.Point(93, 65);
+ this.txtFilterDistance.Location = new System.Drawing.Point(140, 100);
+ this.txtFilterDistance.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtFilterDistance.Name = "txtFilterDistance";
- this.txtFilterDistance.Size = new System.Drawing.Size(38, 20);
+ this.txtFilterDistance.Size = new System.Drawing.Size(55, 26);
this.txtFilterDistance.TabIndex = 22;
this.txtFilterDistance.TextChanged += new System.EventHandler(this.txtFilterDistance_TextChanged);
//
// grServer
//
+ this.grServer.Controls.Add(this.cbCompressionLevel);
+ this.grServer.Controls.Add(this.label2);
this.grServer.Controls.Add(this.rBinaryPly);
this.grServer.Controls.Add(this.lbFormat);
this.grServer.Controls.Add(this.rAsciiPly);
@@ -515,9 +568,11 @@
this.grServer.Controls.Add(this.txtICPIters);
this.grServer.Controls.Add(this.chMerge);
this.grServer.Controls.Add(this.lbICPIters);
- this.grServer.Location = new System.Drawing.Point(12, 345);
+ this.grServer.Location = new System.Drawing.Point(18, 478);
+ this.grServer.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.grServer.Name = "grServer";
- this.grServer.Size = new System.Drawing.Size(632, 111);
+ this.grServer.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.grServer.Size = new System.Drawing.Size(948, 175);
this.grServer.TabIndex = 44;
this.grServer.TabStop = false;
this.grServer.Text = "KinectServer settings";
@@ -525,9 +580,10 @@
// rBinaryPly
//
this.rBinaryPly.AutoSize = true;
- this.rBinaryPly.Location = new System.Drawing.Point(179, 71);
+ this.rBinaryPly.Location = new System.Drawing.Point(277, 105);
+ this.rBinaryPly.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.rBinaryPly.Name = "rBinaryPly";
- this.rBinaryPly.Size = new System.Drawing.Size(76, 17);
+ this.rBinaryPly.Size = new System.Drawing.Size(110, 24);
this.rBinaryPly.TabIndex = 30;
this.rBinaryPly.TabStop = true;
this.rBinaryPly.Text = "binary PLY";
@@ -537,18 +593,20 @@
// lbFormat
//
this.lbFormat.AutoSize = true;
- this.lbFormat.Location = new System.Drawing.Point(6, 73);
+ this.lbFormat.Location = new System.Drawing.Point(7, 106);
+ this.lbFormat.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbFormat.Name = "lbFormat";
- this.lbFormat.Size = new System.Drawing.Size(58, 13);
+ this.lbFormat.Size = new System.Drawing.Size(88, 20);
this.lbFormat.TabIndex = 29;
this.lbFormat.Text = "File format:";
//
// rAsciiPly
//
this.rAsciiPly.AutoSize = true;
- this.rAsciiPly.Location = new System.Drawing.Point(98, 71);
+ this.rAsciiPly.Location = new System.Drawing.Point(156, 105);
+ this.rAsciiPly.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.rAsciiPly.Name = "rAsciiPly";
- this.rAsciiPly.Size = new System.Drawing.Size(75, 17);
+ this.rAsciiPly.Size = new System.Drawing.Size(111, 24);
this.rAsciiPly.TabIndex = 28;
this.rAsciiPly.TabStop = true;
this.rAsciiPly.Text = "ASCII PLY";
@@ -557,40 +615,63 @@
//
// txtRefinIters
//
- this.txtRefinIters.Location = new System.Drawing.Point(266, 23);
+ this.txtRefinIters.Location = new System.Drawing.Point(408, 31);
+ this.txtRefinIters.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.txtRefinIters.Name = "txtRefinIters";
- this.txtRefinIters.Size = new System.Drawing.Size(38, 20);
+ this.txtRefinIters.Size = new System.Drawing.Size(55, 26);
this.txtRefinIters.TabIndex = 27;
this.txtRefinIters.TextChanged += new System.EventHandler(this.txtRefinIters_TextChanged);
//
// lbOuterIters
//
this.lbOuterIters.AutoSize = true;
- this.lbOuterIters.Location = new System.Drawing.Point(142, 26);
+ this.lbOuterIters.Location = new System.Drawing.Point(222, 36);
+ this.lbOuterIters.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.lbOuterIters.Name = "lbOuterIters";
- this.lbOuterIters.Size = new System.Drawing.Size(118, 13);
+ this.lbOuterIters.Size = new System.Drawing.Size(178, 20);
this.lbOuterIters.TabIndex = 26;
this.lbOuterIters.Text = "Num of refinement iters:";
//
- // chSkeletons
+ // label2
//
- this.chSkeletons.AutoSize = true;
- this.chSkeletons.Location = new System.Drawing.Point(11, 41);
- this.chSkeletons.Name = "chSkeletons";
- this.chSkeletons.Size = new System.Drawing.Size(154, 17);
- this.chSkeletons.TabIndex = 21;
- this.chSkeletons.Text = "show skeletons in live view";
- this.chSkeletons.UseVisualStyleBackColor = true;
- this.chSkeletons.CheckedChanged += new System.EventHandler(this.chSkeletons_CheckedChanged);
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(8, 139);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(141, 20);
+ this.label2.TabIndex = 31;
+ this.label2.Text = "Compression level:";
+ //
+ // cbCompressionLevel
+ //
+ this.cbCompressionLevel.FormattingEnabled = true;
+ this.cbCompressionLevel.Items.AddRange(new object[] {
+ "0 (no compression)",
+ "1",
+ "2 (recommended)",
+ "3",
+ "5",
+ "7",
+ "9",
+ "11",
+ "13",
+ "15",
+ "17",
+ "19"});
+ this.cbCompressionLevel.Location = new System.Drawing.Point(154, 136);
+ this.cbCompressionLevel.Name = "cbCompressionLevel";
+ this.cbCompressionLevel.Size = new System.Drawing.Size(169, 28);
+ this.cbCompressionLevel.TabIndex = 32;
+ this.cbCompressionLevel.SelectedIndexChanged += new System.EventHandler(this.cbCompressionLevel_SelectedIndexChanged);
//
// SettingsForm
//
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(656, 468);
+ this.ClientSize = new System.Drawing.Size(984, 663);
this.Controls.Add(this.grServer);
this.Controls.Add(this.grClient);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.MaximizeBox = false;
this.Name = "SettingsForm";
this.Text = "Settings";
@@ -657,11 +738,12 @@
private System.Windows.Forms.Label lbX;
private System.Windows.Forms.GroupBox grBody;
private System.Windows.Forms.CheckBox chBodyData;
- private System.Windows.Forms.Label label1;
private System.Windows.Forms.RadioButton rBinaryPly;
private System.Windows.Forms.Label lbFormat;
private System.Windows.Forms.RadioButton rAsciiPly;
private System.Windows.Forms.CheckBox chSkeletons;
+ private System.Windows.Forms.ComboBox cbCompressionLevel;
+ private System.Windows.Forms.Label label2;
}
}
\ No newline at end of file
diff --git a/LiveScanServer/SettingsForm.cs b/LiveScanServer/SettingsForm.cs
index 0ec42c6..20c2c9b 100644
--- a/LiveScanServer/SettingsForm.cs
+++ b/LiveScanServer/SettingsForm.cs
@@ -54,6 +54,8 @@ namespace KinectServer
chBodyData.Checked = oSettings.bStreamOnlyBodies;
chSkeletons.Checked = oSettings.bShowSkeletons;
+ cbCompressionLevel.SelectedText = oSettings.iCompressionLevel.ToString();
+
chMerge.Checked = oSettings.bMergeScansForSave;
txtICPIters.Text = oSettings.nNumICPIterations.ToString();
txtRefinIters.Text = oSettings.nNumRefineIters.ToString();
@@ -316,5 +318,21 @@ namespace KinectServer
{
oSettings.bShowSkeletons = chSkeletons.Checked;
}
+
+ private void cbCompressionLevel_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ int index = cbCompressionLevel.SelectedIndex;
+ if (index == 0)
+ oSettings.iCompressionLevel = 0;
+ else if (index == 2)
+ oSettings.iCompressionLevel = 2;
+ else
+ {
+ string value = cbCompressionLevel.SelectedItem.ToString();
+ bool tryParse = Int32.TryParse(value, out oSettings.iCompressionLevel);
+ if (!tryParse)
+ oSettings.iCompressionLevel = 0;
+ }
+ }
}
}
diff --git a/LiveScanServer/ZSTDDecompressor.cs b/LiveScanServer/ZSTDDecompressor.cs
new file mode 100644
index 0000000..7e3af98
--- /dev/null
+++ b/LiveScanServer/ZSTDDecompressor.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+using size_t = System.UIntPtr;
+
+namespace KinectServer
+{
+ static class ZSTDDecompressor
+ {
+ private const string dllName = "libzstd.dll";
+
+ [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern ulong ZSTD_getDecompressedSize(IntPtr src, size_t srcSize);
+
+ [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern size_t ZSTD_decompress(IntPtr dst, size_t dstSize,
+ IntPtr src, size_t srcSize);
+
+ public static byte[] Decompress(byte []array)
+ {
+ int size = array.Count();
+ IntPtr ptr = Marshal.AllocHGlobal(size);
+ Marshal.Copy(array, 0, ptr, size);
+
+ int outSize = (int)ZSTD_getDecompressedSize(ptr, (size_t)size);
+
+ IntPtr outPtr = Marshal.AllocHGlobal(outSize);
+ ZSTD_decompress(outPtr, (size_t)outSize, ptr, (size_t)size);
+
+ byte[] outArray = new byte[outSize];
+ Marshal.Copy(outPtr, outArray, 0, outSize);
+
+ Marshal.FreeHGlobal(ptr);
+ Marshal.FreeHGlobal(outPtr);
+ return outArray;
+ }
+ }
+}
diff --git a/bin/libzstd.dll b/bin/libzstd.dll
new file mode 100644
index 0000000..94f9dc1
Binary files /dev/null and b/bin/libzstd.dll differ
diff --git a/include/LiveScanClient/liveScanClient.h b/include/LiveScanClient/liveScanClient.h
index 4f4628d..9c83d7f 100644
--- a/include/LiveScanClient/liveScanClient.h
+++ b/include/LiveScanClient/liveScanClient.h
@@ -52,6 +52,8 @@ private:
bool m_bConfirmCaptured;
bool m_bConfirmCalibrated;
bool m_bShowDepth;
+ bool m_bFrameCompression;
+ int m_iCompressionLevel;
SocketClient *m_pClientSocket;
std::vector m_vBounds;
diff --git a/include/zstd.h b/include/zstd.h
new file mode 100644
index 0000000..333feff
--- /dev/null
+++ b/include/zstd.h
@@ -0,0 +1,692 @@
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#ifndef ZSTD_H_235446
+#define ZSTD_H_235446
+
+/* ====== Dependency ======*/
+#include /* size_t */
+
+
+/* ===== ZSTDLIB_API : control library symbols visibility ===== */
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+# define ZSTDLIB_VISIBILITY __attribute__ ((visibility ("default")))
+#else
+# define ZSTDLIB_VISIBILITY
+#endif
+#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
+# define ZSTDLIB_API __declspec(dllexport) ZSTDLIB_VISIBILITY
+#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
+# define ZSTDLIB_API __declspec(dllimport) ZSTDLIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
+#else
+# define ZSTDLIB_API ZSTDLIB_VISIBILITY
+#endif
+
+
+/*******************************************************************************************************
+ Introduction
+
+ zstd, short for Zstandard, is a fast lossless compression algorithm, targeting real-time compression scenarios
+ at zlib-level and better compression ratios. The zstd compression library provides in-memory compression and
+ decompression functions. The library supports compression levels from 1 up to ZSTD_maxCLevel() which is 22.
+ Levels >= 20, labelled `--ultra`, should be used with caution, as they require more memory.
+ Compression can be done in:
+ - a single step (described as Simple API)
+ - a single step, reusing a context (described as Explicit memory management)
+ - unbounded multiple steps (described as Streaming compression)
+ The compression ratio achievable on small data can be highly improved using compression with a dictionary in:
+ - a single step (described as Simple dictionary API)
+ - a single step, reusing a dictionary (described as Fast dictionary API)
+
+ Advanced experimental functions can be accessed using #define ZSTD_STATIC_LINKING_ONLY before including zstd.h.
+ These APIs shall never be used with a dynamic library.
+ They are not "stable", their definition may change in the future. Only static linking is allowed.
+*********************************************************************************************************/
+
+/*------ Version ------*/
+#define ZSTD_VERSION_MAJOR 1
+#define ZSTD_VERSION_MINOR 1
+#define ZSTD_VERSION_RELEASE 3
+
+#define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE
+#define ZSTD_QUOTE(str) #str
+#define ZSTD_EXPAND_AND_QUOTE(str) ZSTD_QUOTE(str)
+#define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION)
+
+#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
+ZSTDLIB_API unsigned ZSTD_versionNumber(void); /**< library version number; to be used when checking dll version */
+
+
+/***************************************
+* Simple API
+***************************************/
+/*! ZSTD_compress() :
+ Compresses `src` content as a single zstd compressed frame into already allocated `dst`.
+ Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`.
+ @return : compressed size written into `dst` (<= `dstCapacity),
+ or an error code if it fails (which can be tested using ZSTD_isError()). */
+ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ int compressionLevel);
+
+/*! ZSTD_decompress() :
+ `compressedSize` : must be the _exact_ size of a single compressed frame.
+ `dstCapacity` is an upper bound of originalSize.
+ If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data.
+ @return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
+ or an errorCode if it fails (which can be tested using ZSTD_isError()). */
+ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity,
+ const void* src, size_t compressedSize);
+
+/*! ZSTD_getDecompressedSize() :
+* 'src' is the start of a zstd compressed frame.
+* @return : content size to be decompressed, as a 64-bits value _if known_, 0 otherwise.
+* note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode.
+* When `return==0`, data to decompress could be any size.
+* In which case, it's necessary to use streaming mode to decompress data.
+* Optionally, application can still use ZSTD_decompress() while relying on implied limits.
+* (For example, data may be necessarily cut into blocks <= 16 KB).
+* note 2 : decompressed size is always present when compression is done with ZSTD_compress()
+* note 3 : decompressed size can be very large (64-bits value),
+* potentially larger than what local system can handle as a single memory segment.
+* In which case, it's necessary to use streaming mode to decompress data.
+* note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified.
+* Always ensure result fits within application's authorized limits.
+* Each application can set its own limits.
+* note 5 : when `return==0`, if precise failure cause is needed, use ZSTD_getFrameParams() to know more. */
+ZSTDLIB_API unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
+
+
+/*====== Helper functions ======*/
+ZSTDLIB_API int ZSTD_maxCLevel(void); /*!< maximum compression level available */
+ZSTDLIB_API size_t ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case scenario */
+ZSTDLIB_API unsigned ZSTD_isError(size_t code); /*!< tells if a `size_t` function result is an error code */
+ZSTDLIB_API const char* ZSTD_getErrorName(size_t code); /*!< provides readable string from an error code */
+
+
+/***************************************
+* Explicit memory management
+***************************************/
+/*= Compression context
+* When compressing many times,
+* it is recommended to allocate a context just once, and re-use it for each successive compression operation.
+* This will make workload friendlier for system's memory.
+* Use one context per thread for parallel execution in multi-threaded environments. */
+typedef struct ZSTD_CCtx_s ZSTD_CCtx;
+ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void);
+ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx);
+
+/*! ZSTD_compressCCtx() :
+ Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()). */
+ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel);
+
+/*= Decompression context */
+typedef struct ZSTD_DCtx_s ZSTD_DCtx;
+ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void);
+ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);
+
+/*! ZSTD_decompressDCtx() :
+* Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()). */
+ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+
+
+/**************************
+* Simple dictionary API
+***************************/
+/*! ZSTD_compress_usingDict() :
+* Compression using a predefined Dictionary (see dictBuilder/zdict.h).
+* Note : This function loads the dictionary, resulting in significant startup delay.
+* Note : When `dict == NULL || dictSize < 8` no dictionary is used. */
+ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const void* dict,size_t dictSize,
+ int compressionLevel);
+
+/*! ZSTD_decompress_usingDict() :
+* Decompression using a predefined Dictionary (see dictBuilder/zdict.h).
+* Dictionary must be identical to the one used during compression.
+* Note : This function loads the dictionary, resulting in significant startup delay.
+* Note : When `dict == NULL || dictSize < 8` no dictionary is used. */
+ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const void* dict,size_t dictSize);
+
+
+/****************************
+* Fast dictionary API
+****************************/
+typedef struct ZSTD_CDict_s ZSTD_CDict;
+
+/*! ZSTD_createCDict() :
+* When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once.
+* ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay.
+* ZSTD_CDict can be created once and used by multiple threads concurrently, as its usage is read-only.
+* `dictBuffer` can be released after ZSTD_CDict creation, as its content is copied within CDict */
+ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize, int compressionLevel);
+
+/*! ZSTD_freeCDict() :
+* Function frees memory allocated by ZSTD_createCDict(). */
+ZSTDLIB_API size_t ZSTD_freeCDict(ZSTD_CDict* CDict);
+
+/*! ZSTD_compress_usingCDict() :
+* Compression using a digested Dictionary.
+* Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.
+* Note that compression level is decided during dictionary creation. */
+ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const ZSTD_CDict* cdict);
+
+
+typedef struct ZSTD_DDict_s ZSTD_DDict;
+
+/*! ZSTD_createDDict() :
+* Create a digested dictionary, ready to start decompression operation without startup delay.
+* dictBuffer can be released after DDict creation, as its content is copied inside DDict */
+ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict(const void* dictBuffer, size_t dictSize);
+
+/*! ZSTD_freeDDict() :
+* Function frees memory allocated with ZSTD_createDDict() */
+ZSTDLIB_API size_t ZSTD_freeDDict(ZSTD_DDict* ddict);
+
+/*! ZSTD_decompress_usingDDict() :
+* Decompression using a digested Dictionary.
+* Faster startup than ZSTD_decompress_usingDict(), recommended when same dictionary is used multiple times. */
+ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const ZSTD_DDict* ddict);
+
+
+/****************************
+* Streaming
+****************************/
+
+typedef struct ZSTD_inBuffer_s {
+ const void* src; /**< start of input buffer */
+ size_t size; /**< size of input buffer */
+ size_t pos; /**< position where reading stopped. Will be updated. Necessarily 0 <= pos <= size */
+} ZSTD_inBuffer;
+
+typedef struct ZSTD_outBuffer_s {
+ void* dst; /**< start of output buffer */
+ size_t size; /**< size of output buffer */
+ size_t pos; /**< position where writing stopped. Will be updated. Necessarily 0 <= pos <= size */
+} ZSTD_outBuffer;
+
+
+
+/*-***********************************************************************
+* Streaming compression - HowTo
+*
+* A ZSTD_CStream object is required to track streaming operation.
+* Use ZSTD_createCStream() and ZSTD_freeCStream() to create/release resources.
+* ZSTD_CStream objects can be reused multiple times on consecutive compression operations.
+* It is recommended to re-use ZSTD_CStream in situations where many streaming operations will be achieved consecutively,
+* since it will play nicer with system's memory, by re-using already allocated memory.
+* Use one separate ZSTD_CStream per thread for parallel execution.
+*
+* Start a new compression by initializing ZSTD_CStream.
+* Use ZSTD_initCStream() to start a new compression operation.
+* Use ZSTD_initCStream_usingDict() or ZSTD_initCStream_usingCDict() for a compression which requires a dictionary (experimental section)
+*
+* Use ZSTD_compressStream() repetitively to consume input stream.
+* The function will automatically update both `pos` fields.
+* Note that it may not consume the entire input, in which case `pos < size`,
+* and it's up to the caller to present again remaining data.
+* @return : a size hint, preferred nb of bytes to use as input for next function call
+* or an error code, which can be tested using ZSTD_isError().
+* Note 1 : it's just a hint, to help latency a little, any other value will work fine.
+* Note 2 : size hint is guaranteed to be <= ZSTD_CStreamInSize()
+*
+* At any moment, it's possible to flush whatever data remains within internal buffer, using ZSTD_flushStream().
+* `output->pos` will be updated.
+* Note that some content might still be left within internal buffer if `output->size` is too small.
+* @return : nb of bytes still present within internal buffer (0 if it's empty)
+* or an error code, which can be tested using ZSTD_isError().
+*
+* ZSTD_endStream() instructs to finish a frame.
+* It will perform a flush and write frame epilogue.
+* The epilogue is required for decoders to consider a frame completed.
+* Similar to ZSTD_flushStream(), it may not be able to flush the full content if `output->size` is too small.
+* In which case, call again ZSTD_endStream() to complete the flush.
+* @return : nb of bytes still present within internal buffer (0 if it's empty, hence compression completed)
+* or an error code, which can be tested using ZSTD_isError().
+*
+* *******************************************************************/
+
+typedef struct ZSTD_CStream_s ZSTD_CStream;
+ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream(void);
+ZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream* zcs);
+
+ZSTDLIB_API size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel);
+ZSTDLIB_API size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
+ZSTDLIB_API size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
+ZSTDLIB_API size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
+
+ZSTDLIB_API size_t ZSTD_CStreamInSize(void); /**< recommended size for input buffer */
+ZSTDLIB_API size_t ZSTD_CStreamOutSize(void); /**< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block in all circumstances. */
+
+
+
+/*-***************************************************************************
+* Streaming decompression - HowTo
+*
+* A ZSTD_DStream object is required to track streaming operations.
+* Use ZSTD_createDStream() and ZSTD_freeDStream() to create/release resources.
+* ZSTD_DStream objects can be re-used multiple times.
+*
+* Use ZSTD_initDStream() to start a new decompression operation,
+* or ZSTD_initDStream_usingDict() if decompression requires a dictionary.
+* @return : recommended first input size
+*
+* Use ZSTD_decompressStream() repetitively to consume your input.
+* The function will update both `pos` fields.
+* If `input.pos < input.size`, some input has not been consumed.
+* It's up to the caller to present again remaining data.
+* If `output.pos < output.size`, decoder has flushed everything it could.
+* @return : 0 when a frame is completely decoded and fully flushed,
+* an error code, which can be tested using ZSTD_isError(),
+* any other value > 0, which means there is still some decoding to do to complete current frame.
+* The return value is a suggested next input size (a hint to improve latency) that will never load more than the current frame.
+* *******************************************************************************/
+
+typedef struct ZSTD_DStream_s ZSTD_DStream;
+ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream(void);
+ZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream* zds);
+
+ZSTDLIB_API size_t ZSTD_initDStream(ZSTD_DStream* zds);
+ZSTDLIB_API size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
+
+ZSTDLIB_API size_t ZSTD_DStreamInSize(void); /*!< recommended size for input buffer */
+ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */
+
+#endif /* ZSTD_H_235446 */
+
+
+#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY)
+#define ZSTD_H_ZSTD_STATIC_LINKING_ONLY
+
+/****************************************************************************************
+ * START OF ADVANCED AND EXPERIMENTAL FUNCTIONS
+ * The definitions in this section are considered experimental.
+ * They should never be used with a dynamic library, as they may change in the future.
+ * They are provided for advanced usages.
+ * Use them only in association with static linking.
+ * ***************************************************************************************/
+
+/* --- Constants ---*/
+#define ZSTD_MAGICNUMBER 0xFD2FB528 /* >= v0.8.0 */
+#define ZSTD_MAGIC_SKIPPABLE_START 0x184D2A50U
+
+#define ZSTD_WINDOWLOG_MAX_32 25
+#define ZSTD_WINDOWLOG_MAX_64 27
+#define ZSTD_WINDOWLOG_MAX ((U32)(MEM_32bits() ? ZSTD_WINDOWLOG_MAX_32 : ZSTD_WINDOWLOG_MAX_64))
+#define ZSTD_WINDOWLOG_MIN 10
+#define ZSTD_HASHLOG_MAX ZSTD_WINDOWLOG_MAX
+#define ZSTD_HASHLOG_MIN 6
+#define ZSTD_CHAINLOG_MAX (ZSTD_WINDOWLOG_MAX+1)
+#define ZSTD_CHAINLOG_MIN ZSTD_HASHLOG_MIN
+#define ZSTD_HASHLOG3_MAX 17
+#define ZSTD_SEARCHLOG_MAX (ZSTD_WINDOWLOG_MAX-1)
+#define ZSTD_SEARCHLOG_MIN 1
+#define ZSTD_SEARCHLENGTH_MAX 7 /* only for ZSTD_fast, other strategies are limited to 6 */
+#define ZSTD_SEARCHLENGTH_MIN 3 /* only for ZSTD_btopt, other strategies are limited to 4 */
+#define ZSTD_TARGETLENGTH_MIN 4
+#define ZSTD_TARGETLENGTH_MAX 999
+
+#define ZSTD_FRAMEHEADERSIZE_MAX 18 /* for static allocation */
+#define ZSTD_FRAMEHEADERSIZE_MIN 6
+static const size_t ZSTD_frameHeaderSize_prefix = 5;
+static const size_t ZSTD_frameHeaderSize_min = ZSTD_FRAMEHEADERSIZE_MIN;
+static const size_t ZSTD_frameHeaderSize_max = ZSTD_FRAMEHEADERSIZE_MAX;
+static const size_t ZSTD_skippableHeaderSize = 8; /* magic number + skippable frame length */
+
+
+/*--- Advanced types ---*/
+typedef enum { ZSTD_fast, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt, ZSTD_btopt2 } ZSTD_strategy; /* from faster to stronger */
+
+typedef struct {
+ unsigned windowLog; /**< largest match distance : larger == more compression, more memory needed during decompression */
+ unsigned chainLog; /**< fully searched segment : larger == more compression, slower, more memory (useless for fast) */
+ unsigned hashLog; /**< dispatch table : larger == faster, more memory */
+ unsigned searchLog; /**< nb of searches : larger == more compression, slower */
+ unsigned searchLength; /**< match length searched : larger == faster decompression, sometimes less compression */
+ unsigned targetLength; /**< acceptable match size for optimal parser (only) : larger == more compression, slower */
+ ZSTD_strategy strategy;
+} ZSTD_compressionParameters;
+
+typedef struct {
+ unsigned contentSizeFlag; /**< 1: content size will be in frame header (if known). */
+ unsigned checksumFlag; /**< 1: will generate a 22-bits checksum at end of frame, to be used for error detection by decompressor */
+ unsigned noDictIDFlag; /**< 1: no dict ID will be saved into frame header (if dictionary compression) */
+} ZSTD_frameParameters;
+
+typedef struct {
+ ZSTD_compressionParameters cParams;
+ ZSTD_frameParameters fParams;
+} ZSTD_parameters;
+
+/*= Custom memory allocation functions */
+typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
+typedef void (*ZSTD_freeFunction) (void* opaque, void* address);
+typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
+
+
+/***************************************
+* Advanced compression functions
+***************************************/
+/*! ZSTD_estimateCCtxSize() :
+ * Gives the amount of memory allocated for a ZSTD_CCtx given a set of compression parameters.
+ * `frameContentSize` is an optional parameter, provide `0` if unknown */
+ZSTDLIB_API size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
+
+/*! ZSTD_createCCtx_advanced() :
+ * Create a ZSTD compression context using external alloc and free functions */
+ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
+
+/*! ZSTD_sizeofCCtx() :
+ * Gives the amount of memory used by a given ZSTD_CCtx */
+ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
+
+/*! ZSTD_createCDict_byReference() :
+ * Create a digested dictionary for compression
+ * Dictionary content is simply referenced, and therefore stays in dictBuffer.
+ * It is important that dictBuffer outlives CDict, it must remain read accessible throughout the lifetime of CDict */
+ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel);
+
+/*! ZSTD_createCDict_advanced() :
+ * Create a ZSTD_CDict using external alloc and free, and customized compression parameters */
+ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, unsigned byReference,
+ ZSTD_parameters params, ZSTD_customMem customMem);
+
+/*! ZSTD_sizeof_CDict() :
+ * Gives the amount of memory used by a given ZSTD_sizeof_CDict */
+ZSTDLIB_API size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict);
+
+/*! ZSTD_getCParams() :
+* @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
+* `estimatedSrcSize` value is optional, select 0 if not known */
+ZSTDLIB_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
+
+/*! ZSTD_getParams() :
+* same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of sub-component `ZSTD_compressionParameters`.
+* All fields of `ZSTD_frameParameters` are set to default (0) */
+ZSTDLIB_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
+
+/*! ZSTD_checkCParams() :
+* Ensure param values remain within authorized range */
+ZSTDLIB_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params);
+
+/*! ZSTD_adjustCParams() :
+* optimize params for a given `srcSize` and `dictSize`.
+* both values are optional, select `0` if unknown. */
+ZSTDLIB_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize);
+
+/*! ZSTD_compress_advanced() :
+* Same as ZSTD_compress_usingDict(), with fine-tune control of each compression parameter */
+ZSTDLIB_API size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const void* dict,size_t dictSize,
+ ZSTD_parameters params);
+
+
+/*--- Advanced decompression functions ---*/
+
+/*! ZSTD_isFrame() :
+ * Tells if the content of `buffer` starts with a valid Frame Identifier.
+ * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.
+ * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled.
+ * Note 3 : Skippable Frame Identifiers are considered valid. */
+ZSTDLIB_API unsigned ZSTD_isFrame(const void* buffer, size_t size);
+
+/*! ZSTD_estimateDCtxSize() :
+ * Gives the potential amount of memory allocated to create a ZSTD_DCtx */
+ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
+
+/*! ZSTD_createDCtx_advanced() :
+ * Create a ZSTD decompression context using external alloc and free functions */
+ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem);
+
+/*! ZSTD_sizeof_DCtx() :
+ * Gives the amount of memory used by a given ZSTD_DCtx */
+ZSTDLIB_API size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx);
+
+/*! ZSTD_createDDict_byReference() :
+ * Create a digested dictionary, ready to start decompression operation without startup delay.
+ * Dictionary content is simply referenced, and therefore stays in dictBuffer.
+ * It is important that dictBuffer outlives DDict, it must remain read accessible throughout the lifetime of DDict */
+ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize);
+
+ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
+ unsigned byReference, ZSTD_customMem customMem);
+
+/*! ZSTD_sizeof_DDict() :
+ * Gives the amount of memory used by a given ZSTD_DDict */
+ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
+
+/*! ZSTD_getDictID_fromDict() :
+ * Provides the dictID stored within dictionary.
+ * if @return == 0, the dictionary is not conformant with Zstandard specification.
+ * It can still be loaded, but as a content-only dictionary. */
+ZSTDLIB_API unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize);
+
+/*! ZSTD_getDictID_fromDDict() :
+ * Provides the dictID of the dictionary loaded into `ddict`.
+ * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
+ * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
+ZSTDLIB_API unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict);
+
+/*! ZSTD_getDictID_fromFrame() :
+ * Provides the dictID required to decompressed the frame stored within `src`.
+ * If @return == 0, the dictID could not be decoded.
+ * This could for one of the following reasons :
+ * - The frame does not require a dictionary to be decoded (most common case).
+ * - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information.
+ * Note : this use case also happens when using a non-conformant dictionary.
+ * - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`).
+ * - This is not a Zstandard frame.
+ * When identifying the exact failure cause, it's possible to used ZSTD_getFrameParams(), which will provide a more precise error code. */
+ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
+
+
+/********************************************************************
+* Advanced streaming functions
+********************************************************************/
+
+/*===== Advanced Streaming compression functions =====*/
+ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
+ZSTDLIB_API size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize); /**< pledgedSrcSize must be correct */
+ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel);
+ZSTDLIB_API size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
+ ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize is optional and can be zero == unknown */
+ZSTDLIB_API size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict); /**< note : cdict will just be referenced, and must outlive compression session */
+ZSTDLIB_API size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize); /**< re-use compression parameters from previous init; skip dictionary loading stage; zcs must be init at least once before */
+ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);
+
+
+/*===== Advanced Streaming decompression functions =====*/
+typedef enum { ZSTDdsp_maxWindowSize } ZSTD_DStreamParameter_e;
+ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
+ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize);
+ZSTDLIB_API size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, ZSTD_DStreamParameter_e paramType, unsigned paramValue);
+ZSTDLIB_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict); /**< note : ddict will just be referenced, and must outlive decompression session */
+ZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds); /**< re-use decompression parameters from previous init; saves dictionary loading */
+ZSTDLIB_API size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
+
+
+/*********************************************************************
+* Buffer-less and synchronous inner streaming functions
+*
+* This is an advanced API, giving full control over buffer management, for users which need direct control over memory.
+* But it's also a complex one, with many restrictions (documented below).
+* Prefer using normal streaming API for an easier experience
+********************************************************************* */
+
+/**
+ Buffer-less streaming compression (synchronous mode)
+
+ A ZSTD_CCtx object is required to track streaming operations.
+ Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource.
+ ZSTD_CCtx object can be re-used multiple times within successive compression operations.
+
+ Start by initializing a context.
+ Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression,
+ or ZSTD_compressBegin_advanced(), for finer parameter control.
+ It's also possible to duplicate a reference context which has already been initialized, using ZSTD_copyCCtx()
+
+ Then, consume your input using ZSTD_compressContinue().
+ There are some important considerations to keep in mind when using this advanced function :
+ - ZSTD_compressContinue() has no internal buffer. It uses externally provided buffer only.
+ - Interface is synchronous : input is consumed entirely and produce 1+ (or more) compressed blocks.
+ - Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario.
+ Worst case evaluation is provided by ZSTD_compressBound().
+ ZSTD_compressContinue() doesn't guarantee recover after a failed compression.
+ - ZSTD_compressContinue() presumes prior input ***is still accessible and unmodified*** (up to maximum distance size, see WindowLog).
+ It remembers all previous contiguous blocks, plus one separated memory segment (which can itself consists of multiple contiguous blocks)
+ - ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps.
+ In which case, it will "discard" the relevant memory section from its history.
+
+ Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum.
+ It's possible to use a NULL,0 src content, in which case, it will write a final empty block to end the frame,
+ Without last block mark, frames will be considered unfinished (broken) by decoders.
+
+ You can then reuse `ZSTD_CCtx` (ZSTD_compressBegin()) to compress some new frame.
+*/
+
+/*===== Buffer-less streaming compression functions =====*/
+ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
+ZSTDLIB_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
+ZSTDLIB_API size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize);
+ZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize);
+ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+
+
+
+/*-
+ Buffer-less streaming decompression (synchronous mode)
+
+ A ZSTD_DCtx object is required to track streaming operations.
+ Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
+ A ZSTD_DCtx object can be re-used multiple times.
+
+ First typical operation is to retrieve frame parameters, using ZSTD_getFrameParams().
+ It fills a ZSTD_frameParams structure which provide important information to correctly decode the frame,
+ such as the minimum rolling buffer size to allocate to decompress data (`windowSize`),
+ and the dictionary ID used.
+ (Note : content size is optional, it may not be present. 0 means : content size unknown).
+ Note that these values could be wrong, either because of data malformation, or because an attacker is spoofing deliberate false information.
+ As a consequence, check that values remain within valid application range, especially `windowSize`, before allocation.
+ Each application can set its own limit, depending on local restrictions. For extended interoperability, it is recommended to support at least 8 MB.
+ Frame parameters are extracted from the beginning of the compressed frame.
+ Data fragment must be large enough to ensure successful decoding, typically `ZSTD_frameHeaderSize_max` bytes.
+ @result : 0 : successful decoding, the `ZSTD_frameParams` structure is correctly filled.
+ >0 : `srcSize` is too small, please provide at least @result bytes on next attempt.
+ errorCode, which can be tested using ZSTD_isError().
+
+ Start decompression, with ZSTD_decompressBegin() or ZSTD_decompressBegin_usingDict().
+ Alternatively, you can copy a prepared context, using ZSTD_copyDCtx().
+
+ Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively.
+ ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue().
+ ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail.
+
+ @result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity).
+ It can be zero, which is not an error; it just means ZSTD_decompressContinue() has decoded some metadata item.
+ It can also be an error code, which can be tested with ZSTD_isError().
+
+ ZSTD_decompressContinue() needs previous data blocks during decompression, up to `windowSize`.
+ They should preferably be located contiguously, prior to current block.
+ Alternatively, a round buffer of sufficient size is also possible. Sufficient size is determined by frame parameters.
+ ZSTD_decompressContinue() is very sensitive to contiguity,
+ if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place,
+ or that previous contiguous segment is large enough to properly handle maximum back-reference.
+
+ A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero.
+ Context can then be reset to start a new decompression.
+
+ Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType().
+ This information is not required to properly decode a frame.
+
+ == Special case : skippable frames ==
+
+ Skippable frames allow integration of user-defined data into a flow of concatenated frames.
+ Skippable frames will be ignored (skipped) by a decompressor. The format of skippable frames is as follows :
+ a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F
+ b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits
+ c) Frame Content - any content (User Data) of length equal to Frame Size
+ For skippable frames ZSTD_decompressContinue() always returns 0.
+ For skippable frames ZSTD_getFrameParams() returns fparamsPtr->windowLog==0 what means that a frame is skippable.
+ It also returns Frame Size as fparamsPtr->frameContentSize.
+*/
+
+typedef struct {
+ unsigned long long frameContentSize;
+ unsigned windowSize;
+ unsigned dictID;
+ unsigned checksumFlag;
+} ZSTD_frameParams;
+
+/*===== Buffer-less streaming decompression functions =====*/
+ZSTDLIB_API size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input, see details below */
+ZSTDLIB_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
+ZSTDLIB_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
+ZSTDLIB_API void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
+ZSTDLIB_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
+ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
+ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
+
+/**
+ Block functions
+
+ Block functions produce and decode raw zstd blocks, without frame metadata.
+ Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes).
+ User will have to take in charge required information to regenerate data, such as compressed and content sizes.
+
+ A few rules to respect :
+ - Compressing and decompressing require a context structure
+ + Use ZSTD_createCCtx() and ZSTD_createDCtx()
+ - It is necessary to init context before starting
+ + compression : ZSTD_compressBegin()
+ + decompression : ZSTD_decompressBegin()
+ + variants _usingDict() are also allowed
+ + copyCCtx() and copyDCtx() work too
+ - Block size is limited, it must be <= ZSTD_getBlockSizeMax()
+ + If you need to compress more, cut data into multiple blocks
+ + Consider using the regular ZSTD_compress() instead, as frame metadata costs become negligible when source size is large.
+ - When a block is considered not compressible enough, ZSTD_compressBlock() result will be zero.
+ In which case, nothing is produced into `dst`.
+ + User must test for such outcome and deal directly with uncompressed data
+ + ZSTD_decompressBlock() doesn't accept uncompressed data as input !!!
+ + In case of multiple successive blocks, decoder must be informed of uncompressed block existence to follow proper history.
+ Use ZSTD_insertBlock() in such a case.
+*/
+
+#define ZSTD_BLOCKSIZE_ABSOLUTEMAX (128 * 1024) /* define, for static allocation */
+/*===== Raw zstd block functions =====*/
+ZSTDLIB_API size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx);
+ZSTDLIB_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+ZSTDLIB_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+ZSTDLIB_API size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert block into `dctx` history. Useful for uncompressed blocks */
+
+
+#endif /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */
+
+#if defined (__cplusplus)
+}
+#endif
diff --git a/lib/libzstd.lib b/lib/libzstd.lib
new file mode 100644
index 0000000..630ef99
Binary files /dev/null and b/lib/libzstd.lib differ
diff --git a/lib/libzstdd.lib b/lib/libzstdd.lib
new file mode 100644
index 0000000..dae1ca8
Binary files /dev/null and b/lib/libzstdd.lib differ
diff --git a/src/LiveScanClient/liveScanClient.cpp b/src/LiveScanClient/liveScanClient.cpp
index 96e2b8a..825aa93 100644
--- a/src/LiveScanClient/liveScanClient.cpp
+++ b/src/LiveScanClient/liveScanClient.cpp
@@ -19,6 +19,7 @@
#include
#include
#include
+#include "zstd.h"
std::mutex m_mSocketThreadMutex;
@@ -57,6 +58,8 @@ LiveScanClient::LiveScanClient() :
m_bConfirmCalibrated(false),
m_bShowDepth(false),
m_bSocketThread(true),
+ m_bFrameCompression(true),
+ m_iCompressionLevel(2),
m_pClientSocket(NULL),
m_nFilterNeighbors(10),
m_fFilterThreshold(0.01f)
@@ -130,7 +133,7 @@ int LiveScanClient::Run(HINSTANCE hInstance, int nCmdShow)
MSG msg = {0};
WNDCLASS wc;
- // Dialog custom window class
+ // Dialog custom window class
ZeroMemory(&wc, sizeof(wc));
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbWndExtra = DLGWINDOWEXTRA;
@@ -499,10 +502,13 @@ void LiveScanClient::HandleSocket()
}
m_bStreamOnlyBodies = (received[i] != 0);
- i++;
+ i += 1;
- //so that we do not lose the next character in the stream
- i--;
+ m_iCompressionLevel = *(int*)(received.c_str() + i);
+ if (m_iCompressionLevel > 0)
+ m_bFrameCompression = true;
+ else
+ m_bFrameCompression = false;
}
//send stored frame
else if (received[i] == MSG_REQUEST_STORED_FRAME)
@@ -634,7 +640,7 @@ void LiveScanClient::SendFrame(vector vertices, vector RGB, vector
ptr2 += sizeof(short) * 3;
pos += sizeof(short) * 3;
}
-
+
int nBodies = body.size();
size += sizeof(nBodies);
for (int i = 0; i < nBodies; i++)
@@ -682,9 +688,25 @@ void LiveScanClient::SendFrame(vector vertices, vector RGB, vector
}
}
- m_pClientSocket->SendBytes((char*)&size, sizeof(int));
- m_pClientSocket->SendBytes(buffer.data(), size);
+ int iCompression = static_cast(m_bFrameCompression);
+ if (m_bFrameCompression)
+ {
+ char buf[8];
+ // *2, because according to zstd documentation, increasing the size of the output buffer above a
+ // bound should speed up the compression.
+ int cBuffSize = ZSTD_compressBound(size) * 2;
+ vector compressedBuffer(cBuffSize);
+ int cSize = ZSTD_compress(compressedBuffer.data(), cBuffSize, buffer.data(), size, m_iCompressionLevel);
+ size = cSize;
+ buffer = compressedBuffer;
+ }
+ char header[8];
+ memcpy(header, (char*)&size, sizeof(size));
+ memcpy(header + 4, (char*)&iCompression, sizeof(iCompression));
+
+ m_pClientSocket->SendBytes((char*)&header, sizeof(int) * 2);
+ m_pClientSocket->SendBytes(buffer.data(), size);
}
void LiveScanClient::StoreFrame(Point3f *vertices, Point2f *mapping, RGB *color, vector &bodies, BYTE* bodyIndex)