Rough overview of a PES0070-File: --------------------------------- * This is work in progress. This is incomplete and contains errors. * It ends in a "PEC" file, which contains redundant stitch data in an (probably) slightly simpler format. * Numbers are stored little endian, most values are 16bit values. * Strings are encoded with a single-byte prefix, containing the length of the string. If the length exceeds 254 bytes the first byte contains 0xff and the length is encoded in the following uint16. * There is a block structure, with "FF FF 00 00" apparently serving as a separator, followed by a block identifier. I have not yet found the length of a block encoded somewhere. That makes skipping unknown blocks hard. It is unclear if there is a protection against block data consisting of "FF FF 00 00" itself. * There are some variable length strings in the beginning. Expecting certain number at fix offsets will fail. Details ------- 0000: 23 50 45 53 30 30 37 30 #PES0070 * 0x00-0x07: Header and Versionsnumber 0008: A5 01 00 00 .... * 0x08-0x0b: Offset of PEC-File (uint32) 000c: 01 00 30 31 ..01 * 0x0c-0x0f: 4 Bytes unknown. Observed values: PES0001: 00 00 01 00 PES0040, PES0070, PES0080: 01 00 30 31 0010: 0A 44 65 73 69 67 6E 6E 61 6D 65 08 43 61 74 65 .Designn ame.Cate 0020: 67 6F 72 79 07 41 75 20 54 68 6F 72 0F 4B 65 79 gory.Au Thor.Key 0030: 77 6F 72 64 73 31 2C 20 32 2C 20 33 17 55 6E 64 words1, 2, 3.Und 0040: 20 6E 6F 63 68 20 65 69 6E 20 4B 6F 6D 6D 65 6E noch ei n Kommen 0050: 74 61 72 2E tar. 0x10: * String: Design name * String: Category * String: Author * String: Keywords * String: Comment 0054: 00 00 00 00 64 00 64 00 00 00 C8 00 .... d.d..... 0060: C8 00 64 00 64 00 64 00 07 00 13 00 00 00 00 00 ..d.d.d. ........ 0070: 00 00 19 00 01 00 00 00 ........ Parameters from the embroidery file: * uint16: [ ] optimize hoop change * uint16: 0x00 for Page-Size == Hoop-Size, 0x01 for Custom Size * unit16: Hoop width in mm (100) * uint16: Hoop height in mm (100) * uint16: 0x00 for default-display, 0x02 for Monochrom? * uint16: Page width in mm * uint16: Page height in mm * uint16: hoop width in mm (from section width) * uint16: hoop height in mm (from section height) * uint16: unknown * uint16: Background color index * uint16: Page color index * uint16: [ ] Show Grid * uint16: [ ] with Axes * uint16: [ ] Snap to Grid * uint16: Grid interval (* 0.1mm) * uint16: Sewing Area: 0x00 "Design Page area", 0x01: "Use existing design area" * uint16: [ ] Optimize Entry points 0078: 00 00 00 80 3F 00 00 00 ....?... 0080: 00 00 00 00 00 00 00 80 3F 00 00 00 00 00 00 00 ........ ?....... 0090: 00 00 00 00 00 00 00 ....... * 31 Bytes unknown. Some floats? Could contain 24 bytes (6 floats) transformation matrix 0097: 02 00 03 38 30 30 ED 17 1F . ..800... 00A0: 00 0A 00 00 00 01 35 0A 45 4D 42 52 4F 49 44 45 ......5. EMBROIDE 00B0: 52 59 00 03 34 30 35 0A 55 A3 00 0A 00 00 00 01 RY..405. U....... 00C0: 32 0A 45 4D 42 52 4F 49 44 45 52 59 00 2.EMBROI DERY. Color table: * uint16: Number of entries in the color table. * for each color: * String: "Code" * 3 Bytes: RGB-representation of the color * 5 Bytes: unknown * String: "Description" * String: "Brand" * String: "Thread Chart Name" here: two colors: ("800", #ed171f", ..., "5", "EMBROIDERY", "") ("405", #0a55a3", ..., "2", "EMBROIDERY", "") 00CD: 02 00 FF ... 00D0: FF 00 00 07 00 43 45 6D 62 4F 6E 65 .....CEm bOne * Block structure of PES starts * uint16: unknown. some observed values: 0x0001, 0x0002, 0x0003, 0x0005, 0x0007, 0x0042 * FF FF 00 00: Unknown. Crude block separator? * uint16: block name length * bytes: block name (here: "CEmbOne") Block: CEmbOne -------------- This block apparently contains information about the (one of many?) embroidery. 00DC: 6C 03 C8 02 l... 00E0: 6D 03 C9 02 6C 03 C8 02 6D 03 C9 02 m...l... m... * General Information about the embroidery. Bounding Box. * uint16: min_x * uint16: min_y * uint16: max_x * uint16: max_y another bounding box. Not sure what for exactly. * uint16: min_x * uint16: min_y * uint16: max_x * uint16: max_y 00EC: 00 00 80 3F ...? 00F0: 00 00 00 00 00 00 00 00 00 00 80 3F 00 00 00 00 ........ ...?.... 0100: 00 00 00 00 .... Transformation matrix for stitch coordinate system vs. bounding box. * 4 floats (a, b, c, d) scaling/shearing/rotation (matrix multiplication) * 2 floats (x, y) offset 0104: 01 00 6C 03 C9 02 01 00 01 00 00 00 ..l. ........ 0110: 00 00 00 00 00 00 01 00 FF FF 00 00 ........ .... * uint16: unknown * uint16: min_x * uint16: max_y * uint16: width (max_x - min_x) * uint16: height (max_y - min_y) * 18 unknown bytes, followed by the starting header of the next block could be the number of components, followed by start coordinate and color? Block: CSewSeg -------------- Contains "raw" stitches. [different example data] 00B0: 00 01 00 FF FF 00 00 07 00 43 53 65 77 53 65 67 ........ .CSewSeg * Header 00C0: 00 00 00 00 03 00 C8 02 BD 02 C8 02 C2 02 CE 02 ........ ........ 00D0: C2 02 01 00 00 00 00 00 01 80 CE 02 C8 02 D4 02 ........ ........ 00E0: C8 02 CE 02 C8 02 D4 02 C8 02 00 00 80 3F 00 00 ........ .....?.. 00F0: 00 00 00 00 00 00 00 00 80 3F 00 00 00 00 00 00 ........ .?...... 0100: 00 00 01 00 CE 02 C8 02 06 00 00 00 00 00 00 00 ........ ........ 0110: 00 00 00 00 01 00 03 80 00 00 00 00 02 00 CE 02 ........ ........ 0120: C8 02 D4 02 C8 02 01 00 00 00 00 00 00 00 00 00 ........ ........ 0130: 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 ........ ........ 0140: 00 00 00 00 .... * 2 bytes 0x00: unknown * uint16: color index * uint16: number of coordinates * *(uint16, uint16): Stitch coordinates [...] * 4 Bytes: 0x01 0x00 0x00 0x00: unknown * uint16: color index (why twice?) For multiple colors: separator between stitch data: * 0x01 0x80: block ID? apparently also 0x09 0x80, 0x03 0x80 ? dann analog zu CEmbOne: * 4x uint16: min_x, min_y, max_x, max_y * 4x uint16: min_x, min_y, max_x, max_y (why a 2nd bounding box?) * 6x float: transformation matrix * uint16: unknown * uint16: min_x * uint16: max_y * uint16: width (max_x - min_x) * uint16: height (max_y - min_y) * 8 bytes 0x00 unknown * 0x01 0x00 unknonwn * 0x03 0x80 separator? [next stitch data segment] Finally the block ends with 8 bytes per component, which apparently determines the sewing order. PEC-Code section ---------------- Preview section --------------- In the end there are several small bitmap images (48x38 pixels, 228 Bytes each) using the bits from low to high. There generally is a "global" preview image plus one for each color/stitching pass. Then there are 128 byte, per default filled with 0x20 (space). These bytes contain: * uint8: number of colors * for each color: color ID. Following are some smaller images showing the color IDs. These are 48x24 = 144 bytes. * In the end there are 3-byte RGB color codes for all colors, * two bytes 0x00 0x00 * library id (byte) / color code numbers (uint16) for all colors. 0x0d Brother Embroidery 0x0c Brother Country 0xfe Ver4 Option Color (?) 0x0b Brother Flesh Tone (Embroidery) 0x08 Sulky Rayon 0x05 Madeira Rayon 0x04 Madeira Polyneon 0x07 Robinson Anton Rayon 0x06 Robinson Anton Polyester 0x03 Isacord Polyester 0x02 Guetermann Dekor In stitching order.