All-About調査室 Annex

ふと湧いた疑問や巷を漂うウワサを全部アバウト~に調査・検証
<OCNから漂着 流浪の調査室>

JPEGの悪評は風評被害か? ~ JPEGってなんだ?:10(JPEGパラメータ分析)

2014-08-07 21:47:07 | JPEGの悪評は風評被害か?

前々回に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のセグメント内に何かの記号がありそうな気配は・・・・ある)

この標準と最適化の違いについては、また後日。。。。



最新の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。