トップ小ネタPrince of Persia > 圧縮データ


圧縮データ

一部のファイルは圧縮して保存されています。
ここでは、マップファイルなどにかかっている圧縮データの解説をします。

※ここで解説している圧縮形式はMAPファイルや一部の画像ファイルで使われていますが、
 ファイルによっては他の形式で圧縮されている可能性もあります。

データは基本的に
[圧縮パターン番号] [パラメータ]
の繰り返しで、パターン番号によって展開方法が違い、
パラメータ部のサイズ、展開サイズもパターン番号によって変わります。
(パラメータ部:0〜3バイト 展開サイズ:4の倍数)

圧縮されたファイルを展開する時は、
1.パターン番号を読みこむ
2.後に続くパラメータ部を読み込む(無い場合もある)
3.圧縮パターンとパラメータからデータを展開して展開先バッファに書き込む
4.1に戻る(次の圧縮パターンを読み込む)
…の繰り返しになります。
ファイルの終端まで来たら終了です。
(終了を示す識別子のようなものは無いようです)

展開方法
各圧縮パターンごとの展開方法を解説します。
・値は基本的に16進数で表しています。
・[ ]付き数字はパターン番号、 aa bbなどはパラメータ部を表しています。
・「*1」など、*付きの数字は、*の部分に任意の値が入ることを表しています。
・「前の○byte〜」「○byte前〜」となっているものは、
 (展開後のデータに対して)展開先のアドレスから○バイト前が参照されます。

・00(無圧縮)
展開前 展開後
[00] aa bb cc dd aa bb cc dd

・*1、*2(繰り返し(コピー)系)
展開前 展開後
[01] (前の4byteをコピー)
[02] aa aa aa aa aa
[11] aa (前の4byteを(aa+1)回繰り返して書き込む)
[21] aa bb (前の4byteを(bbaa+1)回繰り返して書き込む)
[81] (8byte前から4byte分コピー)
[91] aa (前の8byteを4byte単位で(aa+1)回繰り返す)
[a1] aa bb (前の8byteを4byte単位で(bbaa+1)回繰り返す)
例:
手前の8バイト(展開後)が 01 02 03 04 05 06 07 08の時、
[01]    → 05 06 07 08
[11] 01 → 05 06 07 08 05 06 07 08
[81]    → 01 02 03 04
[91] 01 → 01 02 03 04 05 06 07 08
[91] 02 → 01 02 03 04 05 06 07 08 01 02 03 04

※[81][91][a1]に関しては、
 1.「その圧縮パターンが来る前の8byte前」
 2.「展開先アドレスの8byte前」
 の、どちらの方式で処理しているのかは不明ですが、
 展開した結果はどちらも同じになるはずなので問題ないと思います。

・*3、*4
展開前 展開後
[03] aa bb aa bb bb bb
[04] aa bb aa aa bb bb
[13] aa bb aa bb aa aa
[14] aa bb aa bb aa bb
[23] aa bb aa aa bb aa
[24] aa bb aa bb bb aa
[33] aa bb aa aa aa bb
[44] aa bb cc aa aa bb cc
[54] aa bb cc aa bb aa cc
[64] aa bb cc aa bb cc aa
[74] aa bb cc aa bb bb cc
[84] aa bb cc aa bb cc bb
[94] aa bb cc aa bb cc cc

・*5、*6
展開前 展開後
[*5] ab cd *b *a *d *c
[*6] ab cd b* a* d* c*
例:
[05] 12 34 → 02 01 04 03
[15] 12 34 → 12 11 14 13
.....
[F5] 12 34 → F2 F1 F4 F3

[06] 12 34 → 20 10 40 30
[16] 12 34 → 21 11 41 31
.....
[F6] 12 34 → 2F 1F 4F 3F

・*7〜*a
※「--」の部分に入る値は、パターン番号の下の位(下位8bit)によって違います。
 *7 = 00
 *8 = ff
 *9 = 4byte前の値
 *a = 8byte前の値
展開前 展開後
[0*] aa -- -- -- aa
[1*] aa -- -- aa --
[2*] aa -- aa -- --
[3*] aa aa -- -- --
[4*] aa bb -- -- aa bb
[5*] aa bb -- aa -- bb
[6*] aa bb -- aa bb --
[7*] aa bb aa -- -- bb
[8*] aa bb aa -- bb --
[9*] aa bb aa bb -- --
[a*] aa bb cc -- aa bb cc
[b*] aa bb cc aa -- bb cc
[c*] aa bb cc aa bb -- cc
[d*] aa bb cc aa bb cc --
例:
[57] 44 55 → 00 44 00 55
[58] 44 55 → ff 44 ff 55
手前の8バイト(展開後)が 01 02 03 04 05 06 07 08の時、
[59] 44 55 → 05 44 07 55
[5a] 44 55 → 01 44 03 55

・f7、f8(固定値)
展開前 展開後
[f7] 00 00 00 00
[f8] ff ff ff ff
戻る