miauのブログ

はてなダイアリー「miauの避難所」をはてなブログに移行しました

ScanSnap S1500 のスキャン時の動作など

2010年の5月に ScanSnap S1500 を買っていたのですが、fi-7160 を買って ScanSnap S1500 を手放すことにしたので、ノウハウを軽くまとめておこうかと。

まずはスキャン時の動作やら、各種設定によって画像ファイルの属性がどのように変わるかを書いておきます。S1500 を持っている人であっても、ほとんどの人が気にしないくらい細かい話なので、気をつけてください。


以下 Windows 7/8 あたりでの検証結果です。

ScanSnap Manager のプロセス構成

以下のような構成みたいです。

  PfuSsMon.exe             -> ScanSnap Manager の GUI。スキャン時の画像処理もこのプロセス。
    PfuSsOrg.exe
      PfuSsOrgPDF2JPEG.exe
    PfuSsQuickMenu.exe     -> 何に保存するか聞いてくるウィンドウ
      Scan2Folder.exe      ->「指定したフォルダに保存」時に起動するウィンドウ
                              このタイミングでは 【イメージの保存先】\yyyymmddhhmiss.pdf を参照している

スキャンに関わるほとんどの処理は PfuSsMon.exe が行っているので、このプロセスだけ追えば大丈夫そうです。

スキャン時の動作

ScanSnap S1500 でスキャンを行った場合の PfuSsMon.exe の動作を追ってみました。

(1) 設定の読み込み?

深くは追っていませんが、%APPDATAR\PFU\ScanSnap\*.cfg がいろいろと読み込まれます。

(2) カラープロファイルの読み込み

OpenColorProfile で以下のカラープロファイルが読み込まれます。

  • %SYSTEMROOT%\system32\spool\drivers\color\ScanSnap S1500.icm
  • %SYSTEMROOT%\system32\spool\drivers\color\sRGB Color Space Profile.icm
(3) RAW画像の出力

まず %TEMP%\SSRawData に、ScanSnap0.raw(表面)、ScanSnap1.raw(裏面)のように一面に対して 1 ファイルずつ画像が出力されます。RAW と言いつつ中身は JPEG ファイルなのですが、クロッピング(トリミング)も行われていない、かなり生データに近いファイルです。

(その辺にあった半券を取り込んだもの。意図的に傾けて取り込んだもので、普通はこんなに傾きません。)

JpegAnalyzer Plus で見ると、以下のような情報が出ました。(「★dpi」を付加した部分は、dpi 設定によって変わる部分です。また、上記の画像に対応する情報ではありません。)

Address  Length Message
00000000 ****** SOI  :Start Of Image ******
00000002 [0010] APP0 :JPEG File Interchange Format Ver 1.2 (JFIF)
                 密度 600:600 dots/inch ★dpi 600:600, 300:300, 200:200, 150:150
00000014 [0084] DQT  :Define Quantization Table
                 00000018 QT0-8bit LEADTOOLS色差 画質015 ★dpi 600,300,200:015, 150:002
                 00000059 QT1-8bit LEADTOOLS輝度 画質015 ★dpi 600,300,200:015, 150:002
0000009A [0004] DRI  :Define Restart Interval (MCU blocks=653) ★dpi 600:653, 300:326, 200:217, 150:163
000000A0 [0011] SOF0 :Start Of Frame 0 - Baseline DCT
                 5224[0] x 2816[0] pixel - 24bit color (YCbCr 4:4:4)
                 ComponentID-01 Y  1x1 QT0
                 ComponentID-02 Cb 1x1 QT1
                 ComponentID-03 Cr 1x1 QT1
000000B3 [01A2] DHT  :Define Huffman Table 【汎用ハフマンテーブル】
                 000000B7 HT0-DC   汎用輝度HT-DC
                 000000D4 HT0-AC   汎用輝度HT-AC
                 00000187 HT1-DC   汎用色差HT-DC
                 000001A4 HT1-AC   汎用色差HT-AC
00000257 [000C] SOS  :Start Of Scan 0-63[00]
                 HT Selector[DC/AC] Y[0/0] Cb[1/1] Cr[1/1]
00000265 ****** Image Data ******
                 Data Size 3,706,553 bytes
0038911E ****** EOI  :End Of Image   ******

なお、カラーモードがグレースケールでも白黒であっても、カラー画像として保存されます。白黒は「1200 dpi 相当」とは書かれていますが、実際 600 dpi のデータが元になっているので、ちょっと引っかかります。(ベイヤーパターンの CCD ならそうなる表記されるのもわかるのですが、スキャナーの CCD はリニアイメージセンサだと思いますし・・・。)

片面読み取り時も 2 枚出力されますが、裏面の画像は以降の処理では使用していないようです。ということは、裏側の画像情報を使った裏写り除去の処理は行っていないようです。

次の紙を読み込むと ScanSnap2.raw、ScanSnap3.raw のように連番で続いていきますが、継続読み取り時は 0 にリセットされるようです。

後続の処理に進むとすぐ消されてしまうファイルですが、このファイルを保存したり差し換えたりする方法については後日また書こうと思います。(20140509 追記: 書きました。ScanSnapHelper(ScanSnap Manager 補助ツール)を作ってみた

(4) カラープロファイルによる色変換

最込に読み込んだカラープロファイルを利用して(CreateMultiProfileTransformTranslateBitmapBits を使って)色変換がかかります。

(5) %TEMP%\JpgTmp 等への出力

変換&切り出しが終わった画像が以下のファイルに出力されます。

  • %TEMP%\JpgTmp\Spool_For_ScanSnap*.jpg ※PDF 出力時のみ
    • 最終出力画像を作るための中間ファイル
    • この総サイズをチェックすれば「処理できる総ファイルサイズの上限(2GB)に達しました。」エラーを事前に防げる
  • 【イメージの保存先】\YYYYMMDDHHMISS.jpg ※JPEG 出力時のみ
    • 最終出力ファイル
  • %TEMP%\ImfrTemp\ImfrImg*.jpg
    • プレビュー用の画像?直近の二枚だけ残る
  • %TEMP%\BizCardTemp\sstmp*.jpg
    • 名前からすると名刺用の画像?JpgTmp と同じくらいのサイズだけど見開き画像が入ってない

この時点でクロッピングや傾き補正も行われていて、このように画像になっています。

RAW 画像と見比べると、色合いが変わっているのもわかると思います。確かに RAW 画像はやや青が強いのですが、ちょっと補正が効きすぎて赤〜黄色がかってしまっているように感じますね。

「傾き補正も行われ〜」と書きましたが、実は例外があります。画質がエクセレント(600dpi、白黒は1200dpi)で PDF で保存する場合は傾き補正は行われず、クロッピングのみが行われた以下のような画像が出力されます。(理由については後述)

カラーの場合、JpegAnalyzer Plus で見るとこんな情報が出ました。

00000000 ****** SOI  :Start Of Image ******
00000002 [0010] APP0 :JPEG File Interchange Format Ver 1.0 (JFIF)
                 密度 600:600 dots/inch ★dpi 600:600, 300:300, 200:200, 150:150
00000014 [001D] COM  :Comment
                 PFU ScanSnap Manager #S1500
00000033 [0043] DQT  :Define Quantization Table
                 00000037 QT0-8bit IJG輝度 画質95 ★圧縮率 1:95, 2:80, 3:67, 4:45, 5:15
00000078 [0043] DQT  :Define Quantization Table
                 0000007C QT1-8bit IJG色差 画質95 ★圧縮率 1:95, 2:80, 3:67, 4:45, 5:15
000000BD [01A2] DHT  :Define Huffman Table 【汎用ハフマンテーブル】
                 000000C1 HT0-DC   汎用輝度HT-DC
                 000000DE HT0-AC   汎用輝度HT-AC
                 00000191 HT1-DC   汎用色差HT-DC
                 000001AE HT1-AC   汎用色差HT-AC
00000261 [0011] SOF0 :Start Of Frame 0 - Baseline DCT
                 3552[0] x 2459[5] pixel - 24bit color (YCbCr 4:2:0)
                 ComponentID-00 Y  2x2 QT0
                 ComponentID-01 Cb 1x1 QT1
                 ComponentID-02 Cr 1x1 QT1
00000274 [000C] SOS  :Start Of Scan 0-63[00]
                 HT Selector[DC/AC] Y[0/0] Cb[1/1] Cr[1/1]
00000282 ****** Image Data ******
                 Data Size 3,610,577 bytes
00371A53 ****** EOI  :End Of Image   ******

RAW データと比べると、サンプリング比が 4:4:4 から 4:2:0 に変わっており、間引きが入っています。圧縮率の設定によって画質が変わっています。それがどういう意味を持つかは、このページを参照ということで。

グレースケールの場合もカラーとほぼ同じ情報でしたが、以下の点が変わっていました。

000000BD [00D2] DHT  :Define Huffman Table
                 000000C1 HT0-DC   汎用輝度HT-DC
                 000000DE HT0-AC   汎用輝度HT-AC
00000191 [000B] SOF0 :Start Of Frame 0 - Baseline DCT
                 3542[2] x 2461[3] pixel - 8bit grey scaled (Mono)
                 ComponentID-00 Y  1x1 QT0
0000019E [0008] SOS  :Start Of Scan 0-63[00]
                 HT Selector[DC/AC] Y[0/0]

白黒だとこうでした。TIFF ですね。

ヘッダのない TIFF CCITT T.6
FAX4(CCITT T.6)

00094F98-00095045 0th IFD Tag-14   Next IFD 00000000 (Value-00000000)
00094F9A 0100 画像の幅                      7088
00094FA6 0101 画像の高さ                    4912
00094FB2 0102 画像ビットの深さ              1 (bit)
00094FBE 0115 コンポーネント数              1
00094FCA 0116 ストリップ中のライン数        4,912
00094FD6 0111 画像データへのポインタ        00000008 (Value-00000008)
00094FE2 0117 ストリップのデータ量          610,192 bytes
00094FEE 0103 圧縮種類                      T.6MMR圧縮(Group4)
00094FFA 0106 画素構成                      グレイスケール(白=0)
00095006 010A Fill Order                    MSB to LSB
00095012 011C 画像データの並び              点順次 Chunky format
0009501E 011A 画像の幅の解像度              72 
0009502A 011B 画像の高さの解像度            72 
00095036 0128 画像の幅と高さの解像度の単位  インチ(dpi)
(6) PDF 生成の中間処理

ファイル形式が PDF の場合、以下のような処理が行われます。

  • 【イメージの保存先】\YYYYMMDDHHMISS.pd~ に空ページの PDF ファイルを出力
  • %TEMP%\SSMon\【32桁の16進数】_【5桁の連番】.tmp として JPEG ファイルを出力
    • ただし先頭に 80 bytes 謎データが入っている
  • %Temp%\PFUSSMON_SPL.LST にファイル名書き出し
  • %TEMP%\SSMon\【32桁の16進数】_【5桁の連番】_Compressed.pdf.tmp として単一ページの PDF に変換
    • AdobeScanLibrary.dll や PDFL70.dll を使って処理(処理中で %Temp%\Acr【32桁の16進数】.tmp を使用)
  • JpgTmp\SPOOL【5桁の連番】.ini には都度画像の情報を出力
    • その後の処理では使われてないっぽい

SPOOL*.ini についてはフォーマットも軽く調べていたので書いておきます。

[File]
FilePath=C:\Users\****\AppData\Local\Temp\JpgTmp\Spool_For_ScanSnap001.jpg
BuffSize=561818
DataType=2
InCompression=3  ★color,gray:3, binary:1
Width=3551
Height=2455
Color=24         ★color:24, gray:8, binary:1
Resolution=600   ★binary は 1200 等
OutCompression=3 ★color,gray:3, binary:1
SegmentMono=1
RotationAngle=0  →270 だったら左に 90 度回転してくれる。
DeskewAngle=-20  →傾きっぽい。強制回転された場合は 0 になる。
GBJPG=1          ★color,gray:1, binary:0
Flag=1

ちなみにファイル形式が JPEG の場合はこのあたりの処理は行われず、%Temp%\PFUSSMON_FCN.INI にファイルの一覧が出力されるだけです。

(7) ファイルの保存

ファイル形式が PDF の場合は、

  • 【イメージの保存先】\aa【32桁の16進数】 として YYYYMMDDHHMISS.pdf~ を退避?(でも使ってない気がする)
  • *Compressed.pdf.tmp を結合して YYYYMMDDHHMISS.pd~ に格納
  • YYYYMMDDHHMISS.pd~ を YYYYMMDDHHMISS.pdf にリネーム

といった感じで最終的な PDF が出来上がります。

ファイル形式が JPEG の場合は、すでに保存済みなので特に何も行われません。

ファイル名をつけたりする部分は後続の exe に処理させているようです。

画質がエクセレント PDF 保存する場合の動作

画質がエクセレント(600dpi、白黒は1200dpi)で PDF 保存する設定だった場合、傾いてスキャンされた画像は、PDF 中に逆向きに傾けて埋め込むことで補正を行っているようです。

PDF では変換マトリックスを定義できて、これを使えば画像その他を引き伸ばしたり傾けたりして表示できます。


PDF Reference second edition【PDF】 の 129 ページあたりを切り貼りして引用)

この変換マトリックスを変える命令が cm なのですが、傾けて保存される場合は

212.3054962 -13.8981018 26.2519531 401.0214996 -12.8987274 7.3783112 cm

のように第 2、3 オペランドが 0 以外になっていることが確認できます。

PDF ビューアで開くと、傾きが正されているのがわかります。白い部分が目立ちますが、普通はこんなに傾きませんので技術書を取り込んでいる限りでは気になりませんでした。

何が嬉しいかというと、より元画像に近い(回転処理による画像劣化がない)情報を保持しながら、通常の使用ではその傾きが気にならない動作になっていることですね。

調査のためのツールとか

もっと詳しく調べたい方もいるでしょうし、後継機種である ScanSnap iX500 で動作が変わっているかもしれませんので、このあたりの動作を調べるのに役立つツールを紹介しておきます。

Process Monitor

ファイルやレジストリのアクセスを表示するプログラムです。Process Explorer や TCPView も含めて必須のツールなので、Sysinternals Suite でまとめて入れてます。

API Monitor v2

API の呼び出しをトレースするプログラムです。ファイルアクセスよりも上の層の情報を知りたいときや、API hook のあたりをつけるのに使います。

ただし、環境によっては API 呼び出しがうまく拾えないケースもあるようですので、そういうものだと思って使ったほうがいいと思います。.icm に対する CreateFileW の呼び出しが、ある環境(Win8.1 64 bit)では拾えないのに、別の環境(Win7 32 bit)なら拾える、なんとことがありました。(スキャナの設定が悪いのかと思って数時間ハマってました。)

HHD USB Monitor

USB の生データを覗けるツールで、ライセンスは $64.99 ですが 14 日間試用できます。
Usb Sniffer for WindowsWindows 7 以降で使えないし、Bus Hound のフリー版はデータサイズに制限があって今回の用途には向かない&価格が $799 と高いので、こちらを使ってデータを覗いたりしてました。プロトコルが公開されてるわけでもなく、USB 通信の勝手がわかってるわけでもないので、眺めただけで終わりましたが・・・。

PDFtk

PDF の内容は(元々圧縮されている JPEGTIFF 以外の箇所は)圧縮されているので、それを解除したい場合なんかに使います。
xxx.pdf の圧縮を解除して xxx_uncompressed.pdf として出力するコマンドは下記のとおりです。

pdftk xxx.pdf output xxx_uncompressed.pdf uncompress