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

削除された内容 追加された内容
→‎そもそもの圧縮の理論について: 簡易的なコード例。初学者用の理解優先のものなので、想定漏れあり(明記済み)。
1,025 行
例えば、下記のようになります。簡易的なものなので、2種類の文字までしか圧縮に対応していませんが、とりあえずこれでも実装時の方針はつかめます。
想定漏れはいろいろありますが、文句をつけるのではなく、読者がご自身で改良したコードを手元で自分で作っていってください。そうやってプログラミングは勉強していくものです。
 
1バイトの整数を宣言するには char 型を使います。(一方、int 型だと4バイトになるので、エラーの原因になりかねず危険です。)
 
また、ランレングスでは繰り返し回数は必ず0以上の正(ただし0も正とした)の数なので unsigned char 型で宣言するのが安全です。(unsigned をつけないと、繰り返し回数 128以上の結果が異なってしまうので。)
 
 
1,042 ⟶ 1,046行目:
}
 
unsigned char str1[70]; // 表示結果を短くするために数値を微妙に小さくした
printf("機械語を読み取っています。\n"); // 「文字列」ではなく機械語
 
1,192 ⟶ 1,196行目:
 
なお、実際にコードを作る場合は、けっしていきなり for とかwhile のコードを書くのではなく、愚直にまずは if 文のコードで「文字が2回続いた場合」「文字が3回続いた場合」などと場合ワケをしていき、あとからそれら場合分けをしたいくつもあるif文ブロックをfor などの構造でまとめていくことで、上記のように雛形(ひながた)を作っていきます。
 
ランレングスは、符号の種類が少ない場合ほど、符号が連続しやすいので、圧縮効率が高くなります。なので、ファクシミリなどの白黒印刷で、よくランレングス圧縮が使われます。
 
説明の都合上、文字の圧縮で解説していますが、どちらかというとランレングスはある種の画像データの圧縮向きであり、文書データの圧縮には向かない手法です。
 
=== PackBits ===
ランレングス圧縮の欠点として、
 
ABCDE
 
のような文字を圧縮すると、
 
A1B1C1D1E1
 
となり、逆に長くなってしまいます。
 
そこで、長さが2以上または3以上のときにだけ圧縮する手法が考えられますが、しかしこの問題は、どこが圧縮された文字で、圧縮されてない文字かの区別をつけるのが難しいことです。
 
そこで、圧縮する部分としない部分との区別を、負数で区別する方法が考えられました。
 
たとえば
 
AAAAABCDEEEE
 
 
A5B-3E4
 
のように処理する方法です。
 
ただし、この方法だと、負数を保管するために負号付き整数を利用するため、 つまり 255文字ではなく127文字までしか長さを保管できません。
 
C言語では、unsigned をつけないchar型で宣言すれば、-128~127を保管できる1バイト整数型になります。