14bit RAWでは現像時に+1EV露出補正した程度なら、
まだ色調調整出来る程度の階調余裕が十分あることを前回示した。
では、12bit RAWではどうなのか?
使用VBAプログラムは後回しに、結果から紹介する。
30x30pixを1ブロックとしてRGB同値で0~4095の全階調段階を螺旋状に
12bitのNEFに書き込んで、これをPictureNX-DでPictureStyle=ニュートラル、
ホワイトバランス=晴天で露出補正なしで現像したものは下のようになった。(1/8縮小)
同様に露出補正+1EVでも現像し、前回の14bit RAWの時と同様に、
それぞれのRGBヒストグラムで階調が70~89と110~129の20階調段階の範囲の
ピクセル数を調べて、階調段階数の20とブロックのピクセル数の900で割り
それぞれの階調範囲での、8bit画像1階調段階あたりの平均RAW階調数とした。
このカメラではRもさることながら、BもGに対して感度がかなり低い。
晴天ホワイトバランスではその補正のためにBでもかなり階調が消費されている。
12bit RAWでは露出補正ナシならば十分色調補正できるが、
白トビを嫌ってあらかじめアンダー露出で撮影して、現像時にプラス補正で適正化する
というワザは、階調余裕を考慮するとほぼ無理ということになる。
なお、RAWファイルへのパターン書き込みVBAプログラムは・・・
Private Type Temp_Byte
TB(1) As Byte
End Type
Private Type Int_Data
ID As Integer
End Type
Sub GraySpiral_12bit()
Dim DataMap(63, 63) As Integer
Dim LineIData() As Integer
Dim LineBData() As Byte
Dim MI As String * 2
Dim FType As String * 3
Dim St_Offset As Long, Start_Ad As Long
Dim Y_Step As Long, Data_Ad As Long
Dim X As Integer, Y As Integer
Dim N As Integer
Const End_N As Integer = 4095
Dim S As Integer, W As Integer
'for Change Order
Dim A As Int_Data
Dim B As Temp_Byte
Dim C As Byte
Folder$ = Range("B2").Value
File$ = Range("B3").Value
Open Folder$ & "\" & File$ For Binary As #1
Get #1, , MI
Close #1
If MI <> "MM" And MI <> "II" Then End
FileCopy Folder$ & "\" & File$, Folder$ & "\GSp_" & File$
FType = Right(File$, 3)
If FType = "NEF" Or FType = "nef" Then
BT = 1.5
ReDim LineBData(2879)
Else
BT = 2
ReDim LineIData(1919)
End If
File$ = Folder$ & "\GSp_" & File$
Sr_Width% = Range("B5").Value '←センサ横Pix数
Sr_Height% = Range("B6").Value '←センサ縦Pix数
St_Offset = Range("B7").Value '←StripOffset
Offset_X% = (Sr_Width% - 1920) \ 2
Offset_Y% = (Sr_Height% - 1920) \ 2
Y_Step = Sr_Width% * BT
Start_Ad = St_Offset + Y_Step * Offset_Y% + ((Offset_X% * BT) \ 2) * 2
X = 31
Y = 31
N = 0
S = 1
W = 1
DataMap(X, Y) = N
Do
For K% = 1 To W
N = N + 1
If N > End_N Then Exit Do
X = X + S
DataMap(X, Y) = N
Next K%
For K% = 1 To W
N = N + 1
If N > End_N Then Exit Do
Y = Y + S
DataMap(X, Y) = N
Next K%
W = W + 1
S = -1 * S
Loop
If FType <> "NEF" And FType <> "nef" And MI = "MM" Then
For X = 0 To 63
For Y = 0 To 63
GoSub Change_Order
Next Y
Next X
End If
On Error GoTo Retry
Write_Data:
Y = 0
While Y < 1920
If FType <> "NEF" And FType <> "nef" Then
For X = 0 To 1919
LineIData(X) = DataMap(X \ 30, Y \ 30)
Next X
Else
For X = 0 To 2877 Step 3
LineBData(X) = DataMap(X \ 45, Y \ 30) \ 16
LineBData(X + 1) = (DataMap(X \ 45, Y \ 30) Mod 16) * 16 _
+ DataMap((X + 1) \ 45, Y \ 30) \ 256
LineBData(X + 2) = DataMap((X + 1) \ 45, Y \ 30) Mod 256
Next X
End If
Range("B4").Value = "Writing " & Y
Do
Data_Ad = Start_Ad + Y_Step * Y
Open File$ For Binary As #1
If FType <> "NEF" And FType <> "nef" Then
Put #1, Data_Ad + 1, LineIData()
'Offset値は0~、VBのアクセスアドレスは1~
Else
Put #1, Data_Ad + 1, LineBData()
End If
Close #1
Y = Y + 1
Loop While Y Mod 30 > 0
Wend
Range("B4").Value = "Finish"
Range("A1").Select
Exit Sub
'***** Sub-Routine ****************
Change_Order:
'Big Endianファイルの場合にデータのバイトオーダを入れ替える
A.ID = DataMap(X, Y)
LSet B = A
C = B.TB(0)
B.TB(0) = B.TB(1)
B.TB(1) = C
LSet A = B
DataMap(X, Y) = A.ID
Return
'------
Retry:
'FileCopy未完了で失敗した時はリトライする
Close #1
If Err.Number <> 75 Then
Range("B4").Value = "Error #" & Err.Number
Exit Sub
End If
DoEvents
Err.Clear
Resume Write_Data
End Sub
これに以下のデータ記述欄を作って実行する。
(データの記入方法や非圧縮RAWだけしか扱えないのは14bitの時と同じ)
ワークシート上にボタンを作ってマクロ登録しておくとプログラム起動が楽になる
なお、プログラムでは対象ファイルの素性はチェックしていないので、
12bit非圧縮RAWかどうかは使う側が確認する必要がある。
(元ファイルを「GSp_」から始まるファイル名でコピーして使うので、
元ファイルを破壊することは無いのだが・・・)
また、DNGの非圧縮では12bitデータを2Byte(16bit)整数値で、ごく普通に保存する。
・・・なので上位4bitは常にALLゼロのムダ領域が生じるのに対して、
NEFの12bit非圧縮のデータ保存は2つの12bitデータ(計24bit)を3Byteの領域に
3個のByteデータとして格納する、特殊な形式を使用しているのが普通である。
プログラムでは対象ファイルの拡張子がNEFか否かだけで、
この保存方法を切り替えている。
万一、別ルールの保存方法を使うNEFがあったら、結果は予定外のものになる。
またDNGに関して(14bitRAWでも同じなんだけど)、Foveonセンサーなど
非ベイヤー配列素子から作られたRAWを変換したDNGでも予定外の結果になるだろう。
(非ベイヤー配列素子のRAWはいぢったことが無いので、どうなるかはわからない)
参考:
12bit RAWに二つのデータ値1234、3456が書き込まれる場合
これらのデータを16進数で表現すると4D2、D86となり(12bitでは最大16進数でFFF)
これをByte(16進数2桁)ごとにファイル格納されて行く