blogSimutrans本体改造まわりのお話をつらつらと2018-09-10アドオン画像の減色についてアドオン画像の減色メカニズムについて、コードを読みながら整理したいと思います。本来この話は現在執筆中の『Simutransの本体開発』に載せるつもりでしたが、本の構成上溢れそうなのでこちらで供養するといったものです。Simutransの仕様は数年もすれば様変わりしてしまいますが、いつ何時も原典であるコードの読み方といっしょに分析しておけば時代が下っても参考程度にはなるかなと考え書き残しておきます。減色処理はpngとdatからアドオンをコンパイルするときに行われるのでdescriptor/writer/image_writer.ccを見れば良いことになります。コードはこちらからオンラインで見れます。github.comきちんと流れを追うのはしんどいのでわかりやすいところからつまみ食いしていきましょう。62行目からはじまるpixrgb_to_pixval関数を呼んでいきます。名前の通り8bitなrgb値をSimutrans内部で使われているpixval値に変換する関数です。endian(pix);}前提として、一般的にピクセルの色はアルファ値を含めて32bitで表現されます。頭8bitが透明度、次の8bitがR、その次の8bitがG、一番最後の8bitがBを表します。0x00FFFFFFで分岐しているので、ざっくりALPHA値が含まれてるか否かで処理が分岐していることがわかると思います。ココでは数値はすべて16進数で表記されています(頭に0xがついていたら16進数)。ALPHA値が入っていない処理から見ていきましょう。以下はpixrgb_to_pixval関数の後半部分を抜粋したものです。endian(pix);与えられた色に対してプレイヤーカラーや発光色といった特別色に該当していないかまず検査します。特別色の場合は特別色番号に0x8000を加算した値をpixvalとして返します。pixval値は16bitなので最上位bitが1の場合は特別色であることを表すことがわかります(0x8000は2進数で表すと1000000000000000)。一般色に使えるbitは15bitしかありません。(ちなみに後で分かりますが、最上位bitが1のときは「透過ナシ一般色ではない」というのが真の意味です。)特別色でない場合は、色の32bit表現からr,g,bを取り出した上で、各成分8bit(256段階)から5bit(32段階)にダウンサイジングしています。ビット演算で表現されてるので少々わかりにくいですが、やってることは256階調の色の値を8で割ってあまりは切り捨てです。R成分が87であれば87÷8→10となります。最終的に返されるpixval値は16bitになります。元が32bitなのでデータサイズだけで見れば半分に圧縮されたことになります。つづいてアルファ値が入っている場合を見てみましょう。以下はpixrgb_to_pixval関数の前半部分を抜粋したものです。endian(pix);}やってることは概ね同じで、特別色を検査してから8bitのrgb値を圧縮しています。pixval値で一般色に使えるbit数は15bitなので、ALPHA値がない場合はRGB各成分5bit(32段階)で表現してましたが、今回はALPHA値の表現ですでに5bit(32段階)使っているのでRGBを10bitで表現せねばなりません。そのため、RとBは3bit(8段階)、Gは4bit(4段階)に圧縮されています。計算ルールは同じで、例えば元のRGB値でRが87であれば、87÷(256÷8)→2と計算されます。pixval値は16bitであり、その中で透過ナシ色や特別色と衝突しない表現をする必要があるので、最終的な値の計算式はやや複雑になります。グラデーションの表現が不自然になることですでに悪名高い減色処理ですが、png画像にALPHA値を含めるとさらに激しく減色されるので、必要ない限りはALPHA値を含めることは避けるべきです。いえ大サイズ3Dアドオンが普及するにつれて減色問題による弊害は深刻さを増しているので、次回は減色がなぜ行われているのか、減色問題を解決する手立てはあるのかについて分析する予定です。読者になる検索リンクはてなブログブログをはじめる週刊はてなブログはてなブログPro最新記事OTRPのスケジュール機能を使いこなそうOTRPのバグ報告についてOTRPの跡継ぎをしてくださる方へOTRPの運営方針についてC95日本シムトラ学会大盛況のお礼とBOOTH通販開始のお知らせ月別アーカイブはてなブログをはじめよう!himeshiさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。