GSC(4)

名称
gsc - ハンディスキャナ用デバイスドライバ

書式
#include <machine/gsc.h>

マイナ番号ビット: uu d g p ...
uu  ユニット gsc0 .. gsc3
d   デバッグ メッセージの記録を選択
g   ビットマップ または グレーマップ 出力を選択
p   raw または portable pnm 出力を選択

解説
gsc キャラクタデバイスドライバは、今のところ Genius GS-4500 ハンディスキャナ のみを扱っています。このドライバはハードウェアが irq を使用して 動作可能であっても、完全に dma 方式で制御を行ないます。 私には割り込み駆動型のデバイスドライバを書くのに十分な ドキュメントも経験もありません。

デバイスは、次の 4 つの異なった 解像度 で動作可能です: 100, 200, 300, 400dpi。デバイスは最上位のビットが左にくるシンプルなビットマップを 生成します。ドライバは Jef Poskanzer による、 よく知られていて適度にシンプルなポータブルビットマップファイル形式 pbm(5) で出力することもできます。 したがってスキャンの結果はその辺にあるどのようなグラフィックパッケージ (一部の名前を挙げるなら xpaint(1), xv(1), xli(1) など) で簡単に処理することができます。 raw モードでは、スキャナは白い紙の上の黒い点を検出するため、 セットされたビットは黒いピクセルを意味します。 逆に、pnm フォーマットはビデオ画面の電子ビームの光度を記述するため、 pbm モードにおいては、セットされたビットは白いピクセルを意味します。

出力されたビットマップの 幅 は与えられた解像度値によって固定されます。しかしながら pnm モードでは、ドライバはいつ 'ファイルの終わり' が検出されたかを知っている はずなので、ビットマップの 高さ は自動で設定されます。 この機能により、 cat を用いてスキャナ出力を pbm ファイルに直接コピーすることができます。 もちろん ドライバを raw モードで使用し dd(1) を用いて似た効果を得ることはできます。

グレーマップ 出力モードはまだドライバに実装されていません。 外部プログラムがこの作業をよりうまくできるかどうかは怪しいですが、 その結果カーネルの大きさが減るかどうかは疑問に思っています。 ただたとえそうであったとしても、中間調ビットマップからグレーマップを 生成するツールを私は知りません。

gsc が処理する ioctl リクエストは以下に列挙されています。 sgsc(1) と呼ばれるユーティリティを使うと、シェルからこれらの リクエストにアクセスできます。

GSC_SRES int
    解像度 の値を設定します。デバイスへの最初の読み込みアクセスの後に、 この呼び出しを行なった場合は、デバイスをクローズして再びオープンしない限り 効果を持ちません。

GSC_GRES int
    現在の解像度を 1 インチあたりのドット数 (dpi) で取得します。

GSC_SRESSSW void
    解像度の値をセレクタスイッチで設定します。ドライバはオープンされているが 触れられていない状態である必要があります。そうでない場合はリクエストは 失敗し、 errno(2) には EBUSY が入ります。

GSC_SWIDTH int
    ビットマップの 幅 を設定します。どのような設定可能な解像度もまさしく一つの幅に対応するので、 実際はこのリクエストは解像度を設定する代わりの手段となります。 設定可能な値は下の表に列挙されています。
    解像度 幅
    100 dpi
        424 ピクセル
    200 dpi
        840 ピクセル
    300 dpi
        1264 ピクセル
    400 dpi
        1648 ピクセル
    ?   1696 ピクセル
    ?   2544 ピクセル
    ?   3648 ピクセル

    上の表に書かれていない値は ioctl 呼び出しに失敗し、 errno(2) には EINVAL が入ります。

    見たとおり、1696 よりも大きな幅の値があります。しかし、このことは スキャナの幅よりも長いラインをスキャンできたり、 もっと高い解像度でスキャンできたりすることを意味するわけではありません。 実際、解像度はハードウェアスイッチのみによって選択されます。 実際の解像度で定義されている以上の長さのラインで、標準のラインの長さを越えた 右部分は定義されていません (通常は白になります)。

GSC_GWIDTH int
    現在のビットマップの幅をピクセル数で取得します。

GSC_SHEIGHT int
    pnm モードでのビットマップの 高さ を設定します。 実際にはこのリクエストは最初の読み込み操作の後、スキャンできるライン数の合計を 制限します。制限値に達した時、読み込みは 0 を返します。 しかし、(呼び出しプロセスの終了時に、明示的あるいは暗黙的に) デバイスがクローズされた時にのみ、電源は切断されます。

GSC_GHEIGHT int
    現在のビットマップの高さを取得します。

GSC_SBLEN int
    DMA 転送に内部で使用するバッファの長さを設定します。 バッファの長さはビットマップのライン数で与えられます。 バッファのサイズは (現在) 0x3000 バイトに制限されているので、 許されるラインの最大数は各ラインの幅によって変化します。 この上限は、現在の値を上書きし errno(2) 変数に ENOMEM を入れてしまう前にチェックされます。 しかし、バッファライン数を選択した後もビットマップの幅を変更することは できるので、バッファライン数が大きすぎることがわかった時は読み込みリクエストは ENOMEM で失敗するかもしれません。一般的にはより良い出力を得るためには、 節約するよりも長いバッファを選択する方が賢いです。

GSC_GBLEN int
    現在のバッファの長さをライン数で取得します。

GSC_SBTIME int
    1 つのバッファを読み込み終わるまでのタイムアウト時間を設定します。 ハンディスキャナはフラットスキャナよりも、人間 / コンピュータ インタフェースのタイムアウト時間が長いので、デフォルトでは 15 秒に なっています。タイムアウト時間後は、読み込み操作は EBUSY で失敗します。 タイムアウトタイマはそれぞれのバッファが読み込まれる度に 新たに開始されるので、長いイメージを早くスキャンできるようになる わけではないことに注意してください。BLEN/BTIME は termios(4) の MIN/TIME と似ています。

GSC_GBTIME int
    現在のバッファのタイムアウト時間を取得します。

パラメータを変更する GSC_SBTIME 以外のすべての ioctl リクエストは、 現在進行中のスキャンプロセスには影響しません。すなわち最初の読み込み リクエスト時の設定がデバイスのオープン中は続きます。影響を及ぼすには デバイスをクローズしてオープンし直す必要があります。したがって、 設定はデバイスをクローズするかオープンするまでリセットされません。

同様に、設定値を読むリクエストは現在進行中のスキャンプロセスで 使われている値を報告しません。スキャンプロセスが必要とする値は 開始時に保存されているので、ioctl リクエストではアクセスできません。

しかし BTIME 値は現在進行中のスキャンにすぐに反映されます。 したがってタイムアウト時間は、例えばユーザがスキャンを開始するまでの 長い時間に設定することができます。 またユーザが停止したら (ほぼ) すぐに反応できるような短い時間に 設定することもできます。 ユーザが慌てることなく一つのバッファを埋められるだけの時間は、最低でも残す 必要があることに注意してください。

pbm と raw のモード選択は、ioctl リクエストではなく、マイナ番号によって行なわれる ことに注意してください。 raw モードでは、選択されたビットマップの高さはなんの効果も持ちません。

関連ファイル

/dev/gsc0
    raw 出力のためのデバイスノードで、マイナ番号は 0 です。

/dev/gsc0d
    raw 出力のためのデバイスノードで、 コンパイル時に GSCDEBUG オプションが設定されていたら、 デバック メッセージを出力します。マイナ番号は 32 です。

/dev/gsc0p
    pbm ファイルフォーマット出力のためのデバイスノードで、マイナ番号は 8 です。

/dev/gsc0pd
    pbm と debug モードのためのデバイスノードで、マイナ番号は 40 です。

使用例

    dd if=/dev/gsc0 of=rawfile bs=(width/8) count=(height)
    cat /dev/gsc0p > pbmfile

診断

GSCDEBUG
    カーネル設定でこの名称を `option' として定義すると、 デバッグビット (すなわち 7 ビット中のビット 5) がセットされたマイナ番号 でドライバにアクセスした場合デバッグ出力を得ることができます。

関連項目
cat(1), dd(1), pbmtopgm(1), pnm(1), sgsc(1), close(2), intro(2), ioctl(2), open(2), read(2), termios(4), pbm(5)

作者
Gunther Schadow <gusw@fub46.zedat.fu-berlin.de>

バグ
たとえスキャナデバイスに、4 つの解像度のうち 1 つを選択できるように なっている小さなスイッチがあったとしても、私にはまだその状態を知る方法が わかっていません。 この問題が解決されない限り、ハードウェアで選択した解像度と一致する保証 のない ioctl(2) で渡した値にドライバは依存します。