「ゲームプログラミング/画像ファイルの作成プログラム」の版間の差分

削除された内容 追加された内容
→‎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バイトと比べたら大幅に圧縮できているので、意義のある圧縮です。