Skip to content
frno7 edited this page Apr 23, 2017 · 10 revisions

The PES format is a machine embroidery file format for Brother Industries and Bernina International series of embroidery machines, among others.

PES files contain at their core two different parts for two completely different purposes. The PES part contains the design information for Brother PE-Design and similar applications. And the PEC part contain the design name, colors, embroidery machine commands, and graphics. These are all intended for the embroidery machine. Since the PEC block is the same in all versions so that it's always backwards compatible with the hardware of the Brother and Bernina embroidery machines, software tends to only read that data and turns those commands into line segments.

PES version 1. The only blocks contained within the format were the CEmbOne and CSewSeg blocks. These blocks contain the affine transformation data for the position data, and the position data. These can be grouped in a few different ways but they only ever contain sewing segment information. So within PES version one we end up with two copies of the same data in each of their respective blocks.

Later versions of PES have higher level objects which contain vector shapes and information about how these are filled when it renders. If a PES version 6 design, for example, contained a rectangle object. The PES block would have a CEmbRect object only. The PEC block would have all the commands for the machine to sew that according to the pathing chosen by the instance that saved the PES file. The reason for this is if Brother PE-Design loses the information it used to generate the PEC data namely that it was a rectangle at this specific location it becomes impossible to do operations like change the spacing between the scanlines within the rectangle, because after reloading the file all the program would have access to are the line segments; losing the shape makes rerendering that shape with a different fill density impossible.

Fully grasping these elements of the format allow for hacking PES files or ways to modify them in logically consistent but weird methods.

Unknown parts

Several parts of the PES format remain unknown and are not properly described in this wiki. If you happen to understand these parts and are happy to contribute, please do!

File Format

The PES file consists of the version data #PES0001, #PES0020, #PES0030, #PES0040, #PES0050, #PES0055, #PES0060. This is followed by the PEC seek value, as a 4 byte little-endian integer. Then within the file the two main sections the PES and the PEC. The PES section must immediately follow this and often the version and the PEC seek value are considered in the context of the header. The PEC section can occur anywhere. The seek value must point to it though. Outside hacking the PES file these occur immediately after each other with the seek value set to the appropriate location.

The PES and PEC sections are distinct and disjoint and have their own conventions, purposes, formats, read values, etc. You will always find shorts in PEC block. It's all PEC writes. Whereas PES will in places read and write 4-byte integers and floating point numbers. The PEC section is a 16 bit format. PES section is a 32 bit format. PES is variable and valid things in one version are invalid in the next, and the header is different for each version. Whereas PEC needs to be consistent and remain backwards compatible so all future embroidery machines can read any PES files.

Sections

Section Description
PES High-level embroidery design data, primarily for embroidery design applications
PEC Low-level embroidery machine data, primarily for embroidery hardware

Basic types

All integer and floating point numbers are stored in little-endian byte order unless otherwise noted.

Type Bytes Description
char 1 ASCII text (not NUL terminated)
u8 1 8 bit unsigned integer
u16 2 16 bit unsigned integer
s16 2 16 bit signed integer in stitch coordinate space where 1 represents 0.1 mm
u32 4 32 bit unsigned integer
f32 4 32 bit single-precision floating-point number