-
Notifications
You must be signed in to change notification settings - Fork 9
HG‐X ProcessImage
The HG image encoding used by the HG-3 and HG-2 formats (.hg3
, .hg2
). This encoding method is over 20 years old, and appears to be identical to the method described in this software patent.
🚧 This page is a work in progress
The encoding process is a bit lengthy, and shares some similarity to the PSVita CSX image formats (primarily delta filtering, and image slicing). The primary methods used are:
- Zlib compression
- Elias Gamma coding
- Zero-run length encoding
- Weighted table normalization
- Absolute signed values
- Delta filtering
- Image slicing (never used, HG-3 only)
When simplified, these processes can be grouped into 2-3 functions. In addition, the following are used before the encoding or after the decoding process.
- Crop transparent borders
- Vertically flip pixel buffer (like in Bitmap image format, Orthogonal transform)
- Reduced bit depth of each RGBA channel (HG-2 only)
The weight tables are 4 arrays of 256 byte values each, only used during the decoding process. The encoding process has no simple lookup table equivalent, and must be done manually, in the same manor that the weight tables are initialized.
31 23 15 7 0
0000 0000 0000 0000 0000 0000 0000 0000
1122 3344 1122 3344 1122 3344 1122 3344
32:30 24:22 16:14 8:6
30:28 22:20 14:12 6:4
28:26 20:18 12:10 4:2
26:24 18:16 10: 8 2:0
Byte | Table 1 | Table 2 | Table 3 | Table 4 |
---|---|---|---|---|
0 | 00000000 |
00000000 |
00000000 |
00000000 |
1 | 00000040 |
00000010 |
00000004 |
00000001 |
2 | 00000080 |
00000020 |
00000008 |
00000002 |
3 | 000000c0 |
00000030 |
0000000c |
00000003 |
4 | 00004000 |
00001000 |
00000400 |
00000100 |
5 | 00004040 |
00001010 |
00000404 |
00000101 |
6 | 00004080 |
00001020 |
00000408 |
00000103 |
7 | 000040c0 |
00001030 |
0000040c |
00000103 |
8 | 00008000 |
00002000 |
00000800 |
00000200 |
9 | 00008040 |
00002010 |
00000804 |
00000201 |
... | ... | ... | ... | ... |
248 | c0c08000 |
30302000 |
0c0c0800 |
03030200 |
249 | c0c08040 |
30302010 |
0c0c0804 |
03030201 |
250 | c0c08080 |
30302020 |
0c0c0808 |
03030202 |
251 | c0c080c0 |
30302030 |
0c0c080c |
03030203 |
252 | c0c0c000 |
30303000 |
0c0c0c00 |
03030300 |
253 | c0c0c040 |
30303010 |
0c0c0c04 |
03030301 |
254 | c0c0c080 |
30303020 |
0c0c0c08 |
03030302 |
255 | c0c0c0c0 |
30303030 |
0c0c0c0c |
03030303 |
Mask | |
---|---|
c0c0c0c0 |
255 |
30303030 |
255 |
0c0c0c0c |
255 |
03030303 |
255 |
To describe this section, signed and unsigned values will be used interchangeably. This part of the encoding reduces the number of '1' bits for negative numbers by 'grouping' them with positive numbers.
Normal signed int8 value:
Byte | Byte bits | Abs | Abs bits |
---|---|---|---|
0 | 0000 0000 |
0 | 0000 0000 |
-1 | 1111 1111 |
1 | 0000 0001 |
1 | 0000 0001 |
2 | 0000 0010 |
-2 | 1111 1110 |
3 | 0000 0011 |
2 | 0000 0010 |
4 | 0000 0100 |
-3 | 1111 1101 |
5 | 0000 0101 |
... | ... | ... | ... |
126 | 0111 1110 |
252 | 1111 1100 |
-127 | 1000 0001 |
253 | 1111 1101 |
127 | 0111 1111 |
254 | 1111 1110 |
-128 | 1000 0000 |
255 | 1111 1111 |