HUS and VIP File Formats

This file has been taken from Jason Weiler and updated using information from Embroidermodder and KDE’s Liberty project as well as some of my own work.

File Header Information (Same for HUS & VIP)

Note: Multibyte values are stored in little-endian.

Offset Size Description
0x00 4 bytes HUS: Can be 0x5B 0xAF 0xC8 0x00 or 0x5D 0xFC 0xC8 0x00[1]
VIP: Always 0x5D 0xFC 0x90 0x01
0x04 4 bytes NumberOfStitches - The total number of stitches defined in this file.
0x08 4 bytes NumberOfColors - The total number of colors used in this pattern.
0x0C 2 bytes (signed) +X hoop-size offset as a positive number (same as +X from DST)
0x0E 2 bytes (signed) +Y hoop-size offset as a positive number (same as -Y from DST)
0x10 2 bytes (signed) -X hoop-size offset as a negative number (same as -X from DST)
0x12 2 bytes (signed) -Y hoop-size offset as a negative number (same as +Y from DST)
0x14 4 bytes Absolute file-offset to SECTION 1 (contains stitch attributes)
0x18 4 bytes Absolute file-offset to SECTION 2 (contains x-coordinates)
0x1C 4 bytes Absolute file-offset to SECTION 3 (contains y-coordinates)
0x20 8 bytes String identifier (I’ve never seen it used)
0x28 2 bytes Unknown

Color information

As with most embroidery formats, the first color is used for all the stitches up until the first color change; then the 2nd and so on.

HUS Color list

Offset Size Description
0x2A 2*NumberOfColors bytes Color indices

HUS files use a list of 2-byte color indices to express a progression of colors used in the pattern. This list starts immediately following the header information (offset 0x2A) and is always 2*NumberOfColors in length. Each colour is defined as 0xYY 0x00 where YY is a an index in the lookup table below. In theory this could be a little-endian index, though given the length of the table in seems unlikely.

It isn’t clear if there is an accepted set of colors and associated indices, but we’ve experimentally derived the following HUS color table:

Value Color[2] Color values
0x00 Black  #000000
0x01 Blue  #0000FF
0x02 Light Green  #00FF00
0x03 Red  #FF0000
0x04 Purple  #FF00FF
0x05 Yellow  #FFFF00
0x06 Gray  #7F7F7F
0x07 Light Blue  #339AFF
0x08 Green  #33CC66
0x09 Orange  #FF7F00
0x0A Pink  #FFA0B4
0x0B Brown  #994B00
0x0C White  #FFFFFF
0x0D Dark Blue  #00007F
0x0E Dark Green  #007F00
0x0F Dark Red  #7F0000
0x10 Light Red  #FF7F7F
0x11 Dark Purple  #7F007F
0x12 Light Purple  #FF7FFF
0x13 Dark Yellow  #C8C800
0x14 Light Yellow  #FFFF99
0x15 Dark Gray  #3C3C3C
0x16 Light Gray  #C0C0C0
0x17 Dark Orange  #E83F00
0x18 Light Orange  #FFA541
0x19 Dark Pink  #FF667A
0x1A Light Pink  #FFCCCC
0x1B Dark Brown  #732800
0x1C Light Brown  #AF5A0A

VIP Color table information (VIP Only)

Offset Size Description
0x2A 4 bytes Sometimes zero; otherwise 0x2E + 8*NumberOfColors[3]
0x2E 4*NumberOfColors bytes Encoded color information

VIP files are more advanced than HUS files in that they actually contain the real 24-bit colors that were intended by the pattern author. The color information is stored as RGB-0 quadruplets, but they’re also encoded with a simple double-XOR scheme. For example:

Encoded bytes:

48 70 DD B2  77 07 05 C3  48 0E D6 7A  70 E2 0E 40
4B 0A FA 1E  C5 64 DB B3  EE 36 C9 7D

becomes:

66 BA 49 00  FD D9 DE 00  F0 F0 F0 00  F7 38 66 00
7D 6F 00 00  FE BA 35 00  13 4A 46 00

The decoding algorithm is actually quite simple:

1
2
3
4
5
6
7
8
BYTE prevByte = 0
BYTE tmpByte = 0;
for (i=0; i < NumberOfColors*4; ++i)
{
tmpByte = INPUT[i] ^ TABLE[i];
OUTPUT[i] = tmpByte ^ prevByte;
prevByte = INPUT[i];
}

where:

INPUT and OUTPUT represent the encoded file bytes and the decoded output bytes TABLE represents a fixed set of values defined as:

2E 82 E4 6F  38 A9 DC C6  7B B6 28 AC  FD AA 8A 4E
76 2E F0 E4  25 1B 8A 68  4E 92 B9 B4  95 F0 3E EF
F7 40 24 18  39 31 BB E1  53 A8 1F B1  3A 07 FB CB
E6 00 81 50  0E 40 E1 2C  73 50 0D 91  D6 0A 5D D6
8B B8 62 AE  47 00 53 5A  B7 80 AA 28  F7 5D 70 5E
2C 0B 98 E3  A0 98 60 47  89 9B 82 FB  40 C9 B4 00
0E 68 6A 1E  09 85 C0 53  81 D1 98 89  AF E8 85 4F
E3 69 89 03  A1 2E 8F CF  ED 91 9F 58  1E D6 84 3C
09 27 BD F4  C3 90 C0 51  1B 2B 63 BC  B9 3D 40 4D
62 6F E0 8C  F5 5D 08 FD  3D 50 36 D7  C9 C9 43 E4
2D CB 95 B6  F4 0D EA C2  FD 66 3F 5E  BD 69 06 2A
03 19 47 2B  DF 38 EA 4F  80 49 95 B2  D6 F9 9A 75
F4 D8 9B 1D  B0 A4 69 DB  A9 21 79 6F  D8 DE 33 FE
9F 04 E5 9A  6B 9B 73 83  62 7C B9 66  76 F2 5B C9
5E FC 74 AA  6C F1 CD 93  CE E9 80 53  03 3B 97 4B
39 76 C2 C1  56 CB 70 FD  3B 3E 52 57  81 5D 56 8D
51 90 D4 76  D7 D5 16 02  6D F2 4D E1  0E 96 4F A1
3A A0 60 59  64 04 1A E4  67 B6 ED 3F  74 20 55 1F
FB 23 92 91  53 C8 65 AB  9D 51 D6 73  DE 01 B1 80
B7 C0 D6 80  1C 2E 3C 83  63 EE BC 33  25 E2 0E 7A
67 DE 3F 71  14 49 9C 92  93 0D 26 9A  0E DA ED 6F
A4 89 0C 1B  F0 A1 DF E1  9E 3C 04 78  E4 AB 6D FF
9C AF CA C7  88 17 9C E5  B7 33 6D DC  ED 8F 6C 18
1D 71 06 B1  C5 E2 CF 13  77 81 C5 B7  0A 14 0A 6B
40 26 A0 88  D1 62 6A B3  50 12 B9 9B  B5 83 9B 37

Stitch Attributes

Section 1 defines the per-stitch attributes of the pattern. This section is generally much smaller than the other two, but that’s only because the data in this section compresses more readily than in the others. The section is compressed using the proprietary ArchiveLib compression library made by Greenleaf Software. This library supports several different compression schemes, but the one used in this case is called AL_GREENLEAF_LEVEL_4. Once decompressed, the data should be exactly NumberOfStitches bytes in length with each byte sequentially representing one stitch of the pattern.

Attribute Stitch type
0x80 Normal stitch
0x81 Jump stitch
0x84 Color change
0x88 Cut?[4]
0x90 Last stitch in pattern

Stitch Coordinates

These sections are compressed using exactly the same method as Section 1, but they define the X and Y components of the pattern. They each decompress to exactly NumberOfStitches bytes in length. The first byte from Section 2 defines the X-coordinate of the first stitch in the pattern. Likewise, the first byte of Section 3 defines the Y-coordinate. Together with the first byte of Section 1, we get the full definition of the first stitch. Subsequent bytes correspond to one another in the same way.

The byte values of the second and third sections are signed and represent the relative movement from the previous stitch. These offsets are measured in 0.1mm units. For example, if the first bytes of the sections was 0x81, 0x45, 0xC9, this would be interpreted as a Jump Stitch moving X+6.9mm, Y-5.5mm.

Acknowledgements

Jimmy Engström - For pointing out the existence of the VIP format and how closely it resembled HUS…and for reminding me of this old project lurking on my hard drive. :)


Copyright Jason Weiler 2006. All Rights Reserved.


  1. Originally there was one magic byte sequence for HUS and one for VIP; however some test HUS files have been found with a combination of the first two VIP bytes and the last two HUS bytes so that option has been added. ↩︎

  2. This table has been updated using information from libembroidery/format-hus.h in Embroidermodder. The value for 0x10 was unknown; however in Embroidermodder all the values have been shifted up one to fill that gap. ↩︎

  3. This was derived from a number of files. As to why it is this bizarre calculation I have no idea. ↩︎

  4. This stitch doesn’t have a obvious purpose; however it appeared at the start of a series of jumps making cut a plausible meaning ↩︎