From 1d0a3a5c47a2ba4cdabb9f8a4fab694d4987083f Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Wed, 6 Mar 2019 14:23:47 +0200 Subject: Implemented pulse TWN file. --- .../Tango.Pulse/Properties/AssemblyInfo.cs | 7 ++ .../Visual_Studio/Tango.Pulse/SpoolingMethods.cs | 15 +++ .../Visual_Studio/Tango.Pulse/Tango.Pulse.csproj | 60 ++++++++++ .../Visual_Studio/Tango.Pulse/Twine TWN Spec.pdf | Bin 0 -> 54304 bytes Software/Visual_Studio/Tango.Pulse/TwnFile.cs | 118 +++++++++++++++++++ .../Visual_Studio/Tango.Pulse/TwnFileReader.cs | 109 ++++++++++++++++++ .../Visual_Studio/Tango.Pulse/TwnFileWriter.cs | 128 +++++++++++++++++++++ Software/Visual_Studio/Tango.Pulse/TwnSegment.cs | 35 ++++++ Software/Visual_Studio/Tango.Pulse/TwnStop.cs | 67 +++++++++++ 9 files changed, 539 insertions(+) create mode 100644 Software/Visual_Studio/Tango.Pulse/Properties/AssemblyInfo.cs create mode 100644 Software/Visual_Studio/Tango.Pulse/SpoolingMethods.cs create mode 100644 Software/Visual_Studio/Tango.Pulse/Tango.Pulse.csproj create mode 100644 Software/Visual_Studio/Tango.Pulse/Twine TWN Spec.pdf create mode 100644 Software/Visual_Studio/Tango.Pulse/TwnFile.cs create mode 100644 Software/Visual_Studio/Tango.Pulse/TwnFileReader.cs create mode 100644 Software/Visual_Studio/Tango.Pulse/TwnFileWriter.cs create mode 100644 Software/Visual_Studio/Tango.Pulse/TwnSegment.cs create mode 100644 Software/Visual_Studio/Tango.Pulse/TwnStop.cs (limited to 'Software/Visual_Studio/Tango.Pulse') diff --git a/Software/Visual_Studio/Tango.Pulse/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.Pulse/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f05da7191 --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/Properties/AssemblyInfo.cs @@ -0,0 +1,7 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Tango - Pulse TWN format library")] +[assembly: AssemblyVersion("2.0.29.1608")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.Pulse/SpoolingMethods.cs b/Software/Visual_Studio/Tango.Pulse/SpoolingMethods.cs new file mode 100644 index 000000000..3677e0ce7 --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/SpoolingMethods.cs @@ -0,0 +1,15 @@ +namespace Tango.Pulse +{ + /// + /// Represents a twn file spooling method. + /// + public enum SpoolingMethods + { + //Spool per segment. (default) + SpoolPerSegment = 0, + //Spool per copy. + SpoolPerCopy = 1, + //Single spool for all segments. + SingleSpool = 2, + } +} diff --git a/Software/Visual_Studio/Tango.Pulse/Tango.Pulse.csproj b/Software/Visual_Studio/Tango.Pulse/Tango.Pulse.csproj new file mode 100644 index 000000000..fe041bd58 --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/Tango.Pulse.csproj @@ -0,0 +1,60 @@ + + + + + Debug + AnyCPU + {8435223D-DB6B-45E3-A08B-45B7416F8481} + Library + Properties + Tango.Pulse + Tango.Pulse + v4.6.1 + 512 + true + + + true + full + false + ..\Build\Core\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + ..\Build\Core\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + GlobalVersionInfo.cs + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.Pulse/Twine TWN Spec.pdf b/Software/Visual_Studio/Tango.Pulse/Twine TWN Spec.pdf new file mode 100644 index 000000000..bc38981a4 Binary files /dev/null and b/Software/Visual_Studio/Tango.Pulse/Twine TWN Spec.pdf differ diff --git a/Software/Visual_Studio/Tango.Pulse/TwnFile.cs b/Software/Visual_Studio/Tango.Pulse/TwnFile.cs new file mode 100644 index 000000000..75653c03e --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/TwnFile.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Pulse +{ + /// + /// Represents a Pulse, twn embroidery file. + /// + public class TwnFile + { + /// + /// Format Version (Default is 1.0). + /// + public float Version { get; set; } + + /// + /// The name of the design or other labeling information as UTF-8 text. + /// + public String Name { get; set; } + + /// + /// Number of copies. (The number 0 will be treated as 1, so the default is 0) + /// + public int NumberOfCopies { get; set; } + + /// + /// 0 - Spool per segment. (default) + /// 1 - Spool per copy. + /// 2 - Single spool for all segments. + /// + public SpoolingMethods SpoolingMethod { get; set; } + + /// + /// A unique code representing an optional media ID from Twine’s recommended media list + /// + public int MediaID { get; set; } + + /// + /// 3 ASCII characters representing the embedded embroidery file extension (e.g dst, pes). + /// + public String EmbroideryFileFormat { get; set; } + + /// + /// preview image in + /// PNG format(transparent background). The size of the PNG byte array must be defined in the header. + /// Recommended image width is 1280 pixels while maintaining aspect ratio. + /// + public Bitmap Thumbnail { get; set; } + + /// + /// Array of Brush Segment. The number of brush segments must be defined in the header. + /// + public List Segments { get; set; } + + /// + /// Byte array representing the standard embroidery file which can be extracted and inserted into an embroidery machine. + /// + public byte[] EmbroideryFile { get; set; } + + /// + /// Initializes a new instance of the class. + /// + public TwnFile() + { + Version = 1.0f; + Segments = new List(); + } + + /// + /// Writes the to the specified output stream. + /// + /// The output stream. + public void ToStream(Stream output) + { + new TwnFileWriter().Write(this, output); + } + + /// + /// Writes the to the specified file path. + /// + /// The file path. + public void ToFile(String filePath) + { + using (FileStream fs = new FileStream(filePath, FileMode.Create)) + { + ToStream(fs); + } + } + + /// + /// Loads a from the specified stream. + /// + /// The TWN stream. + /// + public static TwnFile FromStream(Stream twnStream) + { + return new TwnFileReader().Read(twnStream); + } + + /// + /// Loads a from the specified file path. + /// + /// The TWN file path. + /// + public static TwnFile FromFile(String twnFilePath) + { + using (FileStream fs = new FileStream(twnFilePath, FileMode.Open)) + { + return FromStream(fs); + } + } + } +} diff --git a/Software/Visual_Studio/Tango.Pulse/TwnFileReader.cs b/Software/Visual_Studio/Tango.Pulse/TwnFileReader.cs new file mode 100644 index 000000000..2efa94936 --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/TwnFileReader.cs @@ -0,0 +1,109 @@ +using System; +using System.Drawing; +using System.IO; +using System.Text; + +namespace Tango.Pulse +{ + /// + /// Represents a Pulse, twn file reader. + /// + public class TwnFileReader + { + /// + /// Reads the specified TWN stream. + /// + /// The TWN stream. + /// + public TwnFile Read(Stream twnStream) + { + TwnFile twnFile = new TwnFile(); + + BinaryReader reader = new BinaryReader(twnStream); + + //Format Version (Default is 1.0). + twnFile.Version = reader.ReadSingle(); + + + //The name of the design or other labeling information as UTF - 8 text padded with white spaces and limited to 50 bytes. + twnFile.Name = Encoding.UTF8.GetString(reader.ReadBytes(50)).Trim(); + + + //The embedded preview image size in byte length as a 32 bit unsigned integer. + UInt32 thumbnail_size = reader.ReadUInt32(); + + + //The total number of brush segments as a 32 bit unsigned integer. + UInt32 segments_count = reader.ReadUInt32(); + + + //Number of copies. (The number 0 will be treated as 1, so the default is 0) + twnFile.NumberOfCopies = (int)reader.ReadUInt32(); + + + //0 - Spool per segment. (default) + //1 - Spool per copy. + //2 - Single spool for all segments. + twnFile.SpoolingMethod = (SpoolingMethods)(int)reader.ReadByte(); + + + //A unique code representing an optional media ID from Twine’s recommended media list. + twnFile.MediaID = (int)reader.ReadUInt32(); + + + //3 ASCII characters representing the embedded embroidery file extension (e.g dst, pes). + twnFile.EmbroideryFileFormat = Encoding.ASCII.GetString(reader.ReadBytes(3)); + + + //The byte array length of the embedded embroidery file. + UInt32 emb_file_size = reader.ReadUInt32(); + + + //Array of bytes representing the design preview image in PNG format(transparent background). + //The size of the PNG byte array must be defined in the header. Recommended image width is 1280 + //pixels while maintaining aspect ratio. + MemoryStream ms = new MemoryStream(reader.ReadBytes((int)thumbnail_size)); + twnFile.Thumbnail = new Bitmap(ms); + + + //Array of Brush Segment. The number of brush segments must be defined in the header. + for (int i = 0; i < segments_count; i++) + { + TwnSegment segment = new TwnSegment(); + + //Required thread length in centimeters. + segment.Length = reader.ReadSingle(); + + //Number of brush stops. + UInt32 stop_count = reader.ReadUInt32(); + + //Array of brush stops. + for (int j = 0; j < stop_count; j++) + { + TwnStop stop = new TwnStop(); + + //The RGB red component. + stop.R = reader.ReadByte(); + + //The RGB green component. + stop.G = reader.ReadByte(); + + //The RGB blue component. + stop.B = reader.ReadByte(); + + //The Brush stop offset position within the parent brush length in percentage (0-1). + stop.Offset = reader.ReadSingle(); + + segment.BrushStops.Add(stop); + } + + twnFile.Segments.Add(segment); + } + + //Byte array representing the standard embroidery file which can be extracted and inserted into an embroidery machine. + twnFile.EmbroideryFile = reader.ReadBytes((int)emb_file_size); + + return twnFile; + } + } +} diff --git a/Software/Visual_Studio/Tango.Pulse/TwnFileWriter.cs b/Software/Visual_Studio/Tango.Pulse/TwnFileWriter.cs new file mode 100644 index 000000000..1b173851a --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/TwnFileWriter.cs @@ -0,0 +1,128 @@ +using System; +using System.Drawing.Imaging; +using System.IO; +using System.Text; + +namespace Tango.Pulse +{ + /// + /// Represents a Pulse, twn file writer. + /// + public class TwnFileWriter + { + /// + /// Writes the specified TWN file. + /// + /// The TWN file. + /// The output. + /// Invalid design name length. + /// + /// Thumbnail image is null. + /// or + /// Could not serialize a null embroidery file. + /// + /// The embroidery format must contain exactly 3 characters. + public void Write(TwnFile twnFile, Stream output) + { + BinaryWriter writer = new BinaryWriter(output); + + //Format Version (Default is 1.0). + writer.Write(twnFile.Version); + + + //The name of the design or other labeling information as UTF - 8 text padded with white spaces and limited to 50 bytes. + byte[] nameBytes = Encoding.UTF8.GetBytes(twnFile.Name.PadRight(50, ' ')); + + if (nameBytes.Length < 50) + { + throw new ArgumentOutOfRangeException("Invalid design name length."); + } + writer.Write(nameBytes, 0, 50); + + + //The embedded preview image size in byte length as a 32 bit unsigned integer. + if (twnFile.Thumbnail == null) + { + throw new NullReferenceException("Thumbnail image is null."); + } + + byte[] thumbnailBytes = null; //For later use. + using (MemoryStream ms = new MemoryStream()) + { + twnFile.Thumbnail.Save(ms, ImageFormat.Png); + writer.Write((UInt32)ms.Length); + thumbnailBytes = ms.ToArray(); + } + + //The total number of brush segments as a 32 bit unsigned integer. + writer.Write((UInt32)twnFile.Segments.Count); + + + //Number of copies. (The number 0 will be treated as 1, so the default is 0) + writer.Write((UInt32)twnFile.NumberOfCopies); + + + //0 - Spool per segment. (default) + //1 - Spool per copy. + //2 - Single spool for all segments. + writer.Write((byte)twnFile.SpoolingMethod); + + + //A unique code representing an optional media ID from Twine’s recommended media list. + writer.Write((UInt32)twnFile.MediaID); + + + //3 ASCII characters representing the embedded embroidery file extension (e.g dst, pes). + if (twnFile.EmbroideryFileFormat.Length != 3) + { + throw new ArgumentException("The embroidery format must contain exactly 3 characters."); + } + writer.Write(Encoding.ASCII.GetBytes(twnFile.EmbroideryFileFormat)); + + + //The byte array length of the embedded embroidery file. + if (twnFile.EmbroideryFile == null) + { + throw new NullReferenceException("Could not serialize a null embroidery file."); + } + writer.Write((UInt32)twnFile.EmbroideryFile.Length); + + + //Array of bytes representing the design preview image in PNG format(transparent background). + //The size of the PNG byte array must be defined in the header. Recommended image width is 1280 + //pixels while maintaining aspect ratio. + writer.Write(thumbnailBytes); + + + //Array of Brush Segment. The number of brush segments must be defined in the header. + foreach (var segment in twnFile.Segments) + { + //Required thread length in centimeters. + writer.Write(segment.Length); + + //Number of brush stops. + writer.Write((UInt32)segment.BrushStops.Count); + + //Array of brush stops. + foreach (var stop in segment.BrushStops) + { + //The RGB red component. + writer.Write(stop.R); + + //The RGB green component. + writer.Write(stop.G); + + //The RGB blue component. + writer.Write(stop.B); + + //The Brush stop offset position within the parent brush length in percentage (0-1). + writer.Write(stop.Offset); + } + } + + + //Byte array representing the standard embroidery file which can be extracted and inserted into an embroidery machine. + writer.Write(twnFile.EmbroideryFile); + } + } +} diff --git a/Software/Visual_Studio/Tango.Pulse/TwnSegment.cs b/Software/Visual_Studio/Tango.Pulse/TwnSegment.cs new file mode 100644 index 000000000..07d4368d5 --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/TwnSegment.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; + +namespace Tango.Pulse +{ + /// + /// Represents a twn file brush segment. + /// + /// + /// The “Brush Segment” structure supports + /// both solid and gradient segments. + /// Solid segments are defined using a “Brush + /// Segment” with a single “Brush Stop” with + /// zero offset. + /// + public class TwnSegment + { + /// + /// Required thread length in centimeters. + /// + public float Length { get; set; } + + /// + /// Array of brush stops. + /// + public List BrushStops { get; set; } + + /// + /// Initializes a new instance of the class. + /// + public TwnSegment() + { + BrushStops = new List(); + } + } +} diff --git a/Software/Visual_Studio/Tango.Pulse/TwnStop.cs b/Software/Visual_Studio/Tango.Pulse/TwnStop.cs new file mode 100644 index 000000000..af50531cc --- /dev/null +++ b/Software/Visual_Studio/Tango.Pulse/TwnStop.cs @@ -0,0 +1,67 @@ +using System.Drawing; + +namespace Tango.Pulse +{ + /// + /// Represents a twn file brush stop. + /// + public class TwnStop + { + /// + /// The RGB red component. + /// + public byte R { get; set; } + + /// + /// The RGB green component. + /// + public byte G { get; set; } + + /// + /// The RGB blue component. + /// + public byte B { get; set; } + + /// + /// The Brush stop offset position within the parent brush length in percentage (0-1). + /// + public float Offset { get; set; } + + /// + /// Gets or sets the stop color. + /// + public Color Color + { + get { return Color.FromArgb(R, G, B); } + set + { + R = value.R; + G = value.G; + B = value.B; + } + } + + /// + /// Initializes a new instance of the class. + /// + public TwnStop() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// Red. + /// Green. + /// Blue. + /// Offset. + public TwnStop(byte r, byte g, byte b, float offset) : this() + { + R = r; + G = g; + B = b; + Offset = offset; + } + } +} -- cgit v1.3.1