2.2. サポートされている ioctl 機能

以下に、サポートされている ioctl 機能を書きます。

  **********************************************************************
  #define HSIOCGSCC               0x73e8  /* Get Scanner Capabilities */
  **********************************************************************

(ioctls の MAGIC NUMBERS は、近い将来 ioctl の仕様がより安定になり"メジャー クリーンアップ"が起きた時に、変更されるだろうと思います) これはスキャナのシステム・コールの中で最も重要です。 というのは、スキャナにどのようにアクセスし、何がサポートされているのかという 必要な情報のほとんど全てを提供するからです。

この関数は下記の構造体を返します。

  struct scanner_capabilities {

          int o_scm_mono;	  /* Options for monochrome mode */
          int o_scm_grey;         /* Options for greyscale  mode */
          int o_scm_true;         /* Options for true-color mode */

          int o_xdpi;             /* Options for x resolution */
          int o_ydpi;             /* Options for y resolution */

          int o_bright;           /* Options for brightness */
          struct minmax bright;
          int o_contrast;         /* Options for contrast */
          struct minmax contrast;
          int o_hue;              /* Options for hue */
          struct minmax hue;
          int o_sat;              /* Options for saturation */
          struct minmax sat;

          int phys_width;         /* Width in mm */
          int phys_length;        /* Length in mm */

          int av_options;         /* Number of available Options (0-32) */

  };

頭に 'o_' が付くフィールドは全て "オプション・フィールド" で下記のフラグと組み合わせることができます。(つまり、これはビットフィールド です)

  #define SCC_SOFTSELECT  0x0001  /* オプションをソフトウェアで選択可能 */
  #define SCC_SOFTDETECT  0x0002  /* オプションをソフトウェアで検出可能 */
  #define SCC_HARDSWITCH  0x0004  /* オプションはハードウェアスイッチ   */ 
                                  /* (ユーザの関与が必要) */
  #define SCC_EMULATE     0x0008  /* オプションはドライバでエミュレートされる */
  #define SCC_CANDO       0x000f  /* 上記の何かがセットされたらドライバが */
                                  /* サポートするオプション */

このオプションをどのように使うかの例を示します。

ハードウェアスイッチを使ってスキャナの dpi を選択できて、その設定をドライバ が読み込むことができるなら、このように書きます:

  SCC_SOFTDETECT|SCC_HARDSWITCH

スキャナが1つの dpi 設定に固定されているなら"ハードウェアスイッチ" はありま せんが、ふつうドライバは固定レートを "検出可能" であるというふりをします。 (しかしレートは固定なので本当に検出する必要はありません):

  SCC_SOFTDETECT

スイッチで dpi 設定を選択できるが、ドライバがその設定を読み込む方法が無い (これは実際にはあるはずがないが、世の中には奇妙なハードウェアがあります) という場合は、SCC_HARDSWITCH をセットしなければなりません。

これのアプリケーションにとっての意味は

SCC_SOFTDETECT が指定されていない場合、パラメータの値を知らないのでない限り それを入力するよう促されるべきです。(私は SCC_SOFTSELECT が SCC_SOFTDETECT を 含まないというようなケースを想像できません...) そして値をドライバに教えるため に明示的に SMOD-call によってセットしなければなりません。

SCC_HARDSWITCH は、アプリケーションがユーザにハードウェアを正しく設定するよう に促す必要があることを意味するでしょう。(これが既に行われていることが分かって いる、例えば SOFTDETECT が処理した...場合を除く)

SCC_EMULATE オプションは、これが選択されたとき、ハードウェアが他のモードで あっても、またはこのモードをサポートしていなくてもドライバはこのモードをエミ ュレートするだろうということを意味します。 (例えば、全てのモノクロスキャナは通常、モノクロデータを全ての3 RGB 値に拡張 することによりトゥルーカラーモードをエミュレートします)

phys_* フィールドは、最大スキャンウィンドウの物理的サイズを mm で表します。

minmax-structs は、パラメータの範囲、下記のように 定義された構造体です。

  struct minmax {int min,max;};

av_options フィールドには、この特別なスキャナの 使用可能なオプションの番号が入ります。この値は、 0-32 (inclusive) の範囲で、 HSIOCGOPT コールからのデータの正確な変換が必要です。

  *********************************************************************
  #define HSIOCGOPT               0x73e7  /* Get option descriptions */
  *********************************************************************

このコールは、下記フォーマットの32までのオプションデスクリプタ(これは av_options エントリを予約するには十分でしょう)のフィールド を返します。

  struct scanner_option {int  options;    /* Option availability */
                          char name[20];};

'オプション'フラグは上記の 'o_'の値の一つとして(すなわち、 ハードウェアまたはソフトウェアによってオプションが選択されたら、そしてそれが ソフトで検出可能、あるいはドライバ機能がエミュレートするようなものならば) 扱われます。

オプションとして、ユーザがオプションを 選択/非選択/表示 するための オプション名を示すユーザダイアログを提案します。

これが出来ない、あるいはしたくない(例えば OCR のようなバックグランド処理)場合、 その名前からオプションの意味を引き出すようにするべきです。

互換性を保証するために、デバイスドライバの作成者は、何かの機能の名付けの彼らの アイデアを私に確認することが奨励されます。これは、同じオプションに対して複数の 名前を避けるために、そしてこの文書を私が更新することができるようにするため です。

現在、ドライバによって使われるオプションは1つだけあります。

  オプション: "Dithering"
  機能F     : dithered greyscale モードを on/off する
  ドライバ  : logi32.o
  作者      : becka@hp.rz.uni-duesseldorf.de

  **************************************************************
  #define HSIOCGSCT               0x73e9  /* Get Scanner Type */
  **************************************************************

このコールは、通常の ioctl インタフェースではアクセスできない特殊なスキャナの 特別の機能をアプリケーションが使えるようにするために、スキャナハードウェアを 識別します。 下記の構造体を返します。

  struct scanner_type {
    char manufacturer[20],model[20];
  };

  **********************************************************
  #define HSIOCGMOD               0x73ea  /* Get modeinfo */
  **********************************************************

このコールは、スキャナの現在のモード情報を得ます。

  struct modeinfo_struct {
    int xdpi,ydpi;                /* resolution */
    int sc_mode;
    int depth;                    /* number of different colors (-1) */
    int bpl;                      /* bytes per scanline */
    int left,right;               /* margins in Pixels */
    int top,bottom;               /* margins in Lines */
    int bright;                   /* brightness */
    int contrast;                 /* contrast */
    int hue;                      /* hue */
    int sat;                      /* saturation */
    int options;                  /* enabled options */
  };

sc_mode は、下記のいずれか一つの値をとります。

  #define SCM_UNKNOWN 0           /* Scanner modes : */
  #define SCM_MONO 1              /* 1 BitPerPixel   */
  #define SCM_GREY 2              /* 8 BitsPerPixel  */
  #define SCM_TRUE 3              /* 24 Bit RGB      */

0の場合、スキャナは未定義の状態です。(起きるべきではない) 新しいモードをセットすることもできますが、むしろアボートするべきです...。

スキャンモードは転送されたデータのフォーマットと異なります:

MONO モードはバイナリエンコードされた黒と白の値のビット列を送ります。 即ち、0x83 0x10 を読み込んだ場合、スキャナヘッドの下のパターンは、

  * . . . . . * *  . . . * . . . . ;

つまり、1バイトにつき常に8個のピクセル(画素)があり、一行には常に複数の 8ピクセルがあります。(これは左右を通して再現される筈です...)

グレーモードは、0〜255 までの範囲で測定された灰色の値のバイト列を送ります。 実際のデプスは、depth フィールドを使うことによって 見つけることができますが、たとえ depth が 0 (即ち、 スキャナが実際に黒白モードである)でも、1 ピクセルにつき常に 0 または 255 を 送ります。即ち、1ピクセルにつき1バイトなのです。

トゥルーモードは、バイトで RGB 値を送ります。従って、1 ピクセルに付き3バイト あります。実際のデプスの解像度は 0xrrggbb で、rr はスキャナが識別できる赤色の 番号です。 即ち、24ビットモデルだと 0xffffff とレポートするべきところを 4096色のスキャナ (4ビットの赤、緑、青)では 0x0f0f0f とレポートするわけです。

bpl は、read コールでアプリケーションに送られる bytes per line (1ラインあたりのバイト数) の数です。

Left, right, top, bottom は、マージンをセット します。

Bright, Contrast, Hue, Saturation は、画像のそれぞれの特性値です。

オプションは、選択されたオプションのビットフィールドとしてみなされます。

  **********************************************************
  #define HSIOCSMOD               0x73eb  /* Set modeinfo */
  **********************************************************

このコールは、スキャナモードをセットするために使います。 あなたが与えた構造体はスキャナまたはドライバが扱うことの出来る本当の値を反映 するために"変更される"という点に注意して下さい。

例えば、400dpi(X方向), 600dpi (y方向), フル・デプスで 24ビットモード、 マージンは 5-1003 (方向x),13-4000 (y方向) という条件でスキャンさせたい場合 下記のようにして SMOD をコールします。

  { 400,600,
    SCM_TRUE,
    0xffffff,
    0,/* bpl doesn't matter */
    5,1003,13,4000,
    ...
  }

スキャナが両方の軸で 300dpi しかサポートできない場合、ハードウェアスイッチを 経由して SCM_MONO にセットします。(そしてドライバはデータを変換できない [!]) 8の倍数で10インチまでのページ長の水平方向の境界のみサポートし、 構造体は次のように変更されるでしょう。

  { 300,300,
    SCM_MONO,
    0,
    126,/* Bytes per line filled in */
    0,1008,13,3000
  }

ドライバは TRUE-MOD をエミュレートできる必要があるという点に注意して下さい。 怠けもののソフトウェアがそれをあてにするかもしれませんから...

  *************************************************************************
  #define HSIOCGREG               0x73ec  /* play with strange registers */
  #define HSIOCSREG               0x73ef
  *************************************************************************

これはドライバの開発に使用し、通常はユーザレベルのアプリケーションにはアクセ ス出来ません。このコールの機能は、スキャナからスキャナへ、あるいはドライバか らドライバへ、とは違います。

  *************************************************************************
  #define HSIOCGBUF               0x73f0  /* get/set current buffer size */
  #define HSIOCSBUF               0x73f1
  *************************************************************************

スキャンするラインの現在のバッファサイズを取得/設定します。

  *************************************************************************
  #define HSIOCSSTH               0x73f2  /* get/set select(2) threshold */
  #define HSIOCGSTH               0x73f3
  *************************************************************************

スレッシュホールドの選択値を取得/設定します。

  *********************************************************************
  #define HSIOCGSIB               0x73f4  /* get scanlines in buffer */
  *********************************************************************

これはスキャナの内部バッファの fill-gauge の一種として使われるでしょう。 これは典型的にはデータフローの量をユーザが制御するスキャナ(例えばハンドスキャ ナ)によって使われ、バッファが満杯になったときにユーザにもっと遅くスキャンする よう伝えることが出来るようにします。

Bye, Andreas.