Stitch format PMV
.pmv files are a brother stitch format.
Overview
Stitch formats are strictly embroidery in the traditional sense. They are the applications of patterned stitches on to fabric. But these are done with programs within the sewing machine itself. Rather than the entire XY field of the hoop they have a Y field of the presser foot and an X dimension forward and back along the fabric. It is for this reason that the formatting is stored in a hybrid absolute/relative manner with different encoding schemes. The amount the element moves up in the fabric is different than the amount the needle moves within the presser foot.
There are several other related Brother stitch files this is simply the only one analyzed.
Header
The header is exactly 100 bytes long. 7 bytes of format spec, 36 of copyright. And 57 bytes of a few different stitch settings.
Type | Bytes | Value | Description |
---|---|---|---|
`string` | 7 | "#PMV0001" | Nearly ever brother format starts with a similar header. |
`string` | 36 | copyright | This is not needed for the format explicitly but the files contain a copyright message. This doesn't affect whether the files work or not. |
`s8` | 9 | \x01\x00\x00\x00\x00\x00\x00\x00\x00 | Unknown |
`s8` | 1 | Length Offset | Usually 00, but can be set within the stitch and saved. It's the offset from the default in signed 8 bit. |
`s8` | 1 | Width Offset | Usually 00, but can be set within the stitch and saved. It's the offset from the default in signed 8 bit. |
`s8` | 42 | (00 or 01) | Unknown |
L/R shift is a 16 bit integer located at 0x4A-0x4B. The length table offset is an 8 bit int located at 0x34 and the width table offset is located at 0x35.
Stitch Block
Point count Byte count. 6 bits forward/back 5 bits movement within presser foot.
While +15,-16 is possible beyond 14,14 is never seen.
Ends with 0, 256 16le 0 16le 256 Likely due to there not being another stitch block.
Followed by 16 bytes of unknown. b'\x00\x00\x00\x00\x05\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x02\x00'
Control Tables
Unknown: 16le 256 8 0 8 0
The sewing machines apparently don't do the math themselves so they process a bunch of tables of settings.
length_range = max_x - min_x write_length_lookup_table(f, length_range) width_range = max_y - min_y write_width_lookup_table(f, width_range) write_int_16le(f, 0x12) f.write(b'\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x00')
Length Lookup Table
write_values = [(0, 0), (10, 71), (20, 143), (40, 214), (60, 286), (80, 357), (100, 429), (120, 500), (140, 571), (160, 714), (180, 786), (200, 857), (250, 1000), (300, 1286), (350, 1429), (400, 1571), (450, 1786), (500, 2000)] write_int_8(f, 12) steps = len(write_values) write_int_8(f, steps) for value in write_values: length_at_step = value[0] other_at_step = value[1] write_int_16le(f, length_at_step) write_int_16le(f, other_at_step)
Width Lookup Table
pos = int(width_range / 2) write_int_8(f, pos) if width_range == 0: write_int_8(f, 1) write_int_16le(f, 8192) write_int_16le(f, 1000) return steps = 15 write_int_8(f, steps) second_max = other_step = 28000.0 / float(width_range) second_step = second_max / float(steps - 1) for i in range(0, steps): width_at_step = 50 * i other_at_step = second_step * i
write_int_16le(f, width_at_step) write_int_16le(f, int(round(other_at_step)))