バイナリデータ (binary data) とは、 図版や動画、音声といったマルチメディアデータのことを指します。 バイナリデータは、必ずテキストデータ (「テキストデータ」 を参照のこと) から参照される形で利用されます。
今のところ EB ライブラリでは、全種類のバイナリデータを取り扱うことが できるわけではありません。 電子ブックで扱えるのは、2 階調のモノクロ図版と、カラー図版 (JPEG) だけ です。 EPWING では、モノクロ図版、カラー図版 (BMP および JPEG) に加えて、 WAVE (PCM) 音声、MPEG 動画を扱うことができます。
ただし、EB ライブラリが提供しているのは、こうしたバイナリデータを CD-ROM 書籍から取得する機能だけです。 表示したり再生したりする機能は用意していませんので、注意して下さい。
アプリケーションは、英和辞書や国語辞書といった辞書だけを対象にするなら、 バイナリデータの表示や再生には対応しなくても支障はありません。 しかし一方では、図鑑や数式の表現にモノクロ図版を使っている数学辞典の ように、対応しないと不便なものもあります。 バイナリデータの表示や再生の機能を実装するかどうかは、アプリケーション の対象辞書をどの範囲までにするのかによって決めると良いでしょう。
以下、この章では種類別にバイナリデータの扱い方について説明します。
バイナリデータの種類毎にデータの取り出し方は微妙に異なりますが (これは データの収録方法が微妙に異なっているからに他なりません)、おおよそ手順 は、次のようなものになります。
eb_binary_set_...()
関数を呼び出して、指定した位置の
バイナリデータをこれから読み込む旨を EB ライブラリに伝える。
eb_read_binary()
で実際にデータを読み込む。
テキストデータと同様に、バイナリデータも副本に属するデータ ですので、副本を選択していないと取得することはできません。 バイナリデータの読み込みには、テキストデータとは別の ファイルディスクリプタが割り当てられます。 したがって、双方を交互に読み込んでも、動作には影響はありません。
2 階調のモノクロ図版は、電子ブック、EPWING 双方に存在し、EB ライブラリ ではどちらも扱うことができます。 (電子ブックに存在する 16 階調のモノクロ図版は、今のところ EB ライブラリ では対応していません。)
モノクロ図版データの内部形式は外字と同じですが、EB ライブラリでは、 1 ピクセルに 1bit を割り当てた BMP 形式に変換してアプリケーションに 渡すようにしています。 したがって、アプリケーションからは、あたかも BMP の図版データが収録 されているようにみえます。
テキストデータ内からは、バイナリデータであるモノクロ図版を参照する形
をとります。
モノクロ図版を取り出すには、この参照情報が必要です。
参照情報の取得は、テキストデータ処理時に、モノクロ図版の開始と終了を
表すエスケープシーケンスへのフック EB_HOOK_BEGIN_MONO_GRAPHIC
と EB_HOOK_END_MONO_GRAPHIC
を用いて行います。
フック EB_HOOK_BEGIN_MONO_GRAPHIC
がフック関数に渡す引数
(argv
) は 4 つあり、このうちの argv[2]
と
argv[3]
が図版の幅と高さ (ピクセル数) を意味します。
また、フック EB_HOOK_END_MONO_GRAPHIC
がフック関数に渡す
引数は 3 つで、argv[1]
と argv[2]
が、
図版データのページ番号とオフセットになります。
モノクロ図版を取得するには、上記のフックから得た図版のページ番号と オフセット、および幅と高さを記憶しておきます。
次に、eb_set_binary_mono_graphic()
を呼び出して、これから
モノクロ図版のデータを取得することを EB ライブラリに伝えます。
eb_set_binary_mono_graphic()
への引数には、
EB_Book
オブジェクトと、先ほど得た図版へのページ番号、
オフセット、幅、高さを渡します。
EB_Book
オブジェクトは、これから取り出そうとしている図版を
収録している副本をあらかじめ選択しておく必要があります。
/*eb_set_binary_mono_graphic()
の関数プロトタイプ */ EB_Error_Code eb_set_binary_mono_graphic(EB_Book *book, EB_Position *position, int width, int height);
電子ブックでは、フック関数に渡される幅と高さの値は 0 になっていますが、
そのまま eb_set_binary_mono_graphic()
に渡します。
(EPWING では 0 を渡してはいけません。)
以上で図版データの取得準備ができたので、データを読み込みます。
これには、eb_read_binary()
を使います。
#define MAX_LENGTH 1000 char bitmap[MAX_LENGTH]; ssize_t bitmap_length; if (eb_read_binary(&book, MAX_LENGTH, bitmap, &bitmap_length) != EB_SUCCESS) { fprintf(stderr, "an error occurs.\n"); return; }
成功すると、読み込んだ図版データが bitmap
に書き込まれ、
何バイト書き込んだのかが bitmap_length
に書き込まれます。
書き込まれるバイト数は、最大で MAX_LENGTH
バイトです。
必ずしも一回の eb_read_binary()
の呼び出しで図版データを
終端まで読み込む必要はなく、関数を繰り返し呼び出せば、前回の続きを
読み込むことができます。
eb_read_binary()
は、図版データの終端まで来るとそれ以上
データは読み込みませんので、eb_read_binary()
が 0 を返した
時点で図版データが終端したことを認識できます。
カラー図版は、電子ブックでは JPEG 形式、EPWING では JPEG と BMP (DIB) 形式のものが使用されています。 EB ライブラリはこれらをすべて扱うことができますが、電子ブックへの対応 は限定的なものになっています。(詳しくは後述します。)
カラー図版のデータを取り出すには、モノクロ図版と同様にテキストデータ からカラー図版への参照情報をフックを通じて取得し、続いて実際に カラー図版のデータを読み込むという手順になります。
eb_set_binary_color_graphic()
を呼び出して、これから
アプリケーションがカラー図版のデータを取得しようとしていることを
EB ライブラリに伝えます。
eb_set_binary_color_graphic()
への引数には、
EB_Book
オブジェクトに加えて、カラー図版のページ番号と
オフセットを渡します。
/*eb_set_binary_color_graphic()
の関数プロトタイプ */ EB_Error_Code eb_set_binary_color_graphic(EB_Book *book, EB_Position *position);
EB_Book
オブジェクトは、これから取り出そうとしている図版を
収録している副本をあらかじめ選択しておきます。
カラー図版のページ番号とオフセットの情報は、カラー図版の開始と終了を表す
エスケープシーケンスへのフックから得ます。
フックは、インライン表示用と非インライン用の 2 種類があり、さらに
それぞれ開始フックが JPEG 用と BMP 用に分かれています。
EB_HOOK_BEGIN_COLOR_BMP
EB_HOOK_BEGIN_COLOR_JPEG
EB_HOOK_END_COLOR_GRAPHIC
EB_HOOK_BEGIN_IN_COLOR_BMP
EB_HOOK_BEGIN_IN_COLOR_JPEG
EB_HOOK_END_IN_COLOR_GRAPHIC
非インライン用の終了フック EB_HOOK_END_GRAPHIC
では、
フック関数に渡す引数の argv[2]
と argv[3]
が、
図版データのページ番号とオフセットになりますので、これを
eb_set_binary_color_graphic()
に渡してやります。
同様に、インライン用の終了フック EB_HOOK_END_IN_GRAPHIC
では、argv[2]
と argv[3]
がページ番号と
オフセットですので、これを渡します。
後は、実際にカラー図版のデータを取り出します。
これには、モノクロ図版と同様に eb_read_binary()
を用います。
使い方はまったく一緒ですので、詳しくは
「モノクロ図版」 を参照してください。
ただし、電子ブックのカラー図版については、データの終了位置が来ても EB ライブラリは読み込みを止めないという制限事項があります。 これは、データの大きさに関する情報が記されていないためで、データの 終端位置は、アプリケーションが JPEG のデータをデコードして割り出すしか ありません。
カラー図版には、画像内の特定の矩形領域に参照先の情報を付け加えたものが あります。 HTML におけるクリッカブル・イメージ (clickable image) とほぼ同じで、その 矩形領域内にマウスポインタがある間にマウスをクリックすると、あらかじめ 決められたリンク先に画面が遷移するという仕掛けです。 リンク先となる矩形領域は、画像一つに対して複数個登録できます。
参照先付きカラー図版の例 ┌────────────────────────┐ │┌ ─ ─ ─ ─ ┐ ┌ ─ ─ ─ ─ ┐│ │ │ ││ 矩形領域1 │ │ 矩形領域2 ││ │ │ │└ ─ ─ ─ ─ ┘ └ ─ ─ ─ ─ ┘│ │ │ │┌ ─ ─ ─ ─ ┐ │ │ │ ││ 矩形領域3 │ 図版 │ │ │ │└ ─ ─ ─ ─ ┘ │ └────────────────────────┘
参照先付きカラー図版の取り扱い方は、通常のカラー図版を拡張した形と なります。通常のカラー図版の場合では、たとえば JPEG の非インライン 画像では、次のような順番でフックが呼び出されます。
EB_HOOK_BEGIN_COLOR_JPEG
(非インライン用 JPEG 開始)
EB_HOOK_END_COLOR_GRAPHIC
(非インライン用 JPEG 終了)
これに対して参照先付きのカラー図版では、この2つのフックの間に、矩形領域 情報に関するフックが挿入されます。
EB_HOOK_BEGIN_COLOR_JPEG
(非インライン用 JPEG 開始)
EB_HOOK_BEGIN_CLICKABLE_AREA
(矩形領域1 開始)
EB_HOOK_END_CLICKABLE_AREA
(矩形領域1 終了)
EB_HOOK_BEGIN_CLICKABLE_AREA
(矩形領域2 開始)
EB_HOOK_END_CLICKABLE_AREA
(矩形領域2 終了)EB_HOOK_END_COLOR_GRAPHIC
(非インライン用 JPEG 終了)
矩形領域に関する具体的な情報は、EB_HOOK_BEGIN_CLICKABLE_AREA
(開始フック) のほうで取得します。
フック関数に渡す引数の argv[1]
と argv[2]
が、
それぞれ矩形領域の開始 x, y 座標を表します。
カラー図版の左上の座標が (0, 0) です。
同様に、argv[3]
と argv[4]
が矩形領域の右方向
への幅と、下方向への高さを表します。
最後の argv[5]
と argv[6]
が参照先のページ番号
とオフセットとなります。
アプリケーションが参照先付きカラー図版に対応しない場合は、矩形領域の 開始情報と終了情報を無視することになります。 これにより、図版は通常の (参照先を持たない) カラー図版とまったく同じく 扱われます。
WAVE (PCM) 形式の音声データは EPWING にだけ存在します。 (代わりに電子ブックには CD-DA 形式の音声データがありますが、EB ライブラリ では対応していません。)
WAVE 形式の音声データを取り出すには、まずテキストデータ中から WAVE 音声
の参照情報を得ます。
参照開始と終了を表すエスケープシーケンスへのフック
EB_HOOK_BEGIN_WAVE
と EB_HOOK_END_WAVE
が
それぞれありますので、これを用います。
フック EB_HOOK_BEGIN_WAVE
がフック関数に渡す引数のうち、
argv[2]
と argv[3]
が音声データの開始位置の
ページ番号とオフセット、argv[4]
と argv[5]
が
終了位置のページ番号とオフセットとなります。
この開始位置と終了位置を関数 eb_set_binary_wave()
に渡して、
その位置にある音声データをこれから取り出すことを EB ライブラリに伝えます。
/*eb_set_binary_wave()
の関数プロトタイプ */ EB_Error_Code eb_set_binary_wave(EB_Book *book, EB_Position *start_position, EB_Position *end_position);
そして後は、実際に音声データを取り出します。
これには、他のバイナリデータと同様に eb_read_binary()
を
用います。
eb_read_binary()
の使い方は、
「モノクロ図版」 を参照のこと を参照してください。
MPEG1 形式の動画データは EPWING にだけ存在します。 動画データは EPWING の CD-ROM の movie というディレクトリの下に、 動画毎に一個のファイルにした形で収められています。
テキストデータ中に存在する、MPEG データの参照開始と終了を表す
エスケープシーケンスへのフック EB_HOOK_BEGIN_MPEG
と
EB_HOOK_END_MPEG
を使用することで、参照先の MPEG の
ファイル名を取得できます。
具体的には、フック EB_HOOK_BEGIN_MPEG
がフック関数に渡す
引数のうち、argv[2]
〜 argv[5]
が合わせて一つ
のファイル名を表すようになっています。
MPEG 動画のデータを得るには、このファイル名を
eb_set_binary_mpeg()
に渡して、そのファイルの動画データを
これから取り出す旨を EB ライブラリに伝えます。
ファイル名は、次のようにして argv + 2
(&argv[2]
でも同じ) を渡します。
if (eb_set_binary_mpeg(&book, argv + 2) != EB_SUCCESS) { fprintf(stderr, "an error occurs.\n"); return; }
後は、実際に動画データを取り出します。
これには、やはり他のバイナリデータと同様に eb_read_binary()
を用います。
eb_read_binary()
の使い方については、
「モノクロ図版」 を参照のこと を参照してください。
この節で説明している関数を使うには、次のようにヘッダファイルを読み込んで 下さい。
#include <eb/binary.h>
EB_Error_Code eb_set_binary_mono_graphic (EB_Book *book, const EB_Position *position, int width, height)
関数 eb_set_binary_mono_graphic()
は、モノクロ図版のデータを
これから取得しようとしていることを EB ライブラリに伝えます。
引数 position は図版の位置、width, height
には図版の幅と高さを渡します。
これらの情報は、図版の参照元であるテキストデータに記載されており、通常は
フック関数を通じて得るようにします。
ただし、電子ブックでは幅と高さの値の情報がテキストデータに記されていない
ため、0 を渡すことになります。
成功すると、関数は EB_SUCCESS
を返します。
失敗すると、原因に応じたエラーコードを返します。
あらかじめ、図版を取り出そうとしている副本を選択しておかなければ
なりません。
book が副本を選択していなければ、EB_ERR_NO_CUR_SUB
を返します。
図版の位置、幅、高さの値が明らかにおかしいと EB ライブラリが判断した
ときは、EB_ERR_NO_SUCH_BINARY
を返します。
この関数は、実際に図版データを読み込むことはしません。
読み込みには、eb_read_binary()
を用います。
モノクロ図版のデータは、1 ピクセルに 1bit を割り当てた BMP 形式になって
います。
EB_Error_Code eb_set_binary_color_graphic (EB_Book *book, const EB_Position *position)
関数 eb_set_binary_color_graphic()
は、EPWING のカラー図版の
データをこれから取得しようとしていることを EB ライブラリに伝えます。
引数 position は図版の位置を渡します。
位置の情報は、図版の参照元であるテキストデータに記載されており、通常は
フック関数を通じて得るようにします。
成功すると、関数は EB_SUCCESS
を返します。
あらかじめ、図版を取り出そうとしている副本を選択しておかなければ
なりません。
book が副本を選択していなければ、EB_ERR_NO_CUR_SUB
を返します。
図版の位置が明らかにおかしいと EB ライブラリが判断したときは、
EB_ERR_NO_SUCH_BINARY
を返します。
この関数は、実際に図版データを読み込むことはしません。
読み込みには、eb_read_binary()
を用います。
カラー図版データは、JPEG か BMP (DIB) のいずかの形式になっています。
EB_Error_Code eb_set_binary_wave (EB_Book *book, const EB_Position *start_position, EB_Position *end_position)
関数 eb_set_binary_wave()
は、WAVE (PCM) 形式の音声のデータ
をこれから取得しようとしていることを EB ライブラリに伝えます。
引数 start_position と end_position には音声データ
の開始位置を渡します。
位置の情報は、音声データの参照元であるテキストデータに記載されており、
通常はフック関数を通じて得るようにします。
成功すると、関数は EB_SUCCESS
を返します。
失敗すると、原因に応じたエラーコードを返します。
あらかじめ、音声データを取り出そうとしている副本を選択しておかなければ
なりません。
book が副本を選択していなければ、EB_ERR_NO_CUR_SUB
を
返します。
音声データの位置が明らかにおかしいと EB ライブラリが判断したときは、
EB_ERR_NO_SUCH_BINARY
を返します。
この関数は、実際に音声データを読み込むことはしません。
読み込みには、eb_read_binary()
を用います。
EB_Error_Code eb_set_binary_mpeg (EB_Book *book, const unsigned int *argv)
関数 eb_set_binary_mpeg()
は、MPEG1 形式の動画のデータを
これから取得しようとしていることを EB ライブラリに伝えます。
引数 argv には動画データのファイル名を渡します。
ただし、このファイル名は文字列ではなく、フック関数
EB_HOOK_BEGIN_MPEG
に渡された引数 argv[2]
〜 argv[5]
の部分を渡します。
つまり、フック関数の引数 argv + 2
を、
eb_set_binary_mpeg()
への引数 argv として
渡します。
成功すると、関数は EB_SUCCESS
を返します。
失敗すると、原因に応じたエラーコードを返します。
あらかじめ、動画データを取り出そうとしている副本を選択しておかなければ
なりません。
book が副本を選択していなければ、EB_ERR_NO_CUR_SUB
を返します。
存在しない動画ファイル名を EB ライブラリが判断したときは、
EB_ERR_NO_SUCH_BINARY
を返します。
成功すると、関数は EB_SUCCESS
を返します。
この関数は、実際に動画データを読み込むことはしません。
読み込みには、eb_read_binary()
を用います。
EB_Error_Code eb_read_binary (EB_Book *book, size_t binary_max_length, char *binary, ssize_t *binary_length)
関数 eb_read_binary()
は、バイナリデータを読み込みます。
読み込もうとしているバイナリデータは、事前に
eb_set_binary_mono_graphic()
eb_set_binary_color_graphic()
eb_set_binary_wave()
eb_set_binary_mpeg()
のいずれかの関数で、EB ライブラリに通知しておく必要があります。
読み込んだデータは引数 binary の指す先の領域に書き込まれます。 また、このとき書き込まれたバイト数は、binary_length の指す 先の領域にセットされます。 ただし、書き込まれるバイト数は、最長でも引数 binary_max_length に指定した値までとなります。
この関数は、特に読み込んだデータの終端にナル文字を付加するような事は しません。 読み込まれるデータもバイナリ形式なので、途中にナル文字が出現する事も あります。
この関数を一回呼び出しだだけで、バイナリデータ全体を一気に取得する 必要はありません。 繰り返し呼び出せば、前回の続きからデータが読み込まれます。
ただし、以下に挙げた関数を呼び出すと、バイナリデータの読み込みに関する 状態記録がリセットされますので、それ以上の読み込みはできなくなります。
eb_set_subbook()
eb_unset_subbook()
eb_load_all_subbooks()
eb_bind()
eb_finalize_book()
eb_set_binary_mono_graphic()
eb_set_binary_color_graphic()
eb_set_binary_wave()
eb_set_binary_mpeg()
eb_read_binary()
を繰り返し呼んだ場合、バイナリデータは
その都度 binary の先頭から書き込まれ、*binary_length
の値も、その回の eb_read_binary()
の呼び出しで書き込まれた
バイト数になります。
データの終端に来ると、それ以上この関数を呼んでも関数は binary
には何も書き込まず、*binary_length に 0 を書き込み、
EB_SUCCESS
を返します。
成功すると、この関数は EB_SUCCESS
を返します。
失敗すると、binary_length が指す領域に -1 を書き込み、原因を
示すエラーコードを返します。
この場合、バイナリデータの読み込み状態の記録がリセットされますので、
データの続きを読み込むことはできなくなります。
あらかじめ、book はいずれかの副本を選択していなくては
なりません。
選択していない場合は、EB_ERR_NO_CUR_SUB
を返します。
また、冒頭に挙げた関数の呼び出しが成功していない状態でこの関数を呼ぶと、
EB_ERR_NO_CUR_BINARY
を返します。
EB_Error_Code eb_compose_movie_file_name (const unsigned int *argv, char *composed_file_name)
関数 eb_compose_movie_file_name()
は、動画データのファイル名
を通常の文字列に変換します。
EB ライブラリでは、動画データのファイル名はフック関数
EB_HOOK_BEGIN_MPEG
に渡された 4 つの int 型引数
(argv[2]
〜 argv[5]
) によって表現されます。
動画データを読み込む際は、これをそのまま eb_set_binary_mpeg()
に渡せば良いのですが、ファイル名を通常の文字列で得たい場合は、この関数を
用います。
たとえば、個々の動画に一意の ID のようなものを振りたい場合は、ファイル
名を ID として使うと良いかも知れません。
なお、この関数で変換して得られるファイル名にはパスが含まれていません。
フック関数の引数 argv + 2
をこの関数への引数 argv
として渡すと、composed_file_name が指す先の領域に、文字列形式
に変換されたファイル名が格納されます。
ファイル名は最長で EB_MAX_DIRECTORY_NAME_LENGTH
(= 8) バイト
になります。
この長さには終端のナル文字の分を含んでいませんので、格納領域にはもう
1 バイト余裕が要ります。
なお、格納されたファイル名は、実際に存在するファイル名とは若干異なって いる可能性があります。 たとえば、英字の大文字と小文字、接尾子の有無などの違いがこれに当たります。 この関数は、あくまで文字列に機械的に変換するだけなので、ファイルが実在 するかどうかのチェックはしません。
成功すると、関数は EB_SUCCESS
を返します。
EB_Error_Code eb_compose_movie_path_name (EB_Book *book, const unsigned int *argv, char *composed_path_name)
関数 eb_compose_movie_path_name()
は、動画データのファイル名
を通常の文字列に変換します。
働きは、前述の関数 eb_compose_movie_file_name()
に良く
似ていますが、eb_compose_movie_path_name()
が返すファイル名
は、絶対パスの形式になっている点が異なります。
また、eb_compose_movie_path_name()
では、ファイル名が実在
するかどうかのチェックを行うという点も、大きな違いです。
ファイル名を文字列に変換した上で、英字の大文字と小文字の違いや接尾子の
有無は、実在のファイルに合わせて調整したものを返します。
したがって、パスを除いた部分で比較しても、
eb_compose_movie_file_name()
が返すファイル名とは必ずしも
一致しません。
引数 book
は、動画ファイルを収録している副本を選択して
おかなければなりません。
副本を選択していなければ、EB_ERR_NO_CUR_SUB
を返します。
引数 argv
の意味は、eb_compose_movie_file_name()
と同じです。
ファイル名の変換が成功すると、関数は composed_path_name が
指す先の領域に、文字列形式に変換された動画ファイル名を格納し、
EB_SUCCESS
を返します。
ファイル名は最長で EB_MAX_PATH_LENGTH
バイトになります。
この長さには終端のナル文字の分を含んでいませんので、格納領域にはもう
1 バイト余裕が要ります。
ファイル名が実在しないと、EB_ERR_BAD_FILE_NAME
を返します。
EB_Error_Code eb_decompose_movie_file_name (unsigned int *argv, const char *composed_file_name)
関数 eb_compose_movie_file_name()
は、
eb_compose_movie_file_name()
とちょうど逆の働きをします。
つまり、通常の文字列に変換された動画データのファイル名
composed_file_name を、4 つの int 型引数 argv に
戻します。
したがって、argv の指す領域は、少なくとも int 型の値を 4 つ
格納できる大きさが必要です。
成功すると、関数は EB_SUCCESS
を返します。