-
Notifications
You must be signed in to change notification settings - Fork 10
Writing PES
We can read PES and PEC for all versions by reading the color data and stitch data from the PEC block. But, the typical use case is going to be writing a successful PES file. [all writes should be done Little Endian].
We must write the following things to disk.
- 8 bytes: "#PES0001"
- 4 bytes: Location of PEC block.
- 2 bytes: 1 (scale to fit)
- 2 bytes: 1 (hoop size, 130mm 180mm)
- 2 bytes: 1 (we are going to write only one stitchblock object).
- 4 bytes: FF FF 00 00, end the header.
-
2 bytes: 7 (length of text "EmbOne")
-
7 bytes: "EmbOne"
-
2 bytes: 0, minX (we're passing on this)
-
2 bytes: 0, minY (we're passing on this)
-
2 bytes: 0, maxX (we're passing on this)
-
2 bytes: 0, maxY (we're passing on this).
-
2 bytes: 0, minX (we're passing on this)
-
2 bytes: 0, minY (we're passing on this)
-
2 bytes: 0, maxX (we're passing on this)
-
2 bytes: 0, maxY (we're passing on this).
-
4 bytes: float 1, 00 00 80 3F (Scale X)
-
4 bytes: float 0, 00 00 00 00 (Skew_X)
-
4 bytes: float 0, 00 00 00 00 (Skew_Y)
-
4 bytes: float 1, 00 00 80 3F (Scale_Y)
-
4 bytes: float (350 + HoopWidth/2 - WidthOfDesign/2), 350 is the distance from 0,0 that the 130mm x 180mm hoop is stored, if we add half the HoopWidth (1300 / 2) and subtract half our design's width. The embroidery will be centered in the hoop.
-
4 bytes float (100 + HoopHeight/2 - HeightOfDesign/2), 100 is the distance from 0,0 that our 130mm x 180mm hoop is stored, if we add half the HoopHeight (1800 / 2) and subtract half our design's height. The embroidery will be centered in the hoop.
-
2 bytes: 1, unknown.
-
2 bytes: 0, X-location (we're passing on this).
-
2 bytes 0, Y-location (we're passing on this).
-
2 bytes width, WidthOfDesign
-
2 bytes height, WidthOfDesign.
-
4 bytes, 0, unknown.
-
4 bytes, 0 unknown.
-
2 bytes, number of segments + (2 * colorChanges), this is going to be the number of segments we will need to use.
-
4 bytes FF FF 00 00, end block.
- 2 bytes: 7, length of "CSewSeg"
- 7 bytes: "CSewSeg"
For these, we must ensure our segments are flagged 0,1,0,1,0,1,0. That our jumps are 0, that our stitches are 1, that our color changes are 0, we pad with jumps and stitches to nowhere to maintain this. We assume that we jump to the location, then color change, then stitch as relevant.
- 2 bytes: 1 this is a stitch.
- 2 bytes color, color index.
- 2 bytes 2, needs a length of at least two to not be a color change.
- 2 byes: X, current position X.
- 2 bytes: Y, current position Y.
- 2 byes: X, current position X.
- 2 bytes: Y, current position Y.
- 2 bytes 0x8001, 01 80. End Segment
- 2 bytes: 0, non-stitching.
- 2 bytes, color, color index.
- 2 bytes, 2, needs a length of at least two to not be a color change.
- 2 byes: X, current position X.
- 2 bytes: Y, current position Y.
- 2 byes: X, current position X.
- 2 bytes: Y, current position Y.
- 2 bytes 0x8001, 01 80. End Segment (We didn't call a color change event, but we ensured that the initial color is established)
- 2 bytes: 0, we are not sewing this
- 2 bytes: Color, color index. Index of old color.
- 2 byte: 1, length of stitches.
- 2 byes: X, current position X.
- 2 bytes: Y, current position Y.
- 2 bytes 0x8001, 01 80. End Segment
- 2 bytes: 1, we are sewing this.
- 2 bytes: Color, color index. Index of new color.
- 2 bytes: 2, length two.
- 2 byes: X, current position X.
- 2 bytes: Y, current position Y.
- 2 byes: X, current position X.
- 2 bytes: Y, current position Y.
- 2 bytes 0x8001, 01 80. End Segment (We invoked a color change, and then a sewable event that went nowhere, to make sure the color is established.)
- 2 bytes, 0, we are not stitching.
- 2 bytes, Color, whatever color we're on.
- 2 bytes, length, the number of stitches in this jump, including start and end (minimum 2).
- NN bytes, X position, Y position (relative to the position given to the StitchGroup description).
- 2 bytes 0x8001, 01 80. End Segment
- 2 bytes, 1, we are stitching.
- 2 bytes, Color, whatever color we're on.
- 2 bytes, length, the number of stitches in this block, including start and end (minimum 2).
- NN bytes, X position, Y position (relative to the position given to the StitchGroup description).
- 2 bytes 0x8001, 01 80. End Segment
We now write the color change log.
- 2 bytes: Number of color changes
For each color change:
- 2 bytes: Section at which this change occurred. (Note this must account for the initialization and the padding sections we added.
- 2 bytes: Color Change, old index value.
Continue to Write PEC
When writing PES v.6 we must note that the PES colors are not the index colors from the PEC-Threads but rather the colors we defined in the header.
- Write, 8 bytes, "#PES0060"
- Write, 2 bytes, 1, // 0 = 100x100 else 130x180 or above
- Write, 1 byte, 0x30, dunno
- Write, 1 byte, 0x32, dunno.
- Write, 1 byte, name length (if this is 0, name is omitted)
- Write, name length bytes, name.
- Write, 1 byte, category length (if this is 0, category is omitted)
- Write, category length bytes, category.
- Write, 1 byte, author length (if this is 0, author is omitted)
- Write, author length bytes, author.
- Write, 1 byte, keywords length (if this is 0, keywords is omitted)
- Write, keywords length bytes, keywords.
- Write, 1 byte, comments length (if this is 0, comment is omitted)
- Write, comment length bytes, comment.
- Write, 2 bytes, 0, optimizeHoopChange false
- Write, 2 bytes, 0, DesignPageIsCustom false.
- Write, 2 bytes, 0x64, HoopWidth
- Write, 2 bytes, 0x64, HoopHeight
- Write, 2 bytes, 0, Design Page Area
- Write, 2 bytes, 0xC8, designWidth
- Write, 2 bytes, 0xC8, designHeight
- Write, 2 bytes, 0x64, designPageSectionWidth
- Write, 2 bytes, 0x64, designPageSectionHeight
- Write, 2 bytes, 0x64, p6, unknown but 100.
- Write, 2 bytes, 0x07, designPageBackgroundColor
- Write, 2 bytes, 0x13, designPageForegroundColor
- Write, 2 bytes, 0x01, ShowGrid true.
- Write, 2 bytes, 0x01, WithAxes true
- Write, 2 bytes, 0x00, SnapToGrid false
- Write, 2 bytes 100, GridInterval 100
- Write, 2 bytes, 0x01, p9, unknown
- Write, 2 bytes, 0, OptimizeEntryExitPoints false
- Write, 1 byte, 0, fromImageStringLength, if non-zero file name must follow.
- Write, 4 bytes, float(1f), image scaleX
- Write, 4 bytes, float(0f), image
- Write, 4 bytes, float(0f), image
- Write, 4 bytes, float(1f), image scaleY
- Write, 4 bytes, float(0f), image
- Write, 4 bytes, float(0f), image
- Write, 2 bytes, 0, numberOfProgrammableFillPatterns
- Write, 2 bytes, 0, NumberOfMotifPatterns
- Write, 2 bytes, 0, NumberOfFeatherPatterns
- Write, 2 bytes, #colors, numberOfThreads.
For each thread:
- Write, 1 byte, catalogNumber string length
- Write, 0-6 byte, catalogNumber should be 0-6 digits long numeric.
- Write, 1 byte, red
- Write, 1 byte, green
- Write, 1 byte, blue
- Write, 1 bytes, 0, unknown.
- Write, 4 bytes, 0xA, thread type.
- Write, 1 byte, Description length
- Write, n bytes, Description
- Write, 1 byte, Brand length
- Write, n bytes, Brand
- Write, 1 byte, Chart length
- Write, n bytes, Chart
After threads, back to header.
- Write, 2 bytes, 1, Objects In Pes.
Write block data in the same way as V.1, except using predefined colors rather than PEC Thread.
- Write CEmbOne block
- Write CSewSeg block We should end after the color log of the CSewSeg block. With the four byte, 0x0000 0x0000 terminator.
- Write, 8 bytes, 0 0 0 0 0 0 0 0, (this makes 12 zeros in a row with the terminator).
- Write, n order data chunks. Where n is the same as the number of color changes we wrote in the colors section.
Each Order Chunk.
- Write, 4 bytes, i
- Write, 4 bytes, 0
So for 3 elements we would write (not including the 00 00 00 00 terminator this comes right after): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00
Continue to Write PEC
The valid header for a blank v.6 PES file is: 23 50 45 53 30 30 36 30 64 00 00 00 01 00 30 31 00 00 00 00 00 01 00 00 00 64 00 64 00 00 00 C8 00 C8 00 64 00 64 00 64 00 0C 00 13 00 01 00 00 00 00 00 19 00 00 00 00 00 00 00 00 80 3F 00 00 00 00 00 00 00 00 00 00 80 3F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
This works but suffers from some rather notable oddities since the colors are absent and expected. PE-Design loads blank as there's no data for it. Wilcom loads with random colors, despite there still being valid PEC colors in the PEC block.
File should end with .pec Write "#PEC0001" Continue to Write PEC
In accordance with hacking PES files:
- Write #PES0001
- Write 1 byte 0x16
- Write 13 bytes 0x00
Continue to Write PEC
The PES block, in total, is:
- 23 50 45 53 30 30 30 31 16 00 00 00 00 00 00 00 00 00 00 00 00 00
No software other than PE-Design will notice, and PE-Design will load normally and display a blank document.
In accordance with hacking PES files:
- Write #PES0001
- Write 0x0c 0x00 0x00 0x00
Continue to Write PEC
This PES block is in total: "#PES0001" 'u32' 12 (0C 00 00 00), the truncated header is 12 bytes in total. The magic number tag and the 4 bytes that says the PEC file starts at the 12th (0x0C) byte.
PE-Design will crash, but no other software will notice that there's no PES or header.
PES format
- PES format overview
- PES section
- PEC section
- PEC thread palette
- Write PES
- Write PEC
- Unknowns