2017年9月10日日曜日

妄想:PNG独自チャンク




 PNGのチャンクについて、以下のブログにいろいろ書いてある。

 Canvas から生成した PNG 画像に独自の情報を埋め込む | GREE Engineers' Blog

 GREEの公式なエンジニアブログっぽいので、たぶん信用して良いんであろう。

 曰く、勝手にチャンク作っていいよ、どこに入れてもいいよ、いろいろ情報持てるよ、みたいな感じ。

 「先頭のビットに真偽値が割り当てられてる」(意訳)って書いてあるけど、ASCIIアルファベット領域ってどう頑張っても先頭ビットはいじれないよね。0x20に真偽値を持ってる感じ。ch & 0x20 == 0で、1バイト目が真なら必須データ、2バイト目が真なら公式なチャンク、3バイト目は予約で常に真、4バイト目が真なら画像を加工してもデータを保持するか、らしい。

 4バイト目の使い方はちょっと謎い。JPEGなら撮影日とかカメラの設定情報みたいなモノだろうか。でもPNGが得意とするイラストだとそういうデータって何になるんだろうか。エディタの名前とか?
 一応APNGに使われるチャンクはすべて4バイト目が真で画像加工後も保持されるはずだが、例えばpaint.netで読み込んで加工せずに別名保存すると、アニメーションはされなくなる(バイナリデータは未確認)。まぁ、知らないチャンクは読み捨てるってのは普通の処理な気がするので、データ保持は信用しない方がいいと思う。

 ちなみに1バイト目が真で必須データのはずのPLTE(パレット)は無くても良い。でも8bppIndexedだと必須なので、必須データの扱いになってる。


 僕がほしいデータは、各32bit(96bpp or 128bpp)の画像データなので、IDATに近いチャンク名になる。また32bitというのがわかり易い名前がいい。チャンク名にはビットフィールドの都合上、アルファベットしか使えないから、数字は不可。
 ということで、32bitを表すdouble wordからDを取り出して、Image DATaを縮めてImage DaTaのIDTを使い、それを組み合わせてIDTDとなり、ビットフィールドを反映してidTDとなる。
 32bitでidTDだが、16bitならidTW、64bitならidTQになる。8bitならidTWだけど、これはIDATと同じデータ。いちおう、オクタバイトで128bitのidTOとかもできる。その倍はヘキサバイトでidTHとなる。その倍は頭文字がDになるらしいので32bitと見分けがつかない。まぁ、128bit(384bpp or 512bpp)もあれば充分だろう(フラグ。
 どうでもいいけど、QWORDってMicrosoftの公式な略称だけど、クアッド(4倍)なのかクォーター(4分の1)なのかわかりづらい気がする。まぁ4分の1バイトって何だよという話しで、クアッドになるんだろうけども。
 参考:Double, Triple, Quad, Quint, Six,...の続き。
After Single, you have double, then triple, then quadruple...what comes after? | Yahoo Answers


 ということで、無事チャンク名が決定した。あとはこれらに対応した画像ハンドリングライブラリだが、面倒だなぁ。


 いちおう、「idTW/idTD/idTQ/idTOはIDATおよびfdATの直後に配置し、データの内容は同一とする」みたいなルールを作っておけば、通常の画像ビューアでは静止画として、APNG対応ビューアではアニメとして、idT*対応ソフトではハイレゾデータとして処理できるようになる。
 例えば3次元空間の3次元ベクトルみたいなデータでも、IDATとして最初の1枚を画像化しておき、残りをfdATとして画像化しておけば、APNG対応ソフトではなんとなく色の雰囲気で3次元空間3次元ベクトルを可視化できる。かつ、idTOとかでデータとして保存しておけば、その画像自体を別の処理ソフトに渡す中間データとしても使える。

 と、言うは易しだが、そういうデータを扱えるソフト(ライブラリ)を作るのは大変なんだよなぁ。そもそも標準化しないと中間データとかにならないし。こういうのって、どこにロビイングすれば良いんだ?

 とりあえず、当面は画像データとハイレゾデータを結合して保存するライブラリと、画像データからハイレゾデータを取り出すライブラリを作る感じかな。
 って、結局フィルタリングやハフマン符号圧縮をやらなきゃいけないから、PNGの一番面倒な部分じゃないか。

***

 ここまで書いて思いついたけど、IDATのAを、倍々で次のcharにしていく、とかどうだろうか。16bitならidBT、32bitならidCT、みたいな感じ。この方法なら26843万bitまで対応できる。コレだけありゃどんなデータでも入るだろ。
 むしろAで1byte、Bで2byte、みたいな感じで26バイト208bitまで、とかのほうが現実的な気がする。とはいえ、256bit浮動小数点が10年位前にIEEEに入ってるらしいので、最大208bitだと圧倒的に足りないと思う。やっぱ倍々でcharインクリメントかなぁ。って、さっき自分で書いてたやつは128bitまでじゃないか、というツッコミが聞こえてくるが。。。


 PNG埋め込みデータが普及してきたら、「謎の研究所から送信されているPNG画像を開いたら変哲もない恒星の写真だった。しかしそれにしてはデータはは大容量過ぎて…… 調べていく内に、画像に隠された膨大なデータが解き明かされ、やがて人類の滅亡を掛けた戦いへと(以下略」みたいな感じになるのかな。むねがあつくなるな!!!

0 件のコメント:

コメントを投稿