-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxmlsimu.go
185 lines (169 loc) · 6.45 KB
/
xmlsimu.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package main
import (
"encoding/xml"
"errors"
"fmt"
"github.com/creasty/defaults"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
)
// FujifilmSimulation the film simulation to generate as XML. The XML grammar follows the FP1 format
// of the Fujifilm film simulations as expected by a Fujifilm camera.
type FujifilmSimulation struct {
XMLName xml.Name `xml:"ConversionProfile"`
Application string `xml:"application,attr" default:"XRFC"`
Version string `xml:"version,attr" default:"1.12.0.0"`
PropertyGroup *SimulationProperties `xml:"PropertyGroup"`
}
type SimulationProperties struct {
Device string `xml:"device,attr"`
Version string `xml:"version,attr"`
Label string `xml:"label,attr"`
SerialNumber int `xml:"CameraSerialNumber"`
TetherRAWConditionCode string `xml:"TetherRAWConditonCode"`
Editable string `xml:"Editable" default:"TRUE"`
SourceFileName string `xml:"SourceFileName"`
FileError string `xml:"Fileerror" default:"NONE"`
RotationAngle int8 `xml:"RotationAngle" default:"0"`
StructVer int `xml:"StructVer" default:"65536"`
IOPCode string `xml:"IOPCode" default:"FF159505"`
ShootingCondition string `xml:"ShootingCondition" default:"OFF"`
FileType string `xml:"FileType" default:"JPG"`
ImageSize string `xml:"ImageSize" default:"L3x2"`
ImageQuality string `xml:"ImageQuality" default:"Fine"`
ExposureBias string `xml:"ExposureBias" default:"0"`
DynamicRange string `xml:"DynamicRange"`
WideDRange int8 `xml:"WideDRange" default:"0"`
FilmSimulation string `xml:"FilmSimulation"`
BlackImageTone int8 `xml:"BlackImageTone" default:"0"`
MonochromaticColorRG int8 `xml:"MonochromaticColorRG" default:"0"`
GrainEffect string `xml:"GrainEffect"`
GrainEffectSize string `xml:"GrainEffectSize"`
ChromeEffect string `xml:"ChromeEffect"`
ColorChromeBlue string `xml:"ColorChromeBlue"`
SmoothSkinEffect string `xml:"SmoothSkinEffect" default:"OFF"`
WBShootCond string `xml:"WBShootCond" default:"OFF"`
WhiteBalance string `xml:"WhiteBalance" default:"Temperature"`
WBShiftR int8 `xml:"WBShiftR"`
WBShiftB int8 `xml:"WBShiftB"`
WBColorTemp string `xml:"WBColorTemp" default:"10000K"`
HighlightTone int8 `xml:"HighlightTone"`
Color int8 `xml:"Color"`
Sharpness int8 `xml:"Sharpness"`
NoiseReduction int8 `xml:"NoisReduction"`
Clarity int8 `xml:"Clarity" default:"0"`
LensModulationOpt string `xml:"LensModulationOpt" default:"ON"`
ColorSpace string `xml:"ColorSpace" default:"sRGB"`
HDR string `xml:"HDR"`
DigitalTeleConv string `xml:"DigitalTeleConv" default:"OFF"`
}
// generateXMLSimulations generates the film simulations for specified each simulation recipe and
// from the given user settings. The film simulation will be generated in XML in a FP1 file into the
// directory specified by the user settings.
func generateXMLSimulations(settings *UserSettings, recipes []*FujiSimulationRecipe) {
var camera = settings.Camera.Model + "_" + flatVersion(settings.Camera.FirmwareVersion)
fmt.Printf("The film simulations will be generated into the folder '%s'\n", settings.FP1Path)
fmt.Printf("Number of film simulation to generate: %d\n", len(recipes))
createRecursivelyDirectory(settings.FP1Path)
for _, recipe := range recipes {
fmt.Printf("Generate film simulation %s...", recipe.Label)
simulation := &FujifilmSimulation{
Version: settings.Xrfc.Version,
}
err1 := defaults.Set(simulation)
if err1 != nil {
log.Fatal(err1)
}
whiteBalance, colorTemp := findColorTemp(recipe.WhiteBalance)
properties := &SimulationProperties{
Device: settings.Camera.Model,
Version: camera,
Label: recipe.Label,
SerialNumber: settings.Xrfc.SerialNumber,
TetherRAWConditionCode: camera,
DynamicRange: recipe.DynamicRange,
FilmSimulation: recipe.FilmSimulation,
GrainEffect: recipe.Grain,
GrainEffectSize: computeGrainEffectSize(recipe.Grain),
ChromeEffect: recipe.CCFx,
ColorChromeBlue: normalizeCCFxB(recipe.CCFx, recipe.CCFxB),
WhiteBalance: whiteBalance,
WBColorTemp: colorTemp,
WBShiftR: recipe.WBShiftR,
WBShiftB: recipe.WBShiftB,
HighlightTone: recipe.HighlightTone,
Color: recipe.Color,
Sharpness: recipe.Sharpness,
NoiseReduction: recipe.NoiseReduction,
ColorSpace: settings.ColorSpace,
}
err2 := defaults.Set(properties)
if err2 != nil {
log.Fatal(err2)
}
simulation.PropertyGroup = properties
xmlSimulation, err := xml.MarshalIndent(simulation, " ", " ")
xmlSimulation = []byte(xml.Header + string(xmlSimulation))
if err != nil {
log.Fatal(err)
}
var fp1Name = normalizeFileName(recipe.Label)
var fp1Path = filepath.Join(settings.FP1Path, fp1Name+".FP1")
err = ioutil.WriteFile(fp1Path, xmlSimulation, 0644)
if err != nil {
fmt.Println(" FAILED")
log.Fatal(err)
}
fmt.Println(" OK")
}
}
func findColorTemp(whiteBalance string) (string, string) {
lastChar := whiteBalance[(len(whiteBalance) - 1):]
if lastChar == "K" {
return "Temperature", whiteBalance
}
return whiteBalance, "10000K"
}
func normalizeFileName(fileName string) string {
return strings.ReplaceAll(
strings.ReplaceAll(
strings.ReplaceAll(fileName, "/", "_"),
"\\", "_"), // for Unix system like MacOS X
"*", "_")
}
func createRecursivelyDirectory(path string) {
if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
err := os.MkdirAll(path, os.ModePerm)
if err != nil {
log.Fatal(err)
}
}
}
func normalizeCCFxB(ccfx string, ccfxb string) string {
if ccfx == "OFF" {
return "OFF"
}
return ccfxb
}
func computeGrainEffectSize(grain string) string {
var size string
switch grain {
case "OFF":
case "WEAK":
case "STRONG":
size = "SMALL"
break
default:
size = "LARGE"
}
return size
}
func flatVersion(version string) string {
if strings.Index(version, ".") == 1 {
return "0" + strings.ReplaceAll(version, ".", "")
}
return strings.ReplaceAll(version, ".", "")
}