REXPaintは、ユーザーインターフェースやレベルのプレハブを設計するために使用されるASCIIアートツールであり、そのデータは特定の.xpファイル形式で保存されます。これらのファイルはgzip圧縮されたバイナリ構造であり、レイヤー化されたアートを再構成するためには、圧縮を解除した後にリトルエンディアンの整数およびカラーバイトのシーケンスを解析するという多段階のデコードプロセスが必要です。

.xpファイルの構造

REXPaint .xpファイルは、マジックナンバー1f8bで識別される標準的なgzipヘッダーで始まります。解凍されると、ファイルはバージョン番号(通常は-1)とレイヤー数から始まるシンプルなリトルエンディアンのレイアウトに従います。各レイヤーは独自の幅と高さによって定義され、その後に一連のセルが続きます。

REXPaintファイル形式の仕様を示す表
REXPaint .xpファイル形式は、ヘッダーとセルデータの構造化されたレイアウトに従います。tylerelton.com

この表は、.xpファイル形式で使用される特定のバイトレイアウトとデータ型を説明しています。

ファイル内の各セルは正確に10バイトを占有し、4バイトの文字インデックスと、前景および背景のための2つの3バイトRGBカラー値で構成されます。これらのセルは列優先順序で構成されており、これは第2列が始まる前に第1列が上から下へと書き込まれることを意味します。

REXPaintファイル形式の構造を示すコードリスト
.xpファイルのレイアウトには、バージョン番号、レイヤー数、およびセルデータが含まれます。tylerelton.com

このコードスニペットは、REXPaintファイル形式の構造的なレイアウトを示しています。

REXPaint セルデータの構成: 文字フィールド 4バイト; 前景色 3バイト; 背景色 3バイト
REXPaint セルデータの構成tylerelton.com

HN Digestによる図表(tylerelton.comの報告数値に基づく)。数値はソースの表記通り。

「すべての値はリトルエンディアンであり、ファイル全体はいくつかの整数と、それに続く長いセルの連続で構成されています。」

— Decoding REXPaint Files in Odin

Odinにおける解析ロジック

Odinプログラミング言語でこれらのファイルをデコードするには、まず`core:compress/gzip`パッケージを使用してファイルをバイトバッファに展開します。次に、カスタムの`Reader`構造体を用いて生のバイト内での現在のオフセットを維持し、バッファオーバーフローをチェックしながら`i32`および`u8`の値を読み取るためのヘルパープロシージャを提供します。

gzipファイルを展開するためのOdinコードスニペット
Odinの実装では、core:compress/gzipパッケージを使用してファイルの展開を処理します。tylerelton.com

このコードは、Odinの圧縮ライブラリを使用したデコードプロセスの最初のステップを示しています。

デコーダーは生のデータを構造体の入れ子構造にマッピングします。`File`構造体は`Layer`構造体のスライスを含み、`Layer`構造体はさらに`Cell`構造体のスライスを含みます。これにより、プログラムはレイヤー化されたアートを、フラットなバイトストリームとしてではなく、構造化されたナビゲート可能なオブジェクトとして表現できるようになります。

メモリ安全性と検証

デコードプロセスには、破損したファイルや悪意のあるファイルによるメモリ枯渇を防ぐためのいくつかの安全チェックが含まれています。レイヤーのメモリを割り当てる前に、コードは予想されるサイズを計算し、バッファ内の残りのバイト数と比較します。また、単一のレイヤーが妥当なサイズを超えないように、`MAX_CELLS_PER_LAYER`の制限を強制します。

Odinの`defer`メカニズムは、複数のレイヤーの解析中にメモリを管理するために使用されます。特定のレイヤーの読み取り中にエラーが発生した場合、`defer if`ブロックによって、その特定のレイヤーのセル用に既に割り当てられたメモリが解放されることが保証されます。これにより、メモリリークを防ぎつつ、ファイルの残りの部分を処理するか、エラーとして報告することが可能になります。

透明度とレンダリングのトレードオフ

REXPaint形式は、特定のカラー値であるホットピンク(255, 0, 255)を通じて透明度を処理します。この形式では、この背景色を持つすべてのセルは透明として扱われることが指定されています。ベースレイヤーには特定のルールが適用されます。上位レイヤーの透明なセルが最下層の透明なセルを露出させる場合、最終的な結果は黒としてレンダリングされます。

デコードロジックはこれらの値を正常に抽出しますが、レンダリングエンジンの透明度ブレンディングの具体的な実装については、デコードプロセスには詳細に記載されていません。デコーダーの主な焦点は、バイナリ形式からOdin環境へのデータ抽出の完全性を確保することにあります。