前々回にPhotoshopのJPEG保存での品質段階とサブサンプリングや量子化テーブルについてちらっとふれた。
アレは以下のExcel VBAプログラムで読み取らせたものです。
JPEGファイルは16進FFに1ByteのIDコードを付けたマーカから始まるデータセグメントに分割されており、
サブサンプリング指定や量子化テーブル、圧縮方式、ハフマンコード変換表等の画像再生に必要な情報が記述されている。
ここを読み取れば画像品質に関するパラメータをどのように指定して作られたJPEGファイルかが判る。
(圧縮保存品質とは関係ないが、デジカメの撮影パラメータを記述したExifデータはAPP1と呼ばれるセグメント内に記述されてる)
"B1”セルに対象ファイルをフルパスで記述して実行すると、
VBAプログラムの実行結果表示は以下のようになり(一部はプログラム外で書き加えている)、
サブサンプリングはY,Cb,CrのV_SampとH_Sampの値から判断する。
Y,Cb,Crがどの量子化テーブルを使用しているかはQ_Table番号で判断し、その内容はQT#で表示する。
(量子化テーブルの値はファイル上のジグザグ・スキャン順からDCTのスペクトル順に直してある)
VBAプログラム:
'構造体定義
Private Type Seg_Mark
S_ID(1) As Byte '1Byte x 2
S_Size(1) As Byte '1Byte x 2
End Type
Private Type APP_Mark
APP_ID As String * 5 '5 Letters
Ver_H As Byte '1Byte
Ver_L As Byte '1Byte
End Type
Private Type YCbCr
YCC_ID As Byte
HV_Samp As Byte
Q_Tbl As Byte
End Type
Private Type SOF_Mark '(0xFFCn)
PL As Byte '???
Y_Pix(1) As Byte '1Byte x 2
X_Pix(1) As Byte '1Byte x 2
FR As Byte '???
YCC(2) As YCbCr
End Type
'-----------------------------------------
Sub Jpeg_P_Read()
'変数宣言
Dim S_Mark As Seg_Mark
Dim APPn As APP_Mark
Dim SOFn As SOF_Mark
Dim Pt As Long
Dim QT As Byte
Dim Mark_ID As Byte
Dim Mark_Size As Long
Dim XP As Long
Dim YP As Long
Dim QT_L(7, 7) As Byte
Dim Q_Table(7, 7) As Byte
'Set Constant
Pt = 1
'Initialize Sheet
Range("A3:D14") = ""
Range("F3:AQ43") = ""
[A1] = "Target File"
[A3] = "File Size"
[A4] = "SOI"
[A5] = "APP 0"
[A6] = "APP 1"
[A7] = "APP 14"
[A8] = "SOFn"
[A9] = "Type"
[A10] = "Pic. Size"
[A11] = "Y"
[A12] = "Cb"
[A13] = "Cr"
[B5] = "<Not Exist>"
[B6] = "<Not Exist>"
[B7] = "<Not Exist>"
'Set Target File
Target = [B1]
'Get File Size
[B3] = FileLen(Target)
[C3] = " Bytes"
M = 0 'DQT Seg.が複数存在する場合の対処
'Get Jpeg Parameters
Open Target For Binary As #1
Do
Get #1, Pt, S_Mark
If S_Mark.S_ID(0) <> &HFF Then Exit Do 'マーカをロストしたら中止
Mark_ID = S_Mark.S_ID(1)
Mark_Size = CLng(S_Mark.S_Size(0)) * 256 + S_Mark.S_Size(1)
If Mark_ID = &HD8 Then 'SOI Marker
[B4] = "Detected"
Mark_Size = 0
ElseIf Mark_ID = &HE0 Then 'APP0 JFIF
Get #1, , APPn
[B5] = APPn.APP_ID
[C5] = "Ver. " & Str(APPn.Ver_H) & "." & Str(APPn.Ver_L)
ElseIf Mark_ID = &HE1 Then 'APP1 Exif
Get #1, , APPn
[B6] = APPn.APP_ID
ElseIf Mark_ID = &HEE Then 'APP14 Adobe
Get #1, , APPn
[B7] = APPn.APP_ID
ElseIf Mark_ID = &HDB Then 'DQT Marker
L = 2
K = 0
Do
Get #1, , QT
Num = QT Mod 16
Cells(3 + K, 6 + M) = "QT#" & Str(Num)
If QT \ 16 = 1 Then '2 Byteの量子化テーブルは非対応
Cells(3 + K, 9 + M) = "2 Bytes Table <Skip>"
L = L + 129
K = K + 10
Else
Get #1, , QT_L()
N = 0
For i = 0 To 14 Step 2
For j = 0 To i
If (j < 8) And (i - j < 8) Then
Q_Table(j, i - j) = QT_L(N Mod 8, N \ 8)
N = N + 1
End If
Next j
For j = i + 1 To 0 Step -1
If (j < 8) And (i + 1 - j < 8) Then
Q_Table(j, i + 1 - j) = QT_L(N Mod 8, N \ 8)
N = N + 1
End If
Next j
Next i
For Y = 0 To 7
For X = 0 To 7
Cells(Y + 4 + K, X + 6 + M) = Q_Table(X, Y)
Next X
Next Y
L = L + 65
K = K + 10
End If
If Mark_Size <= L Then Exit Do
Loop
M = M + 9
ElseIf Mark_ID = &HC0 Or ((&HC1 <= Mark_ID And Mark_ID <= &HCF) _
And Mark_ID Mod 4 > 0) Then 'SOFn Marker
Get #1, , SOFn
If Mark_ID Mod 4 = 0 Then
[B9] = "BaseLine"
ElseIf Mark_ID Mod 4 = 1 Then
[B9] = "Sequential"
ElseIf Mark_ID Mod 4 = 2 Then
[B9] = "Progressive"
ElseIf Mark_ID Mod 4 = 3 Then
[B9] = "LossLess"
End If
If Mark_ID <= &HC7 Then [C9] = "Huffmann" Else [C9] = "Arithmetic"
XP = CLng(SOFn.X_Pix(0)) * 256 + SOFn.X_Pix(1)
YP = CLng(SOFn.Y_Pix(0)) * 256 + SOFn.Y_Pix(1)
[B10] = "W: " & Str(XP) & " pix"
[C10] = "H: " & Str(YP) & " pix"
[B11] = "H_Samp = " & Str(SOFn.YCC(0).HV_Samp \ 16)
[C11] = "V_Samp = " & Str(SOFn.YCC(0).HV_Samp Mod 16)
[D11] = "Q_Table # " & Str(SOFn.YCC(0).Q_Tbl)
[B12] = "H_Samp = " & Str(SOFn.YCC(1).HV_Samp \ 16)
[C12] = "V_Samp = " & Str(SOFn.YCC(1).HV_Samp Mod 16)
[D12] = "Q_Table # " & Str(SOFn.YCC(1).Q_Tbl)
[B13] = "H_Samp = " & Str(SOFn.YCC(2).HV_Samp \ 16)
[C13] = "V_Samp = " & Str(SOFn.YCC(2).HV_Samp Mod 16)
[D13] = "Q_Table # " & Str(SOFn.YCC(2).Q_Tbl)
End If
Pt = Pt + 2 + Mark_Size
If Pt > [B3] - 1 Then Exit Do
Loop
Close #1
Range("B1").Select
End Sub
なお、当ブログ掲載のプログラムの実行により如何なる損害が発生しようとも、
その損害の補償には一切応じないので、そのつもりで。。。
バグっていても、アタシが困らない限り修正リリースはしないし、
現時点で興味が無いパラメータや意味不明のパラメータの解析をフォロー続ける意思は
持ち合わせておりません。
亭主敬白
ところで・・・PhotoshopでJPEG保存する時に
”ベースライン(標準)” と ”ベースライン(最適化)” という項目がある。(話題として、プログレは無視)
この指定についての情報はJPEGファイル上には明示的には存在しない。
(APP13のPhotoshopのセグメント内に何かの記号がありそうな気配は・・・・ある)
この標準と最適化の違いについては、また後日。。。。