SPE to JPG converter

Princeton Instruments (Roper Scientific)のCCDカメラ(の制御ソフト)WinViewが吐く画像形式であるSPEファイルをJPEGファイルに変換するプログラムをJavaで書いてみた.Javaには,画像バッファの(i, j)要素を埋めれば後は勝手にJPEGに変換してくれるライブラリが付いてるので.
SPEファイルの仕様はユーザー・マニュアルのAppendix Bに載ってるんだが*1,データの配列の要素の型に関する情報が,仕様だと "0 = float, 1 = long, 2 = short, 3 = unsigned short" となってるのに,手元のファイルでは5になってて途方に暮れてしまった.生データを眺めてみるとどうやらIEEE 754 doubleのようだったのでそれで変換したらできた*2.多分この辺はカメラの設定によって変わるんだろうけど(だから他の選択肢は考慮せず我々の使い方で必要なdouble型で決め打ち),仕様に外れたデータを普通に書き出せるってどうなのよ...
(追記: 仕様書をよく読んだら古いヴァージョンのヘッダの説明に "0 -> float, 1 -> long integer, 2 -> integer, 3 -> unsigned integer, 4 -> String/char, 5 -> double (8 bytes) Not implemented, 6 -> byte, 7 -> unsigned byte" とあった.だが次のヴァージョンでは4以下が消えている.私が最初に見てたのはさらにその次のヴァージョン.お前こんなんで "Data files created under previous versions of WinView/WinSpec _can still be read correctly._" とか書くなよ...)

そう言えば擬似カラー (pseudo color) ってどうやって作るのが標準的なんだろうか.WinViewの擬似カラーのアルゴリズムが分からなかったのだが(単純にHSBのhueだけを変えているのとは明らかに違う),適当に似せて

float h = 2f / 3 - (float) (Math.min(5d / 6 * gray, 2d / 3));
float s = (float) (Math.min(15 * (gray - 1) * (gray - 1.1), 1));
float b = (float) (0.4 + 3 * Math.min(gray, 0.2));

としてみた.
gray = 0.0

gray = 1.0

*1:簡単に書くと,先頭から4100バイトがヘッダでその後が実際の画像データ.(以後,0-originで)ヘッダの42バイト目から2バイトがx方向の幅,656バイト目から2バイトがy方向の幅,108バイト目が上で愚痴った型情報,1446バイト目から4バイトがフレーム数.

*2:Javaにはunsignedな整数型がないのでビット演算がやり辛い.byteデータをシフトしてbitwise orするときも勝手に符号拡張されるのでまず0xffでマスクする必要があったりとか.