Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Explanation on how Tokumaru's tile compression algorithm works.
- The following is pseudo-code that implements a decompressor.
- Reverse engineered by Joel Yliluoma in May 2016
- Based on source code published by Tokumaru and released in tokumaru_tile_compression.7z in 2009
- Algorithm document published at: http://pastebin.com/GNnimLzX
- Read byte ⇒ RemainingTileCount
- Read-new-color-followup-table:
- ; First read the color frequency table.
- For colors 3‥0 in Color:
- ; Read how many different colors can follow the current one
- Read 2 bits ⇒ ColorCount[Color]
- If ColorCount[Color] > 0:
- ; Decide which colors can come next.
- ; NextColor0, NextColor1 and NextColor2 are the colors sorted
- ; in order of probability. Transition from Color to each index
- ; may require one bit more to express than to the previous one.
- A = &NextColor0[Color]
- B = &NextColor1[Color]
- C = &NextColor2[Color]
- Read bit pattern:
- Case 0: A = 1 − (Color ≥ 1) ; 1 0 0 0
- Case 10: A = 2 − (Color ≥ 2) ; 2 2 1 1
- Case 11: A = 3 − (Color ≥ 3) ; 3 3 3 2
- ; Determine the two other colors, that are neither Color nor A
- B = 0. While B=Color or B=A: B = B+1
- C = B+1. While C=Color or C=A: C = C+1
- ; If the number of colors is 2, remove A from the list.
- If ColorCount[Color] = 2: A,B = B,C
- ; Thus, the colors chosen are:
- ; When colors=1: A
- ; When colors=2: B,C
- ; When colors=3: A,B,C
- Read-tiles:
- ; Assume that the previous row was all blank (color 0).
- Plane0 = $00
- Plane1 = $00
- SecondHalf = buffer for 8 bytes
- For rownumber 0‥7 in y:
- ; Read the next row, unless the row just repeats.
- Read 1 bit ⇒ RepeatFlag
- If RepeatFlag = 0:
- ; Read the color of the first pixel.
- Read 2 bits ⇒ Color
- ; Read the colors of the other 7 pixels.
- ; If colors=0, done. Color is not changed, bits are not read.
- ; Else a bit is read; if 1, done. Color is not changed.
- ; Else select color0. If colors=1, done.
- ; Else a bit is read. If 1, select color1. If colors=2, done.
- ; Else a bit is read. If 1, select color2.
- ; In other words:
- ; When colors=0, the color is not changed, and no bits are read.
- ; When colors=1, 1 = not changed, 0 = color0.
- ; When colors=2, 1 = not changed, 00 = color0, 01 = color1.
- ; When colors=3, 1 = not changed, 00 = color0, 010 = color1, 011 = color2.
- For coordinate 0‥7 in x:
- Read bit pattern:
- Case ε when x=0 or ColorCount[Color]=0: Color = Color
- Case 1 when x>0 and ColorCount[Color]>0: Color = Color
- Case 0 when x>0 and ColorCount[Color]=1: Color = NextColor0[Color]
- Case 00 when x>0 and ColorCount[Color]>1: Color = NextColor0[Color]
- Case 01 when x>0 and ColorCount[Color]=2: Color = NextColor1[Color]
- Case 010 when x>0 and ColorCount[Color]>2: Color = NextColor1[Color]
- Case 011 when x>0 and ColorCount[Color]>2: Color = NextColor2[Color]
- Shift Color into Plane0 and Plane1
- // Write out the current row:
- Send 1 byte ⇐ Plane0.
- Write Plane1 ⇒ SecondHalf[y]
- ; The tile is complete. Send out the second half.
- Send 8 bytes ⇐ SecondHalf[0‥7].
- ; If TileCount becomes 0, compression is complete and ends here.
- if --RemainingTileCount = 0: Return
- ; Otherwise read what to do next.
- Read bit pattern:
- Case 0: Go read more tiles.
- Case 1: Go and read a new color-followup-table.
- Bits are read and stored MSB-first.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement