2013-03-27

Jpeg2000 の画像ファイルを読んでみる

諸般の事情で JPEG2000 圧縮されたデータを読まなければいけないことになった。

JPEG というと画像だろうと思われるかもしれないが、GRIB第2版なんかでも使われている。ただ、Data template 7.40 を見ると

Octet No. 6-nn: JPEG 2000 code stream as described in Part 1 of the JPEG
2000 (ISO/IEC 15444–1:2000)

とだけあって、ぜんぜんブラックボックス化している。で、ISO規格票
http://www.iso.org/iso/catalogue_detail.htm?csnumber=37674
が 238 フランもするので、なかなか手が届かない。しかしこの規格は ITU-T T.800
でもあるのだ… http://www.itu.int/rec/T-REC-T.800/en と見に行くと、なんとISOが話をつけていて特別にお買い求めくださいとかなっている。

いろんな人がやってきて、jasperのリファレンスマニュアル読んで関数呼び出すだけでいいんだよ、大人になろうよというのだが、規格票に照らして正誤を確認できないプログラミングなんかナンセンスであって、まあ、なんかググると
http://www.jpeg.org/public/fcd15444-1.pdf とか怪しげなものが引っかかるが、けっこうこいつは古くてぜんぜんだめである。かかる非オープン標準なんぞ断固として相手にしないと忌み嫌ってきたのだが、まあ、いろいろあって、そうもいかなくなってきたという浮世の悲しさ。すべて貧乏が悪いのよ。

なお、私の説明は雑なのでお読みになった諸兄にいかなる損害を生じても一切関知しない。繰り返すが、私と同程度のパラノイアであったなら、今すぐISO に238フランを払ってすぐにダウンロードしてほ
しい。なお、買ったのに意味不明だったと言われても関知しない。投資は自己責任でお願いいたします。

さて、規格票を概観すると本文と Annex A から Annex L からなる。本文は超ざっくりいって用語の定義である。で、 .jp2 ファイルフォーマットの説明は Annex I である。本当は
コーデックの吐いた code stream だけに興味があるのだけど、例を得るためにはファイルを用いるので、まず確認しておこう。

ファイルはボックスの羅列である(ボックスの中にボックス列が入ることもある)。ボックスは可変長のデータ構造で先頭4オクテットがビッグエンディアンのオクテット数で、ボックス長にはこの4を含む。Fortranのシーケンシャルファイルとは違って後ろにボックス長はつかない。ファイルの最後のボックスについてだけ長さ不明を示す0が許される。シークしないで書けるのはすばらしい。なかなかいいヒントをもらった。
ボックス長の次にはボックス種別を指示する4オクテットが続いていてこれは
printable な文字から選ばれている。
ボックス長が4ギガバイトを超える場合は、ダミーの1を埋めて、ボックス種別のあとに8オクテットで書く。

まるでXMLのように種別ごとに必須性、反復可能性、内部にボックス列を含むか否かがきまっていて、大略こうである。

jp, ftyp, jp2h{ ihdr bpcc? colr+ pclr? cmap? cdef? res{ resc? resd? }?},
jp2c+ & jp2i? & xml* & uuid* & uinf{ ulst? url? }*

で、細かい説明をすっとばして、8ビットグレイスケールのファイル先頭はこんなふうになる。

00000000  00 00 00 0C 6A 50 20 20 - 0D 0A 87 0A 00 00 00 14 ....jP  ........
00000010  66 74 79 70 6A 70 32 20 - 00 00 00 00 6A 70 32 20 ftypjp2 ....jp2
00000020  00 00 00 2D 6A 70 32 68 - 00 00 00 16 69 68 64 72 ...-jp2h....ihdr
00000030  00 00 00 BF 00 00 01 40 - 00 01 07 07 00 00 00 00 .......@........
00000040  00 0F 63 6F 6C 72 01 00 - 00 00 00 00 11 00 00 00 ..colr..........
00000050  00 6A 70 32 63          -                         .jp2c

[0x30-0x33] = 0xBF が高さ、 [0x34-0x37] = 0x140 が幅、[0x3a] = 07 が深さから1を減じたものである。あとは固定値か、違っていればグレイスケールではないかへんてこなメタデータが存在することを示している。

その次のオクテットからが本題である。が、疲れたので今回はここまで。また次回お楽しみに(ないかもしれません)。

0 件のコメント:

コメントを投稿