「ゲームプログラミング/画像ファイルの作成プログラム」の版間の差分
削除された内容 追加された内容
→PNGフォーマット: ランレングス |
|||
884 行
同人ゲームプログラミングなどでよくDXライブラリが使われますが、幸運なことに、DXライブラリの作者さまは圧縮にも興味を持っており、リンク先 [https://dxlib.xsrv.jp/lecture/Press/press.html 『データ圧縮プログラムについてざっくり学ぶ』] のように圧縮についての技術解説をしたwebページを作ってくれています。
== そもそもの圧縮の理論について ==
よく圧縮の原理の説明で、「AAAAAAA」(Aが7個ある)を「A7」に置き換える、などと習います(なお「ランレングス圧縮」の原理)。高等学校でも、「ランレングス」という用語は習いませんが、こういう感じの原理を習います。
さて、上記「AAAAAAA」の説明では、都合よく続いている元の文字が、数字ではなく英字です。
ですが、もし「3333333」という数字の並びを圧縮するとき、どうするのかという問題があります。「37」とでも書くのでしょうか? しかしこれだと、もし三十七という内容の文字を表したい場合に困ります。
そう、つまり、実際には「A7」のような原理だけでは、圧縮できないのです。さらに必要な工夫として、圧縮後のどこからどこまでが文字の1単位であり、どこが反復回数なのかを、なんらかの方法で区別する必要性があるのです。
この問題を解決するための方法は単純であり、
:必ず1バイト単位(十六進で2桁)で処理する。
:必ず単位の文字に、反復回数を併記する。
という方法を使います。
たとえ1回しか現れない文字でも、反復回数を併記します。そのほうがアルゴリズムが簡単だからです。
具体例
「3」はアスキーコードで 0x03 です。これを7回続ける 3333333 なら、
0x03 0x07 です。
一方、「37」はアスキーコードで「0x03 0x07」です。1バイト単位で扱うので、「3」を1回、「7」を1回なので、
0x03 0x01 0x07 0x01
となります。
こうすることで、アスキー「3333333」とアスキー「37」を区別できます。
追記
なお、上記のような方法だと、反復回数は1バイト単位の最大数である FF までなので、つまり 255 回までしか反復を1フレーズでは処理できません。
だからもし「3」が262回続いたら、たとえば
0x03 0xFF 0x03 0x07
とでもなるでしょうか。圧縮後の記録が2バイトからバイトに増えましたが、しかしそれでも「FFFFF・・・」とFを262回記録する262バイトと比べたら大幅に圧縮できているので、意義のある圧縮です。
|