All-About調査室 Annex

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

JFIF標準準拠のヘッダを作る の続き

2018-02-09 00:38:51 | 4:4:4 Jpeg保存dll作成

GIMPで作った4:4:4Jpegから抜き出したヘッダはこのままではバイナリなので
これを配列の初期値としてソースコードに記述し、ヘッダの雛形とするため
テキストデータに変換するExcel VBAプログラムを作る。

まず、ExcelワークシートのB2セルに保存したヘッダのデータファイルのあるフォルダを記述。
E:\TestData とかね。
次にB3セルに別名保存したヘッダのデータファイルの名前を記述。
GIMP_Head.datとかね。
で、最後にB4セルに変換出力となるテキストファイルの名前を記述。
Head.txt とかね。

でもって、VBAにて以下のプログラムを書いて実行。

Sub Head()
    Dim D_Byte() As Byte
    Dim K, M, N As Integer
    Dim Data As String

    Folder$ = Range("B2")
    Data_File$ = Range("B3")
    Out_File$ = Range("B4")

    M = FileLen(Folder$ & "\" & Data_File$) – 1
    ReDim D_Byte(M)

    Open Folder$ & "\" & Data_File$ For Binary As #1
    Get #1, , D_Byte()
    Close #1

    K = 0
    Open Folder$ & "\" & Out_File$ For Output As #1
    For N = 0 To M
        Data = Right("0" & _
            Application.WorksheetFunction.Dec2Hex(D_Byte(N)), 2)
        If K <> 7 Then
            Print #1, "0x" & Data & ", ";
            K = K + 1
        Else
            Print #1, "0x" & Data & ", "
            K = 0
        End If
    Next N
    Close #1
End Sub

テキストファイルが出来たら、確認がてらテキストエディタで開いて以下の修正を行う。
テキストファイルはこんなカンジになっている・・・はず

0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46,
0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x48,
0x00, 0x48, 0x00, 0x00, 0xFF, 0xDB, 0x00, 0x43,
・・・ 中略 ・・・
0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00, 0x02, 0x11,
0x03, 0x11, 0x00, 0x3F, 0x00,

修正対象は後から4番目と6番目にある“0x11”。
これはCbとCrが参照するハフマンテーブルIDを指定しているものだが、
Cb,Cr共にY用のハフマンテーブルを共用する方針なので、
後から8番目(Y用ハフマンテーブルID)と同じ“0x00”に直す。

ついでに忘れない内に一番最後に付いている余計な“,”(コンマ)を削除してしまおう。

ところで、テキストファイルの先頭から15・16番目と17・18番目の“0x00, 0x48”なのだが、
これは水平と垂直方向の“印刷解像度(dpi)値”を表している。
値は10進整数値を16進数で表し、15・17番目はその上位2桁、16・18番目は下位2桁である。
なので00 48は72dpiを表す。(10進数の72は16進数で0048)

この値はほとんどカタチだけのもので画像品質には関係なく、
この値を参照・利用するソフトは家庭レベルでは存在せず、どんな値でも意味が無い。
・・・ということを知っている人は良いが、世間にはこの値が小さいとビックリする人が多い。
いちいちビックリされてもめんどくさい・・・と思う人はここを400dpiくらいに変えておこう。
(本プログラムではそうする)
10進数の400は16進数で0190だから15~18番目を“0x01, 0x90, 0x01, 0x90”にする。
(下のソース記述例では400dpiにしてある)

先に用意したCのソースファイル Initialize Variable Array セクション
static unsigned char JPHead[413] = {};
と書いて、この { } の中にテキストファイルのデータをコピペすれば
ヘッダ部分の雛型の出来上がりとなる。

内容が少しわかりやすいようにJpegセグメントごとに分離して
コメントを追記すると・・・

///// Initialize Variable Array /////

/*** Jpeg File Header ***/
static unsigned char JPHead[413] = {
//  SOI Start of Image
0xFF, 0xD8,

//  APP0 Application segment marker #0
//  JFIF 1.1  H400dpi V400dpi  No-Thumb.
0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46,
0x00, 0x01, 0x01, 0x01, 0x01, 0x90, 0x01, 0x90,
0x00, 0x00,

//  DQT Define Quantization Table #00
//  8bit,  @Q50 for Y,  Q-Table:JPHead[25]~
0xFF, 0xDB, 0x00, 0x43, 0x00, 0x10, 0x0B, 0x0C,
0x0E, 0x0C, 0x0A, 0x10, 0x0E, 0x0D, 0x0E, 0x12,
0x11, 0x10, 0x13, 0x18, 0x28, 0x1A, 0x18, 0x16,
0x16, 0x18, 0x31, 0x23, 0x25, 0x1D, 0x28, 0x3A,
0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38, 0x37, 0x40,
0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57, 0x45, 0x37,
0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F, 0x62, 0x67,
0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79, 0x70, 0x64,
0x78, 0x5C, 0x65, 0x67, 0x63,  

//  DQT Define Quantization Table #01
//  8bit,  @Q50 for CbCr,  Q-Table:JPHead[94]~
0xFF, 0xDB, 0x00, 0x43, 0x01, 0x11, 0x12, 0x12,
0x18, 0x15, 0x18, 0x2F, 0x1A, 0x1A, 0x2F, 0x63,
0x42, 0x38, 0x42, 0x63, 0x63, 0x63, 0x63, 0x63,
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
0x63, 0x63, 0x63, 0x63, 0x63,

//  SOF0 Start Of Frame Type-0
//  Huffman Baseline  8bit  V:8pix H:8pix 3Elements 4:4:4
//  Ele#1:H/V sample 1/1 Q-Table #0 ---- Y
//  Ele#2:H/V sample 1/1 Q-Table #1 ---- Cb
//  Ele#3:H/V sample 1/1 Q-Table #1 ---- Cr
//  Vertical pix   : JPHead[163]~[164]
//  Horizontal pix : JPHead[165]~[166]
0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0x08, 0x00,
0x08, 0x03, 0x01, 0x11, 0x00, 0x02, 0x11, 0x01,
0x03, 0x11, 0x01,

//  DHT Define Huffman Table
//  for DC #0
0xFF, 0xC4, 0x00, 0x1F, 0x00, 0x00, 0x01, 0x05,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
0x0B,

//  DHT Define Huffman Table
//  for AC #0
0xFF, 0xC4, 0x00, 0xB5, 0x10, 0x00, 0x02, 0x01,
0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04,
0x04, 0x00, 0x00, 0x01, 0x7D, 0x01, 0x02, 0x03,
0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41,
0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14,
0x32, 0x81, 0x91, 0xA1, 0x08, 0x23, 0x42, 0xB1,
0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62,
0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19,
0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54,
0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64,
0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74,
0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84,
0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93,
0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2,
0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA,
0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5,
0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3,
0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA,

//  DRI Define Restart Interval
//  Interval Each 16(Temp.) Blocks
//  Num. of Blocks : JPHead[397]~[398]
0xFF, 0xDD, 0x00, 0x04, 0x00, 0x10,

//  Start of Scan
//  DC/AC Huffman Table ID Y:0/0 Cb:0/0 Cr:0/0
0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00, 0x02,
0x00, 0x03, 0x00, 0x00, 0x3F, 0x00
};

上記のコメント部分で“JPHead[xxx]~”とした部分は、
保存オプション指定や対象画像データに応じて変更すべき部分である。

で、JPHead[]配列をグローバルに置くことを前提として、
これらを変更するコードを作る。

- さらにつづく -



最新の画像もっと見る

コメントを投稿

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