Welcome to JasonWeiler.com

I work on lots of stuff in my spare time. Occasionally something gets cooked enough to serve. When that happens, it winds up here:

HUS and VIP File Formats

File Header Information (Same for HUS & VIP)

OffsetSizeDescription
0x00 2 bytes HUS: Always 0x5B 0xAF. VIP: Always 0x5D 0xFC
0x02 1 byte HUS: Must be 0xC8. VIP: Must be 0x90
0x03 1 byte HUS: Always 0x00. VIP: Always 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 +X hoop-size offset as a positive number (same as +X from DST)
0x0E 2 bytes +Y hoop-size offset as a positive number (same as -Y from DST)
0x10 2 bytes -X hoop-size offset as a negative number (same as -X from DST)
0x12 2 bytes -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

HUS Color list information (HUS Only)

OffsetSizeDescription
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. The colors are applied to the pattern starting with the first one, and moving to the next whenever a color-change stitch is encountered. 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:

0x00 - Black 0x10 - ???
0x01 - Blue 0x11 - Light Red
0x02 - Green 0x12 - Dark Purple
0x03 - Red 0x13 - Light Purple
0x04 - Magenta (Purple) 0x14 - Dark Yellow
0x05 - Yellow 0x15 - Light Yellow
0x06 - Gray 0x16 - Dark Grey
0x07 - Light Blue 0x17 - Light Grey
0x08 - Light Green 0x18 - Dark Orange
0x09 - Orange 0x19 - Light Orange
0x0A - Pink 0x1A - Dark Pink
0x0B - Brown 0x1B - Light Pink
0x0C - White 0x1C - Dark Brown
0x0D - Dark Blue 0x1D - Light Brown
0x0E - Dark Green
0x0F - Dark Red

VIP Color table information (VIP Only)

OffsetSizeDescription
0x2A 4 bytes *Unknown - Values don't appear to be used. Sometimes the value is zero. But when it's non-zero, it is roughly proportional to the number of colors.
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:
	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
			

Section 1 - Stitch Attributes (Same for HUS & VIP)

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 (http://www.greenleafsoft.com). 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.

0x80 - Normal stitch
0x81 - Jump stitch
0x84 - Color change
0x90 - Last stitch in pattern

Sections 2 & 3 (Same for HUS & VIP)

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 (+6.9mm, -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 harddrive. :)