第1回PAC(ポケコンアルゴリズム協議会)

テーマ

「ポケコン用画像圧縮規格の考案」

PAC参加者のページ

 ポケコンでもE500シリーズのOPASやG800シリーズのSAS(by Toshiさん)などの登場によりBASICでもグラフィックを多用したゲーム等が作れるようになりました。しかし、データは無圧縮のGPRINT形式(縦8ドットで2バイト消費)が基本となっておりメモリの無駄や入力の手間がかかるなどの問題があり、ポケコン用の画像圧縮規格が欲しいと思っている人も多いことでしょう。
 そこですぐに考えつく人もいると思いますが、すでに存在する、GIFやPNGなどの圧縮規格をポケコンに移植しようというものです。しかし、スペックが違うポケコンに移植するのは少々無理がある(メモリ面・速度面)上に、扱うデータがバイナリデータではなくテキストデータのため単純に移植もできません。しかしながら、圧縮の考えとしては役に立つ部分もあるので、参考として知っておくのは悪くないと思います。

《参考》
圧縮法入門 http://www.ingnet.or.jp/~kojif/mu/comp/index.htm

 ということで今回考えていくのは次の2点です。
(1)ポケコンに最適な画像データ圧縮・解凍ルーチンを考える
(2)ポケコン用標準圧縮規格を作る


《(1)についての補足》
 解凍ルーチンはBASICのゲーム等に組み込んで使用することを前提としているのでサイズはできるだけ小さく、速度もBASICで実現可能なものにする。 そういう制約の元でデータサイズを小さく、入力の負担を減らすようなものを考えることにする。

《(2)についての補足》
無理に1つに絞る必要はないけど、ある程度標準的な圧縮規格が定まれば、フリーの画像データ等も発表しやすくなり、ポケコンでグラフィックを多用したソフトが発表しやすくなるかもしれません。

では、まず私が最初に考えた圧縮アルゴリズムを簡単に書いておきます。

御茶目菜子式 画像圧縮
(1)GPRINT形式のデータを上位・下位の4ビットを分離する
(2)文字の組み合わせで最も多いものを調べそれを別のコードに置き換える
   置き換える前の文字は辞書に入れておく
(3)置き換えができなくなるまで(2)を繰り返す。
(4)連続する部分がある場合それを連続を表すコードに置き換える

以上で圧縮が終了

《解説》
 このアルゴリズムでは「簡易辞書+ランレングス法」を使用しており、一定の文字の組み合わせが多く出現したり、同じ文字(または同じ文字の組み合わせ)が連続する場合にはかなりの圧縮率が期待できます。
 しかし、パターンにばらつきが多い場合は圧縮率が低くなる、サイズが小さい画像では辞書の効果が生かせない、辞書のデータだけでも相当の量になるなどの多くの問題をかかえており、まだ改良を加えないといけないでしょう。  ちなみに辞書は2バイト固定式で数は45までです。(解凍プログラムの肥大化を防ぐための措置)


 多くの皆さんに圧縮アルゴリズムについて考えて貰いたいところですが、どの程度の圧縮率かを比較するには同じ画像を圧縮する必要があり、サンプル画像をそもそもさんに提供して戴きました。

24×24ドット サンプル画像(そもそもさん提供) F8FEFFFF3F1721070800100F8B88889023FF03FFFFFF7FFF
010709FFFE015D1EA0800003600E6B0F67F0FEFFE7EFF07F
000000033FFFA254BC58F030B858281410FF3F101729C000

 この画像(144バイト)を何%に圧縮可能になるのかを皆さんの圧縮アルゴリズムで試してみてください。この画像データは完全ランダムに文字が並んでいる訳ではなく少し偏りが見られますが、一般に人の手によって書かれた画像は少なからずパターンが見られます。したがって、この画像の圧縮率が平均的画像の圧縮率と言ってもそれほど問題はないでしょう。
 つまり、圧縮率を高めるにはこのデータの偏りをいかに利用するかがひとつのカギになりそうです。
 ちなみに私のアルゴリズムでは上記のデータは115バイトに圧縮できました。解凍ルーチンは400バイト程度です(E500系は数値がすべて8バイトで扱われるためG800系ならば250バイト程度で可能と思われる)。


圧縮アルゴリズム・プログラム募集中!!

以下の記事はおちゃめくらぶの掲示板に投稿されたのを引用したものです。掲載に関して不都合なことがありましたら、ご遠慮なく申し出てください。
また、引き続きポケコン用の画像圧縮・解凍についてのアルゴリズム、プログラム募集中です!何かあれば掲示板にお願いします!
投稿者 NO1さん(2001年1月25日)
lz77はなにかと組み合わせると有効かも
まぁ、、御茶目菜子陛下方式に辞書データが無い感じ+可変長辞書シュ”詳しくはYAHOOで検索して調べるにょ!”では逃げなので分かりづらい説明にょ、、(間違ってるかも)
”345934AF93”というGPRINTデータなら”3459!<4、2>AF!<5、2>”という感じで圧縮かもじゃて(実際には!<4、2>を”K”とかにあらかじめ割り当て)
この場合、4や5が何文字前に戻るかを表現し2がコピーする文字数にょ、、でも64文字程度を辞書に使えるとして!<8、8>程度しか、戻れないからのー解凍は比較的単純&早いはずシュ
このさい、、RLEとかと組み合わせるか、、
《コメント》
<8、8>では使い勝手が悪いので<16、4>の方が良いかと思います。でも、この考えはパターン化された画像にはかなり有効です!


投稿者 そもそもさん(2001年1月25日)
この方法は縦8ドット 横7ドットに適しています
まずデータを・・

例FF00FF00FF00FF
↑GPRINTデータです

これの各列のドットの一番上を取っていきます
すると 1010101になりますよね
これをG850だと使える文字が128以上あるので128進数で表します
仮に Gとしましょう
後は各列一ドット分取ってしまってるので128を越えることはありません

《コメント》
この方法だと確実に4/7に圧縮(57.1%)できます!
でも、横が7ドット単位というのが少し問題かも(笑)

投稿者 NO1さん(2001年1月26日)
そこで実際には132文字、辞書に使うことにしたにょ、、
これで標準で<22,6>にょ、、
さらに16文字を使って拡張タグすることにより最大で(つまり、2バイトで表現)<176,12>まで可能シュ
G850のかなりの文字コードを使用じゃのー(132+16+16=164文字使用)
しかしlz77は特に高圧縮だと圧縮に何十分かかりそうな気がする、、(爆)特に拡張すると、、、
《コメント》
前日の<8、8>しか戻ることができないという短所を改良したアイデアです。パターン化された画像なら、かなり、使えそうだけど圧縮に時間がかかるかも・・・(笑)
投稿者 NO1さん(2001年1月26日)
確実に66%に圧縮できる方式がいちよう決定にょ、、(6ドット=1バイト)
使用アスキーコード48〜111

欠点&長所
●RLEなどと組み合わせ可能
●非常に小さい画像も圧縮可能

まず、GPRINTデータの長さは3の倍数じゃなきゃ駄目にょ(ならない場合は終わりに0を追加)
で、、”FE2”のGPRINTデータがあるとするFEは文字コード48〜63の間に移動する
で問題なのは”2”

IF 2 AND 8 で1の場合は1文字目に32を足す
IF 2 AND 4 で1の場合は1文字目に16を足す
IF 2 AND 2 で1の場合は2文字目に32を足す
IF 2 AND 2 で1の場合は2文字目に16を足す(足すとは文字コード的に足すにょ、、)
以上で3文字を2文字に圧縮できるシュ
つまり、GPRINTデータにビットで重みをつけただけにょ、、

《コメント》
これは結構面白い方法です。私も6ビット符号化は思い付きましたが、「4ビット→6ビット」変換は速度やリストの長さの面でもかなり有利で圧縮率も固定で66.7%というのもまずまずです。となると圧縮率可変式のアルゴリズムを考える場合、平均圧縮率が66.7%を切るかどうかが高圧縮かどうかの分かれ目になりそうです。
投稿者 NO1さん(2001年1月27日)
圧縮する前にGPRINTデータを変化させることにより(一種の画像処理)格段に圧縮できる可能性があるにょ、、
まぁ、フィルタ無しの方が圧縮できる場合もあるので判定する必要があるけど

●フィルタの長所と欠点
フィルタ用のバイトが画像のヘッダ部に必要圧縮の処理時間が数倍になる(解凍も同様)
(↑なんのフィルタを使えばいいか調べなければ駄目なため)
圧縮&解凍プログラムの長さも長くなる
他の圧縮法と組み合わせて使うにょ

例、前のデータとの比較フィルタ
”123456789ABC”というGPRINTデータはそのままでは御茶目菜子陛下方式でもGPRINTのRLEでも圧縮不可能です
しかし、前のデータと比較してみると”11111111111”となり圧縮がかけやすくなります
解凍の時は元に戻す処理がいるシュ

例 偶数奇数交換フィルタ
”F0F0F0F0”というGPRINTデータを”FFFF0000”とか、、、

《コメント》
フィルタというのは圧縮率を高める場合に有効なことが多いです。しかし、どんなフィルタが効果的かはデータによって異なるので簡単なことではないです。
投稿者 NO1さん(2001年1月28日)
新たな圧縮法にょ
今度は高速性重視かつまずまず高圧縮?
とはいえ、8ビット=1ビットは無理だったのでは?という説もあるのじゃが、、、、
G850はアスキーコードの256うち、212は割り当てられているので、、、、
つまり文字コードが割り当てられている部分は2文字を圧縮し(例外として”0”〜”F”の部分は圧縮しない)
それ以外は、生のGPRINTデータのままにょ!

●長所短所
圧縮速度は普通?解凍&圧縮プログラムはまずまず短い
解凍速度は高速な部類すべての文字コードを使う他の圧縮法との組み合わせは基本的に不可
最低圧縮率 100%
最高圧縮率 50%
平均圧縮率 適当計算では61.71%
サンプルデータ圧縮率 70%


REM G850の文字コードに最適化しています
REM まだバグがあるかも、、、
CLS
DIM S$(0)*255
REM S$(0)はGPRINTデータ用の文字変数です
DIM E$(0)*255
REM E$(0)は圧縮されたデータ用の文字変数です
DIM K$(0)*255
REM K$(0)は解凍されたGPRINTデータ用の文字変数です
INPUT S$(0)
REM S$(0)にGPRINTデータが入ります
FOR I=1 TO LEN(S$(0))
B=ASC(MID$(S$(0),I,1))-48
C=ASC(MID$(S$(0),I+1,1))-48
D=(B+(B>9)*7)*16+(C+(C>9)*7)
REM 変数Dに文字コードが入ります
 IF ((D>32 AND D<48) OR 
  (D>57 AND D<65) OR 
  (D>70 AND D<127) OR 
  (D>128 AND D<160) OR 
  (D>160 AND D<248)) AND(I<>LEN(S$(0))) THEN
REM このIF文が圧縮メインです
REM 文字コードで機種依存しているでしょう?
REM 他の文字コードにわりあてる場合はここを変更
E$(0)=E$(0)+CHR$(D)
I=I+1
ELSE
E$(0)=E$(0)+MID$(S$(0),I,1)
REM 無圧縮になるけどコピー
ENDIF
NEXT
PRINT E$(0)
REM ここまでが圧縮プログラム
REM ここからが解凍プログラム
FOR I=1 TO LEN(E$(0))
B=ASC(MID$(E$(0),I,1))
 IF (B>47 AND B<58) OR
   (B>64 AND B<71) THEN
REM 無圧縮データなのか圧縮データなのかを判定
K$(0)=K$(0)+CHR$(B)
ELSE
K$(0)=K$(0)+HEX$(B)
ENDIF
PRINT K$(0)
END
《コメント》
すべての文字コードを使用するので圧縮率はかなり高めになりそうですね。あと「全桁に同じ値を足すフィルタ」を使えばさらに高圧縮できそうです。E500シリーズを使用の場合、通常キーボードから入力出来るコードは20h〜9Eh、A0h〜DEhだけなので注意が必要です。

《注》「全桁に同じ値を足すフィルタ」とは・・・
このプログラムではキー入力入力ができない0xh、1xhのコード(大半が圧縮できない3xh、4xh、Fxhも同様)できないが多発すると圧縮率が下がるという短所があります。従って、全部の桁に一定の値を足しそういう値(0、1、3、4、F)が出にくくすることで平均圧縮率を高めることが可能になります。
 (例) 6を足す場合: Fh+6h=15h → 5h
圧縮を16通りやれば最も良いものが分かるのですが、頻度を調べそれを元に判断すれば、16回も圧縮しなくてもおよその目安を立てることができます。


投稿者 Toshiさん(2001年1月29日)
とりあえず簡単に説明します。
文字コードの中でキー入力できる文字の部分のみをキャラクタに置き換えて圧縮するのですが、使える文字は連続していません。
途中にスペースや入力できない文字もあります。
俺が考えたアルゴリズムではその空いた部分を無理矢理詰めて使います。#はCHR$35ですが、0として扱います。
圧縮するときは値が128未満と128以上にわけた場合で、多い方を圧縮します。多い方を圧縮する場合は#は0ではなくて128となります。それを区別するためにデータのはじめに[!]を入れます。
その後は128未満か128以上で多い方を圧縮していき、連続した同じデータがある場合は[!]を入れてその直後に個数をあらわすア〜ンを使いその後に圧縮するデータを入れます。アを2個とし、ンまでを使い46個分を圧縮できるようにしています。
《コメント》
この方法は上記のNO1さんのと基本的な圧縮アルゴリズムはダブっているのですが、変換するコードがキーから入力できるすべてのコードではないため、ランレングス法などを取り入れ高圧縮に成功しています。
PAC 参加者のページ

ポケコン用の圧縮・解凍プログラムやそのアルゴリズムを掲載しているHPをお持ちの人はぜひご連絡下さい!
ここからリンクを貼ります!!
ということで、グラフィックを多用したゲームや画像処理プログラムを作る人があればこれらの圧縮・解凍規格をぜひ利用してみてください!!より多くの人が使用すれば、それが事実上の標準規格となるでしょう(笑)

現在、準備中・・・(笑)


RETURN *MAIN inserted by FC2 system