diva.js 6.0.2 → 7.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/.clang-format +7 -0
  2. package/.github/workflows/npm-publish.yml +45 -0
  3. package/LICENSE +55 -0
  4. package/Makefile +75 -0
  5. package/README.md +15 -114
  6. package/elm.json +32 -0
  7. package/package.json +12 -59
  8. package/review/elm.json +52 -0
  9. package/review/src/ReviewConfig.elm +87 -0
  10. package/scripts/elm-esm.sh +40 -0
  11. package/scripts/minify-css.mjs +31 -0
  12. package/src/Filters.elm +1044 -0
  13. package/src/Main.elm +1217 -0
  14. package/src/Model.elm +213 -0
  15. package/src/Msg.elm +59 -0
  16. package/src/Utilities.elm +46 -0
  17. package/src/View/CollectionExplorer.elm +172 -0
  18. package/src/View/Helpers.elm +86 -0
  19. package/src/View/HtmlRenderer.elm +136 -0
  20. package/src/View/Icons.elm +159 -0
  21. package/src/View/ManifestInfoModal.elm +363 -0
  22. package/src/View/PageViewModal.elm +1046 -0
  23. package/src/View/Sidebar.elm +786 -0
  24. package/src/View/Toolbar.elm +189 -0
  25. package/src/View.elm +244 -0
  26. package/src/diva.ts +802 -0
  27. package/src/filters.ts +1843 -0
  28. package/src/styles/app.css +328 -0
  29. package/src/styles/collection.css +75 -0
  30. package/src/styles/modal.css +388 -0
  31. package/src/styles/sidebar.css +215 -0
  32. package/src/styles/theme.css +39 -0
  33. package/src/styles/toolbar.css +154 -0
  34. package/src/viewer-element.ts +1307 -0
  35. package/testing/index.html +52 -0
  36. package/testing/testing.html +231 -0
  37. package/tsconfig.json +12 -0
  38. package/AUTHORS +0 -22
  39. package/build/diva.css +0 -554
  40. package/build/diva.css.map +0 -1
  41. package/build/diva.js +0 -9
  42. package/build/diva.js.map +0 -1
  43. package/build/plugins/download.js +0 -2
  44. package/build/plugins/download.js.map +0 -1
  45. package/build/plugins/manipulation.js +0 -2
  46. package/build/plugins/manipulation.js.map +0 -1
  47. package/build/plugins/metadata.js +0 -2
  48. package/build/plugins/metadata.js.map +0 -1
  49. package/index.html +0 -28
  50. package/karma.conf.js +0 -87
  51. package/source/css/_mixins.scss +0 -43
  52. package/source/css/_variables.scss +0 -50
  53. package/source/css/_viewer.scss +0 -462
  54. package/source/css/diva.scss +0 -15
  55. package/source/css/plugins/_manipulation.scss +0 -228
  56. package/source/css/plugins/_metadata.scss +0 -31
  57. package/source/img/adjust.svg +0 -11
  58. package/source/img/book-view.svg +0 -6
  59. package/source/img/close.svg +0 -6
  60. package/source/img/download.svg +0 -6
  61. package/source/img/from-fullscreen.svg +0 -8
  62. package/source/img/grid-fewer.svg +0 -6
  63. package/source/img/grid-more.svg +0 -6
  64. package/source/img/grid-view.svg +0 -6
  65. package/source/img/link.svg +0 -6
  66. package/source/img/metadata.svg +0 -9
  67. package/source/img/page-view.svg +0 -6
  68. package/source/img/to-fullscreen.svg +0 -11
  69. package/source/img/zoom-in.svg +0 -6
  70. package/source/img/zoom-out.svg +0 -7
  71. package/source/js/composite-image.js +0 -174
  72. package/source/js/diva-global.js +0 -7
  73. package/source/js/diva.js +0 -1543
  74. package/source/js/document-handler.js +0 -180
  75. package/source/js/document-layout.js +0 -286
  76. package/source/js/exceptions.js +0 -26
  77. package/source/js/gesture-events.js +0 -190
  78. package/source/js/grid-handler.js +0 -122
  79. package/source/js/iiif-source-adapter.js +0 -63
  80. package/source/js/image-cache.js +0 -113
  81. package/source/js/image-manifest.js +0 -157
  82. package/source/js/image-request-handler.js +0 -76
  83. package/source/js/interpolate-animation.js +0 -122
  84. package/source/js/page-layouts/book-layout.js +0 -161
  85. package/source/js/page-layouts/grid-layout.js +0 -97
  86. package/source/js/page-layouts/index.js +0 -38
  87. package/source/js/page-layouts/page-dimensions.js +0 -9
  88. package/source/js/page-layouts/singles-layout.js +0 -27
  89. package/source/js/page-overlay-manager.js +0 -102
  90. package/source/js/page-tools-overlay.js +0 -95
  91. package/source/js/parse-iiif-manifest.js +0 -302
  92. package/source/js/plugins/_filters.js +0 -679
  93. package/source/js/plugins/download.js +0 -83
  94. package/source/js/plugins/manipulation.js +0 -837
  95. package/source/js/plugins/metadata.js +0 -190
  96. package/source/js/renderer.js +0 -584
  97. package/source/js/settings-view.js +0 -30
  98. package/source/js/tile-coverage-map.js +0 -25
  99. package/source/js/toolbar.js +0 -573
  100. package/source/js/utils/dragscroll.js +0 -106
  101. package/source/js/utils/elt.js +0 -94
  102. package/source/js/utils/events.js +0 -190
  103. package/source/js/utils/get-scrollbar-width.js +0 -29
  104. package/source/js/utils/hash-params.js +0 -86
  105. package/source/js/utils/parse-label-value.js +0 -34
  106. package/source/js/utils/vanilla.kinetic.js +0 -527
  107. package/source/js/validation-runner.js +0 -177
  108. package/source/js/viewer-core.js +0 -1514
  109. package/source/js/viewport.js +0 -143
  110. package/test/_setup.js +0 -13
  111. package/test/composite-image_test.js +0 -94
  112. package/test/diva_test.js +0 -43
  113. package/test/hash-params_test.js +0 -221
  114. package/test/image-cache_test.js +0 -106
  115. package/test/main.js +0 -6
  116. package/test/manifests/beromunsterManifest.json +0 -15514
  117. package/test/manifests/iiifv2.json +0 -11032
  118. package/test/manifests/iiifv2pages.json +0 -30437
  119. package/test/manifests/iiifv3.json +0 -10965
  120. package/test/navigation_test.js +0 -355
  121. package/test/parse-iiif-manifest_test.js +0 -68
  122. package/test/public_test.js +0 -881
  123. package/test/settings_test.js +0 -487
  124. package/test/utils/book-layout_test.js +0 -148
  125. package/test/utils/elt_test.js +0 -102
  126. package/test/utils/events_test.js +0 -245
  127. package/test/utils/hash-params_test.js +0 -79
  128. package/test/utils/parse-label-value_test.js +0 -45
  129. package/test/z_plugins_test.js +0 -180
  130. package/webpack.config.js +0 -58
  131. package/webpack.config.test.js +0 -45
@@ -0,0 +1,1044 @@
1
+ module Filters exposing
2
+ ( FilterFloatValue(..)
3
+ , FilterIntValue(..)
4
+ , FilterStringValue(..)
5
+ , FilterToggle(..)
6
+ , Filters
7
+ , FloatFilterConfig
8
+ , IntFilterConfig
9
+ , StringFilterConfig
10
+ , applyFilterToggle
11
+ , applyFloatFilter
12
+ , applyIntFilter
13
+ , applyStringFilter
14
+ , decodeFilterJson
15
+ , encodeActiveFilters
16
+ , resetAltColourAdjust
17
+ , resetFilters
18
+ , updateFilters
19
+ )
20
+
21
+ import Dict exposing (Dict)
22
+ import Json.Decode as Decode
23
+ import Json.Encode as Encode
24
+
25
+
26
+ type FilterFloatValue
27
+ = FloatColourReplaceBlend
28
+ | FloatContrast
29
+ | FloatGamma
30
+ | FloatNormalizeStrength
31
+ | FloatPseudoColourBlue
32
+ | FloatPseudoColourGreen
33
+ | FloatPseudoColourRed
34
+ | FloatUnsharpAmount
35
+
36
+
37
+ type FilterIntValue
38
+ = IntAdaptiveOffset
39
+ | IntAdaptiveWindow
40
+ | IntAltRedGamma
41
+ | IntAltRedSigmoid
42
+ | IntAltRedVibrance
43
+ | IntAltRedHue
44
+ | IntAltRedHueWindow
45
+ | IntAltGreenGamma
46
+ | IntAltGreenSigmoid
47
+ | IntAltGreenHue
48
+ | IntAltGreenHueWindow
49
+ | IntAltGreenVibrance
50
+ | IntAltBlueGamma
51
+ | IntAltBlueSigmoid
52
+ | IntAltBlueHue
53
+ | IntAltBlueHueWindow
54
+ | IntAltBlueVibrance
55
+ | IntBrightness
56
+ | IntCcBlue
57
+ | IntCcGreen
58
+ | IntCcRed
59
+ | IntColourmapCenter
60
+ | IntColourReplaceTolerance
61
+ | IntPcaHue
62
+ | IntHue
63
+ | IntMorphKernel
64
+ | IntRotation
65
+ | IntSaturation
66
+ | IntThreshold
67
+ | IntVibrance
68
+
69
+
70
+ type FilterStringValue
71
+ = StringColourmapPreset
72
+ | StringColourReplaceSource
73
+ | StringColourReplaceTarget
74
+ | StringConvolutionPreset
75
+ | StringPcaMode
76
+ | StringMorphOperation
77
+ | StringPseudoColourMode
78
+
79
+
80
+ type FilterToggle
81
+ = ToggleAdaptive
82
+ | ToggleAltBlueGamma
83
+ | ToggleAltBlueHue
84
+ | ToggleAltBlueSigmoid
85
+ | ToggleAltBlueVibrance
86
+ | ToggleAltGreenGamma
87
+ | ToggleAltGreenHue
88
+ | ToggleAltGreenSigmoid
89
+ | ToggleAltGreenVibrance
90
+ | ToggleAltRedGamma
91
+ | ToggleAltRedHue
92
+ | ToggleAltRedSigmoid
93
+ | ToggleAltRedVibrance
94
+ | ToggleBrightness
95
+ | ToggleCcBlue
96
+ | ToggleCcGreen
97
+ | ToggleCcRed
98
+ | ToggleColourmap
99
+ | ToggleColourReplace
100
+ | ToggleColourReplacePreserveLum
101
+ | ToggleContrast
102
+ | ToggleConvolution
103
+ | ToggleFlip
104
+ | ToggleGamma
105
+ | ToggleGlobalPca
106
+ | ToggleGrayscale
107
+ | ToggleHue
108
+ | ToggleInvert
109
+ | ToggleMorph
110
+ | ToggleNormalize
111
+ | TogglePseudoColour
112
+ | ToggleSaturation
113
+ | ToggleThreshold
114
+ | ToggleUnsharp
115
+ | ToggleVibrance
116
+
117
+
118
+ type alias Filters =
119
+ { rotation : Int
120
+ , flip : Bool
121
+ , grayscale : Bool
122
+ , invert : Bool
123
+ , thresholdEnabled : Bool
124
+ , threshold : Int
125
+ , brightnessEnabled : Bool
126
+ , brightness : Int
127
+ , saturationEnabled : Bool
128
+ , saturation : Int
129
+ , vibranceEnabled : Bool
130
+ , vibrance : Int
131
+ , hueEnabled : Bool
132
+ , hue : Int
133
+ , ccRedEnabled : Bool
134
+ , ccRed : Int
135
+ , ccGreenEnabled : Bool
136
+ , ccGreen : Int
137
+ , ccBlueEnabled : Bool
138
+ , ccBlue : Int
139
+ , contrastEnabled : Bool
140
+ , contrast : Float
141
+ , gammaEnabled : Bool
142
+ , gamma : Float
143
+ , morphEnabled : Bool
144
+ , morphKernel : Int
145
+ , morphOperation : String
146
+ , convolutionEnabled : Bool
147
+ , convolutionPreset : String
148
+ , colourmapEnabled : Bool
149
+ , colourmapPreset : String
150
+ , colourmapCenter : Int
151
+ , pseudoColourEnabled : Bool
152
+ , pseudoColourMode : String
153
+ , pseudoColourRed : Float
154
+ , pseudoColourGreen : Float
155
+ , pseudoColourBlue : Float
156
+ , globalPcaEnabled : Bool
157
+ , pcaMode : String
158
+ , pcaHue : Int
159
+ , colourReplaceEnabled : Bool
160
+ , colourReplaceSource : String
161
+ , colourReplaceTarget : String
162
+ , colourReplaceTolerance : Int
163
+ , colourReplaceBlend : Float
164
+ , colourReplacePreserveLum : Bool
165
+ , unsharpEnabled : Bool
166
+ , unsharpAmount : Float
167
+ , normalizeEnabled : Bool
168
+ , normalizeStrength : Float
169
+ , adaptiveEnabled : Bool
170
+ , adaptiveWindow : Int
171
+ , adaptiveOffset : Int
172
+ , altRedGamma : Int
173
+ , altRedGammaEnabled : Bool
174
+ , altRedSigmoid : Int
175
+ , altRedSigmoidEnabled : Bool
176
+ , altRedHue : Int
177
+ , altRedHueEnabled : Bool
178
+ , altRedHueWindow : Int
179
+ , altRedVibranceEnabled : Bool
180
+ , altGreenGamma : Int
181
+ , altGreenGammaEnabled : Bool
182
+ , altGreenSigmoid : Int
183
+ , altGreenSigmoidEnabled : Bool
184
+ , altGreenHue : Int
185
+ , altGreenHueEnabled : Bool
186
+ , altGreenHueWindow : Int
187
+ , altGreenVibranceEnabled : Bool
188
+ , altGreenVibrance : Int
189
+ , altBlueGamma : Int
190
+ , altBlueGammaEnabled : Bool
191
+ , altBlueSigmoid : Int
192
+ , altBlueSigmoidEnabled : Bool
193
+ , altBlueHue : Int
194
+ , altBlueHueEnabled : Bool
195
+ , altBlueHueWindow : Int
196
+ , altBlueVibranceEnabled : Bool
197
+ , altBlueVibrance : Int
198
+ , altRedVibrance : Int
199
+ }
200
+
201
+
202
+ type alias FloatFilterConfig =
203
+ { min : Float
204
+ , max : Float
205
+ , get : Filters -> Float
206
+ , set : Float -> Filters -> Filters
207
+ }
208
+
209
+
210
+ type alias IntFilterConfig =
211
+ { min : Int
212
+ , max : Int
213
+ , get : Filters -> Int
214
+ , set : Int -> Filters -> Filters
215
+ , validate : Maybe (Int -> Int)
216
+ }
217
+
218
+
219
+ type alias StringFilterConfig =
220
+ { get : Filters -> String
221
+ , set : String -> Filters -> Filters
222
+ , validate : String -> Bool
223
+ }
224
+
225
+
226
+ applyFilterToggle : FilterToggle -> Bool -> Filters -> Filters
227
+ applyFilterToggle toggle enabled filters =
228
+ case toggle of
229
+ ToggleAdaptive ->
230
+ { filters | adaptiveEnabled = enabled }
231
+
232
+ ToggleAltBlueGamma ->
233
+ { filters | altBlueGammaEnabled = enabled }
234
+
235
+ ToggleAltBlueHue ->
236
+ { filters | altBlueHueEnabled = enabled }
237
+
238
+ ToggleAltBlueSigmoid ->
239
+ { filters | altBlueSigmoidEnabled = enabled }
240
+
241
+ ToggleAltBlueVibrance ->
242
+ { filters | altBlueVibranceEnabled = enabled }
243
+
244
+ ToggleAltGreenGamma ->
245
+ { filters | altGreenGammaEnabled = enabled }
246
+
247
+ ToggleAltGreenHue ->
248
+ { filters | altGreenHueEnabled = enabled }
249
+
250
+ ToggleAltGreenSigmoid ->
251
+ { filters | altGreenSigmoidEnabled = enabled }
252
+
253
+ ToggleAltGreenVibrance ->
254
+ { filters | altGreenVibranceEnabled = enabled }
255
+
256
+ ToggleAltRedGamma ->
257
+ { filters | altRedGammaEnabled = enabled }
258
+
259
+ ToggleAltRedHue ->
260
+ { filters | altRedHueEnabled = enabled }
261
+
262
+ ToggleAltRedSigmoid ->
263
+ { filters | altRedSigmoidEnabled = enabled }
264
+
265
+ ToggleAltRedVibrance ->
266
+ { filters | altRedVibranceEnabled = enabled }
267
+
268
+ ToggleBrightness ->
269
+ { filters | brightnessEnabled = enabled }
270
+
271
+ ToggleCcBlue ->
272
+ { filters | ccBlueEnabled = enabled }
273
+
274
+ ToggleCcGreen ->
275
+ { filters | ccGreenEnabled = enabled }
276
+
277
+ ToggleCcRed ->
278
+ { filters | ccRedEnabled = enabled }
279
+
280
+ ToggleColourmap ->
281
+ { filters | colourmapEnabled = enabled }
282
+
283
+ ToggleColourReplace ->
284
+ { filters | colourReplaceEnabled = enabled }
285
+
286
+ ToggleColourReplacePreserveLum ->
287
+ { filters | colourReplacePreserveLum = enabled }
288
+
289
+ ToggleContrast ->
290
+ { filters | contrastEnabled = enabled }
291
+
292
+ ToggleConvolution ->
293
+ { filters | convolutionEnabled = enabled }
294
+
295
+ ToggleFlip ->
296
+ { filters | flip = enabled }
297
+
298
+ ToggleGamma ->
299
+ { filters | gammaEnabled = enabled }
300
+
301
+ ToggleGlobalPca ->
302
+ { filters | globalPcaEnabled = enabled }
303
+
304
+ ToggleGrayscale ->
305
+ { filters | grayscale = enabled }
306
+
307
+ ToggleHue ->
308
+ { filters | hueEnabled = enabled }
309
+
310
+ ToggleInvert ->
311
+ { filters | invert = enabled }
312
+
313
+ ToggleMorph ->
314
+ { filters | morphEnabled = enabled }
315
+
316
+ ToggleNormalize ->
317
+ { filters | normalizeEnabled = enabled }
318
+
319
+ TogglePseudoColour ->
320
+ { filters | pseudoColourEnabled = enabled }
321
+
322
+ ToggleSaturation ->
323
+ { filters | saturationEnabled = enabled }
324
+
325
+ ToggleThreshold ->
326
+ { filters | thresholdEnabled = enabled }
327
+
328
+ ToggleUnsharp ->
329
+ { filters | unsharpEnabled = enabled }
330
+
331
+ ToggleVibrance ->
332
+ { filters | vibranceEnabled = enabled }
333
+
334
+
335
+ applyFloatFilter : FilterFloatValue -> String -> Filters -> Filters
336
+ applyFloatFilter filterValue raw filters =
337
+ let
338
+ config =
339
+ floatFilterConfig filterValue
340
+
341
+ parsed =
342
+ String.toFloat raw
343
+
344
+ nextValue =
345
+ Maybe.map (clamp config.min config.max) parsed
346
+ |> Maybe.withDefault (config.get filters)
347
+ in
348
+ config.set nextValue filters
349
+
350
+
351
+ applyIntFilter : FilterIntValue -> String -> Filters -> Filters
352
+ applyIntFilter filterValue raw filters =
353
+ let
354
+ config =
355
+ intFilterConfig filterValue
356
+
357
+ parsed =
358
+ String.toInt raw
359
+
360
+ nextValue =
361
+ case parsed of
362
+ Just v ->
363
+ let
364
+ clamped =
365
+ clamp config.min config.max v
366
+ in
367
+ case config.validate of
368
+ Just validator ->
369
+ validator clamped
370
+
371
+ Nothing ->
372
+ clamped
373
+
374
+ Nothing ->
375
+ config.get filters
376
+ in
377
+ config.set nextValue filters
378
+
379
+
380
+ applyStringFilter : FilterStringValue -> String -> Filters -> Filters
381
+ applyStringFilter filterValue raw filters =
382
+ let
383
+ config =
384
+ stringFilterConfig filterValue
385
+
386
+ nextValue =
387
+ if config.validate raw then
388
+ raw
389
+
390
+ else
391
+ config.get filters
392
+ in
393
+ config.set nextValue filters
394
+
395
+
396
+ decodeFilterJson : String -> Result String Filters
397
+ decodeFilterJson raw =
398
+ case Decode.decodeString (Decode.dict Decode.value) raw of
399
+ Ok dict ->
400
+ Ok (applyFilterPatch dict)
401
+
402
+ Err err ->
403
+ Err (Decode.errorToString err)
404
+
405
+
406
+ encodeActiveFilters : Filters -> String
407
+ encodeActiveFilters filters =
408
+ let
409
+ activeFields =
410
+ []
411
+ |> addIf (filters.rotation /= 0) "rotation" (Encode.int filters.rotation)
412
+ |> addIf filters.flip "flip" (Encode.bool True)
413
+ |> addIf filters.grayscale "grayscale" (Encode.bool True)
414
+ |> addIf filters.invert "invert" (Encode.bool True)
415
+ |> addIf filters.thresholdEnabled "threshold" (Encode.int filters.threshold)
416
+ |> addIf filters.brightnessEnabled "brightness" (Encode.int filters.brightness)
417
+ |> addIf filters.contrastEnabled "contrast" (Encode.float filters.contrast)
418
+ |> addIf filters.gammaEnabled "gamma" (Encode.float filters.gamma)
419
+ |> addIf filters.saturationEnabled "saturation" (Encode.int filters.saturation)
420
+ |> addIf filters.vibranceEnabled "vibrance" (Encode.int filters.vibrance)
421
+ |> addIf filters.hueEnabled "hue" (Encode.int filters.hue)
422
+ |> addIf filters.ccRedEnabled "ccRed" (Encode.int filters.ccRed)
423
+ |> addIf filters.ccGreenEnabled "ccGreen" (Encode.int filters.ccGreen)
424
+ |> addIf filters.ccBlueEnabled "ccBlue" (Encode.int filters.ccBlue)
425
+ |> addIf filters.morphEnabled "morphOperation" (Encode.string filters.morphOperation)
426
+ |> addIf filters.morphEnabled "morphKernel" (Encode.int filters.morphKernel)
427
+ |> addIf filters.convolutionEnabled "convolutionPreset" (Encode.string filters.convolutionPreset)
428
+ |> addIf filters.colourmapEnabled "colourmapPreset" (Encode.string filters.colourmapPreset)
429
+ |> addIf filters.colourmapEnabled "colourmapCenter" (Encode.int filters.colourmapCenter)
430
+ |> addIf filters.pseudoColourEnabled "pseudoColourMode" (Encode.string filters.pseudoColourMode)
431
+ |> addIf filters.pseudoColourEnabled "pseudoColourRed" (Encode.float filters.pseudoColourRed)
432
+ |> addIf filters.pseudoColourEnabled "pseudoColourGreen" (Encode.float filters.pseudoColourGreen)
433
+ |> addIf filters.pseudoColourEnabled "pseudoColourBlue" (Encode.float filters.pseudoColourBlue)
434
+ |> addIf filters.globalPcaEnabled "pcaMode" (Encode.string filters.pcaMode)
435
+ |> addIf filters.globalPcaEnabled "pcaHue" (Encode.int filters.pcaHue)
436
+ |> addIf filters.colourReplaceEnabled "colourReplaceSource" (Encode.string filters.colourReplaceSource)
437
+ |> addIf filters.colourReplaceEnabled "colourReplaceTarget" (Encode.string filters.colourReplaceTarget)
438
+ |> addIf filters.colourReplaceEnabled "colourReplaceTolerance" (Encode.int filters.colourReplaceTolerance)
439
+ |> addIf filters.colourReplaceEnabled "colourReplaceBlend" (Encode.float filters.colourReplaceBlend)
440
+ |> addIf filters.colourReplaceEnabled "colourReplacePreserveLum" (Encode.bool filters.colourReplacePreserveLum)
441
+ |> addIf filters.unsharpEnabled "unsharpAmount" (Encode.float filters.unsharpAmount)
442
+ |> addIf filters.normalizeEnabled "normalizeStrength" (Encode.float filters.normalizeStrength)
443
+ |> addIf filters.adaptiveEnabled "adaptiveWindow" (Encode.int filters.adaptiveWindow)
444
+ |> addIf filters.adaptiveEnabled "adaptiveOffset" (Encode.int filters.adaptiveOffset)
445
+ |> addIf filters.altRedGammaEnabled "altRedGamma" (Encode.int filters.altRedGamma)
446
+ |> addIf filters.altRedSigmoidEnabled "altRedSigmoid" (Encode.int filters.altRedSigmoid)
447
+ |> addIf filters.altRedHueEnabled "altRedHue" (Encode.int filters.altRedHue)
448
+ |> addIf filters.altRedHueEnabled "altRedHueWindow" (Encode.int filters.altRedHueWindow)
449
+ |> addIf filters.altRedVibranceEnabled "altRedVibrance" (Encode.int filters.altRedVibrance)
450
+ |> addIf filters.altGreenGammaEnabled "altGreenGamma" (Encode.int filters.altGreenGamma)
451
+ |> addIf filters.altGreenSigmoidEnabled "altGreenSigmoid" (Encode.int filters.altGreenSigmoid)
452
+ |> addIf filters.altGreenHueEnabled "altGreenHue" (Encode.int filters.altGreenHue)
453
+ |> addIf filters.altGreenHueEnabled "altGreenHueWindow" (Encode.int filters.altGreenHueWindow)
454
+ |> addIf filters.altGreenVibranceEnabled "altGreenVibrance" (Encode.int filters.altGreenVibrance)
455
+ |> addIf filters.altBlueGammaEnabled "altBlueGamma" (Encode.int filters.altBlueGamma)
456
+ |> addIf filters.altBlueSigmoidEnabled "altBlueSigmoid" (Encode.int filters.altBlueSigmoid)
457
+ |> addIf filters.altBlueHueEnabled "altBlueHue" (Encode.int filters.altBlueHue)
458
+ |> addIf filters.altBlueHueEnabled "altBlueHueWindow" (Encode.int filters.altBlueHueWindow)
459
+ |> addIf filters.altBlueVibranceEnabled "altBlueVibrance" (Encode.int filters.altBlueVibrance)
460
+ in
461
+ Encode.object activeFields
462
+ |> Encode.encode 2
463
+
464
+
465
+
466
+ -- FILTER TOGGLE TYPES
467
+
468
+
469
+ resetAltColourAdjust : Filters -> Filters
470
+ resetAltColourAdjust filters =
471
+ { filters
472
+ | altRedGamma = 0
473
+ , altRedGammaEnabled = False
474
+ , altRedSigmoid = 0
475
+ , altRedSigmoidEnabled = False
476
+ , altRedHue = 0
477
+ , altRedHueEnabled = False
478
+ , altRedHueWindow = 8
479
+ , altRedVibranceEnabled = False
480
+ , altGreenGamma = 0
481
+ , altGreenGammaEnabled = False
482
+ , altGreenSigmoid = 0
483
+ , altGreenSigmoidEnabled = False
484
+ , altGreenHue = 0
485
+ , altGreenHueEnabled = False
486
+ , altGreenHueWindow = 8
487
+ , altGreenVibranceEnabled = False
488
+ , altGreenVibrance = 0
489
+ , altBlueGamma = 0
490
+ , altBlueGammaEnabled = False
491
+ , altBlueSigmoid = 0
492
+ , altBlueSigmoidEnabled = False
493
+ , altBlueHue = 0
494
+ , altBlueHueEnabled = False
495
+ , altBlueHueWindow = 8
496
+ , altBlueVibranceEnabled = False
497
+ , altBlueVibrance = 0
498
+ , altRedVibrance = 0
499
+ }
500
+
501
+
502
+ resetFilters : Filters
503
+ resetFilters =
504
+ { rotation = 0
505
+ , flip = False
506
+ , grayscale = False
507
+ , invert = False
508
+ , thresholdEnabled = False
509
+ , threshold = 128
510
+ , brightnessEnabled = False
511
+ , brightness = 0
512
+ , saturationEnabled = False
513
+ , saturation = 0
514
+ , vibranceEnabled = False
515
+ , vibrance = 0
516
+ , hueEnabled = False
517
+ , hue = 0
518
+ , ccRedEnabled = False
519
+ , ccRed = 0
520
+ , ccGreenEnabled = False
521
+ , ccGreen = 0
522
+ , ccBlueEnabled = False
523
+ , ccBlue = 0
524
+ , contrastEnabled = False
525
+ , contrast = 1
526
+ , gammaEnabled = False
527
+ , gamma = 1
528
+ , morphEnabled = False
529
+ , morphKernel = 3
530
+ , morphOperation = "erode"
531
+ , convolutionEnabled = False
532
+ , convolutionPreset = "sharpen"
533
+ , colourmapEnabled = False
534
+ , colourmapPreset = "gray"
535
+ , colourmapCenter = 128
536
+ , pseudoColourEnabled = False
537
+ , pseudoColourMode = "rg"
538
+ , pseudoColourRed = 1
539
+ , pseudoColourGreen = 1
540
+ , pseudoColourBlue = 1
541
+ , globalPcaEnabled = False
542
+ , pcaMode = "pca-rgb"
543
+ , pcaHue = 0
544
+ , colourReplaceEnabled = False
545
+ , colourReplaceSource = "#ffffff"
546
+ , colourReplaceTarget = "#ffffff"
547
+ , colourReplaceTolerance = 24
548
+ , colourReplaceBlend = 1
549
+ , colourReplacePreserveLum = False
550
+ , unsharpEnabled = False
551
+ , unsharpAmount = 1
552
+ , normalizeEnabled = False
553
+ , normalizeStrength = 1
554
+ , adaptiveEnabled = False
555
+ , adaptiveWindow = 15
556
+ , adaptiveOffset = 10
557
+ , altRedGamma = 0
558
+ , altRedGammaEnabled = False
559
+ , altRedSigmoid = 0
560
+ , altRedSigmoidEnabled = False
561
+ , altRedHue = 0
562
+ , altRedHueEnabled = False
563
+ , altRedHueWindow = 8
564
+ , altRedVibranceEnabled = False
565
+ , altGreenGamma = 0
566
+ , altGreenGammaEnabled = False
567
+ , altGreenSigmoid = 0
568
+ , altGreenSigmoidEnabled = False
569
+ , altGreenHue = 0
570
+ , altGreenHueEnabled = False
571
+ , altGreenHueWindow = 8
572
+ , altGreenVibranceEnabled = False
573
+ , altGreenVibrance = 0
574
+ , altBlueGamma = 0
575
+ , altBlueGammaEnabled = False
576
+ , altBlueSigmoid = 0
577
+ , altBlueSigmoidEnabled = False
578
+ , altBlueHue = 0
579
+ , altBlueHueEnabled = False
580
+ , altBlueHueWindow = 8
581
+ , altBlueVibranceEnabled = False
582
+ , altBlueVibrance = 0
583
+ , altRedVibrance = 0
584
+ }
585
+
586
+
587
+
588
+ -- FILTER INT VALUE TYPES
589
+
590
+
591
+ updateFilters : (Filters -> Filters) -> { model | filters : Filters } -> { model | filters : Filters }
592
+ updateFilters updater model =
593
+ { model | filters = updater model.filters }
594
+
595
+
596
+ addIf : Bool -> String -> Encode.Value -> List ( String, Encode.Value ) -> List ( String, Encode.Value )
597
+ addIf condition key value acc =
598
+ if condition then
599
+ ( key, value ) :: acc
600
+
601
+ else
602
+ acc
603
+
604
+
605
+ applyFilterPatch : Dict String Decode.Value -> Filters
606
+ applyFilterPatch dict =
607
+ let
608
+ base =
609
+ resetFilters
610
+
611
+ rotation =
612
+ decodeInt "rotation" dict
613
+
614
+ flip =
615
+ decodeBool "flip" dict
616
+
617
+ grayscale =
618
+ decodeBool "grayscale" dict
619
+
620
+ invert =
621
+ decodeBool "invert" dict
622
+
623
+ threshold =
624
+ decodeInt "threshold" dict
625
+
626
+ brightness =
627
+ decodeInt "brightness" dict
628
+
629
+ contrast =
630
+ decodeFloat "contrast" dict
631
+
632
+ gamma =
633
+ decodeFloat "gamma" dict
634
+
635
+ saturation =
636
+ decodeInt "saturation" dict
637
+
638
+ vibrance =
639
+ decodeInt "vibrance" dict
640
+
641
+ hue =
642
+ decodeInt "hue" dict
643
+
644
+ ccRed =
645
+ decodeInt "ccRed" dict
646
+
647
+ ccGreen =
648
+ decodeInt "ccGreen" dict
649
+
650
+ ccBlue =
651
+ decodeInt "ccBlue" dict
652
+
653
+ morphOperation =
654
+ decodeString "morphOperation" dict
655
+
656
+ morphKernel =
657
+ decodeInt "morphKernel" dict
658
+
659
+ convolutionPreset =
660
+ decodeString "convolutionPreset" dict
661
+
662
+ colourmapPreset =
663
+ decodeString "colourmapPreset" dict
664
+
665
+ colourmapCenter =
666
+ decodeInt "colourmapCenter" dict
667
+
668
+ pseudoColourMode =
669
+ decodeString "pseudoColourMode" dict
670
+
671
+ pseudoColourRed =
672
+ decodeFloat "pseudoColourRed" dict
673
+
674
+ pseudoColourGreen =
675
+ decodeFloat "pseudoColourGreen" dict
676
+
677
+ pseudoColourBlue =
678
+ decodeFloat "pseudoColourBlue" dict
679
+
680
+ pcaMode =
681
+ decodeString "pcaMode" dict
682
+
683
+ pcaHue =
684
+ decodeInt "pcaHue" dict
685
+
686
+ colourReplaceSource =
687
+ decodeString "colourReplaceSource" dict
688
+
689
+ colourReplaceTarget =
690
+ decodeString "colourReplaceTarget" dict
691
+
692
+ colourReplaceTolerance =
693
+ decodeInt "colourReplaceTolerance" dict
694
+
695
+ colourReplaceBlend =
696
+ decodeFloat "colourReplaceBlend" dict
697
+
698
+ colourReplacePreserveLum =
699
+ decodeBool "colourReplacePreserveLum" dict
700
+
701
+ unsharpAmount =
702
+ decodeFloat "unsharpAmount" dict
703
+
704
+ normalizeStrength =
705
+ decodeFloat "normalizeStrength" dict
706
+
707
+ adaptiveWindow =
708
+ decodeInt "adaptiveWindow" dict
709
+
710
+ adaptiveOffset =
711
+ decodeInt "adaptiveOffset" dict
712
+
713
+ altRedGamma =
714
+ decodeInt "altRedGamma" dict
715
+
716
+ altRedSigmoid =
717
+ decodeInt "altRedSigmoid" dict
718
+
719
+ altRedHue =
720
+ decodeInt "altRedHue" dict
721
+
722
+ altRedHueWindow =
723
+ decodeInt "altRedHueWindow" dict
724
+
725
+ altRedVibrance =
726
+ decodeInt "altRedVibrance" dict
727
+
728
+ altGreenGamma =
729
+ decodeInt "altGreenGamma" dict
730
+
731
+ altGreenSigmoid =
732
+ decodeInt "altGreenSigmoid" dict
733
+
734
+ altGreenHue =
735
+ decodeInt "altGreenHue" dict
736
+
737
+ altGreenHueWindow =
738
+ decodeInt "altGreenHueWindow" dict
739
+
740
+ altGreenVibrance =
741
+ decodeInt "altGreenVibrance" dict
742
+
743
+ altBlueGamma =
744
+ decodeInt "altBlueGamma" dict
745
+
746
+ altBlueSigmoid =
747
+ decodeInt "altBlueSigmoid" dict
748
+
749
+ altBlueHue =
750
+ decodeInt "altBlueHue" dict
751
+
752
+ altBlueHueWindow =
753
+ decodeInt "altBlueHueWindow" dict
754
+
755
+ altBlueVibrance =
756
+ decodeInt "altBlueVibrance" dict
757
+ in
758
+ base
759
+ |> applyMaybe rotation (\v f -> { f | rotation = v })
760
+ |> applyMaybe flip (\v f -> { f | flip = v })
761
+ |> applyMaybe grayscale (\v f -> { f | grayscale = v })
762
+ |> applyMaybe invert (\v f -> { f | invert = v })
763
+ |> applyMaybe threshold (\v f -> { f | thresholdEnabled = True, threshold = v })
764
+ |> applyMaybe brightness (\v f -> { f | brightnessEnabled = True, brightness = v })
765
+ |> applyMaybe contrast (\v f -> { f | contrastEnabled = True, contrast = v })
766
+ |> applyMaybe gamma (\v f -> { f | gammaEnabled = True, gamma = v })
767
+ |> applyMaybe saturation (\v f -> { f | saturationEnabled = True, saturation = v })
768
+ |> applyMaybe vibrance (\v f -> { f | vibranceEnabled = True, vibrance = v })
769
+ |> applyMaybe hue (\v f -> { f | hueEnabled = True, hue = v })
770
+ |> applyMaybe ccRed (\v f -> { f | ccRedEnabled = True, ccRed = v })
771
+ |> applyMaybe ccGreen (\v f -> { f | ccGreenEnabled = True, ccGreen = v })
772
+ |> applyMaybe ccBlue (\v f -> { f | ccBlueEnabled = True, ccBlue = v })
773
+ |> applyMaybe morphOperation (\v f -> { f | morphEnabled = True, morphOperation = v })
774
+ |> applyMaybe morphKernel (\v f -> { f | morphEnabled = True, morphKernel = v })
775
+ |> applyMaybe convolutionPreset (\v f -> { f | convolutionEnabled = True, convolutionPreset = v })
776
+ |> applyMaybe colourmapPreset (\v f -> { f | colourmapEnabled = True, colourmapPreset = v })
777
+ |> applyMaybe colourmapCenter (\v f -> { f | colourmapEnabled = True, colourmapCenter = v })
778
+ |> applyMaybe pseudoColourMode (\v f -> { f | pseudoColourEnabled = True, pseudoColourMode = v })
779
+ |> applyMaybe pseudoColourRed (\v f -> { f | pseudoColourEnabled = True, pseudoColourRed = v })
780
+ |> applyMaybe pseudoColourGreen (\v f -> { f | pseudoColourEnabled = True, pseudoColourGreen = v })
781
+ |> applyMaybe pseudoColourBlue (\v f -> { f | pseudoColourEnabled = True, pseudoColourBlue = v })
782
+ |> applyMaybe pcaMode (\v f -> { f | globalPcaEnabled = True, pcaMode = v })
783
+ |> applyMaybe pcaHue (\v f -> { f | globalPcaEnabled = True, pcaHue = v })
784
+ |> applyMaybe colourReplaceSource (\v f -> { f | colourReplaceEnabled = True, colourReplaceSource = v })
785
+ |> applyMaybe colourReplaceTarget (\v f -> { f | colourReplaceEnabled = True, colourReplaceTarget = v })
786
+ |> applyMaybe colourReplaceTolerance (\v f -> { f | colourReplaceEnabled = True, colourReplaceTolerance = v })
787
+ |> applyMaybe colourReplaceBlend (\v f -> { f | colourReplaceEnabled = True, colourReplaceBlend = v })
788
+ |> applyMaybe colourReplacePreserveLum (\v f -> { f | colourReplaceEnabled = True, colourReplacePreserveLum = v })
789
+ |> applyMaybe unsharpAmount (\v f -> { f | unsharpEnabled = True, unsharpAmount = v })
790
+ |> applyMaybe normalizeStrength (\v f -> { f | normalizeEnabled = True, normalizeStrength = v })
791
+ |> applyMaybe adaptiveWindow (\v f -> { f | adaptiveEnabled = True, adaptiveWindow = v })
792
+ |> applyMaybe adaptiveOffset (\v f -> { f | adaptiveEnabled = True, adaptiveOffset = v })
793
+ |> applyMaybe altRedGamma (\v f -> { f | altRedGamma = v, altRedGammaEnabled = True })
794
+ |> applyMaybe altRedSigmoid (\v f -> { f | altRedSigmoid = v, altRedSigmoidEnabled = True })
795
+ |> applyMaybe altRedHue (\v f -> { f | altRedHue = v, altRedHueEnabled = True })
796
+ |> applyMaybe altRedHueWindow (\v f -> { f | altRedHueEnabled = True, altRedHueWindow = v })
797
+ |> applyMaybe altRedVibrance (\v f -> { f | altRedVibranceEnabled = True, altRedVibrance = v })
798
+ |> applyMaybe altGreenGamma (\v f -> { f | altGreenGamma = v, altGreenGammaEnabled = True })
799
+ |> applyMaybe altGreenSigmoid (\v f -> { f | altGreenSigmoid = v, altGreenSigmoidEnabled = True })
800
+ |> applyMaybe altGreenHue (\v f -> { f | altGreenHue = v, altGreenHueEnabled = True })
801
+ |> applyMaybe altGreenHueWindow (\v f -> { f | altGreenHueEnabled = True, altGreenHueWindow = v })
802
+ |> applyMaybe altGreenVibrance (\v f -> { f | altGreenVibranceEnabled = True, altGreenVibrance = v })
803
+ |> applyMaybe altBlueGamma (\v f -> { f | altBlueGamma = v, altBlueGammaEnabled = True })
804
+ |> applyMaybe altBlueSigmoid (\v f -> { f | altBlueSigmoid = v, altBlueSigmoidEnabled = True })
805
+ |> applyMaybe altBlueHue (\v f -> { f | altBlueHue = v, altBlueHueEnabled = True })
806
+ |> applyMaybe altBlueHueWindow (\v f -> { f | altBlueHueEnabled = True, altBlueHueWindow = v })
807
+ |> applyMaybe altBlueVibrance (\v f -> { f | altBlueVibranceEnabled = True, altBlueVibrance = v })
808
+
809
+
810
+ applyMaybe : Maybe a -> (a -> Filters -> Filters) -> Filters -> Filters
811
+ applyMaybe maybeValue updater filters =
812
+ case maybeValue of
813
+ Just value ->
814
+ updater value filters
815
+
816
+ Nothing ->
817
+ filters
818
+
819
+
820
+ decodeBool : String -> Dict String Decode.Value -> Maybe Bool
821
+ decodeBool key dict =
822
+ decodeMaybe Decode.bool key dict
823
+
824
+
825
+ decodeFloat : String -> Dict String Decode.Value -> Maybe Float
826
+ decodeFloat key dict =
827
+ decodeMaybe
828
+ (Decode.oneOf
829
+ [ Decode.float
830
+ , Decode.int |> Decode.map toFloat
831
+ ]
832
+ )
833
+ key
834
+ dict
835
+
836
+
837
+
838
+ -- FILTER FLOAT VALUE TYPES
839
+
840
+
841
+ decodeInt : String -> Dict String Decode.Value -> Maybe Int
842
+ decodeInt key dict =
843
+ decodeMaybe Decode.int key dict
844
+
845
+
846
+ decodeMaybe : Decode.Decoder a -> String -> Dict String Decode.Value -> Maybe a
847
+ decodeMaybe decoder key dict =
848
+ Dict.get key dict
849
+ |> Maybe.andThen (\value -> Decode.decodeValue decoder value |> Result.toMaybe)
850
+
851
+
852
+ decodeString : String -> Dict String Decode.Value -> Maybe String
853
+ decodeString key dict =
854
+ decodeMaybe Decode.string key dict
855
+
856
+
857
+ ensureOdd : Int -> Int
858
+ ensureOdd v =
859
+ if modBy 2 v == 0 then
860
+ v + 1
861
+
862
+ else
863
+ v
864
+
865
+
866
+
867
+ -- FILTER STRING VALUE TYPES
868
+
869
+
870
+ floatFilterConfig : FilterFloatValue -> FloatFilterConfig
871
+ floatFilterConfig value =
872
+ case value of
873
+ FloatColourReplaceBlend ->
874
+ { min = 0, max = 1, get = .colourReplaceBlend, set = \v f -> { f | colourReplaceBlend = v } }
875
+
876
+ FloatContrast ->
877
+ { min = 0, max = 4, get = .contrast, set = \v f -> { f | contrast = v } }
878
+
879
+ FloatGamma ->
880
+ { min = 0.1, max = 4, get = .gamma, set = \v f -> { f | gamma = v } }
881
+
882
+ FloatNormalizeStrength ->
883
+ { min = 0, max = 2, get = .normalizeStrength, set = \v f -> { f | normalizeStrength = v } }
884
+
885
+ FloatPseudoColourBlue ->
886
+ { min = 0, max = 2, get = .pseudoColourBlue, set = \v f -> { f | pseudoColourBlue = v } }
887
+
888
+ FloatPseudoColourGreen ->
889
+ { min = 0, max = 2, get = .pseudoColourGreen, set = \v f -> { f | pseudoColourGreen = v } }
890
+
891
+ FloatPseudoColourRed ->
892
+ { min = 0, max = 2, get = .pseudoColourRed, set = \v f -> { f | pseudoColourRed = v } }
893
+
894
+ FloatUnsharpAmount ->
895
+ { min = 0, max = 3, get = .unsharpAmount, set = \v f -> { f | unsharpAmount = v } }
896
+
897
+
898
+ intFilterConfig : FilterIntValue -> IntFilterConfig
899
+ intFilterConfig value =
900
+ case value of
901
+ IntAdaptiveOffset ->
902
+ { min = -50, max = 50, get = .adaptiveOffset, set = \v f -> { f | adaptiveOffset = v }, validate = Nothing }
903
+
904
+ IntAdaptiveWindow ->
905
+ { min = 3, max = 51, get = .adaptiveWindow, set = \v f -> { f | adaptiveWindow = v }, validate = Just ensureOdd }
906
+
907
+ IntAltRedGamma ->
908
+ { min = 0, max = 100, get = .altRedGamma, set = \v f -> { f | altRedGamma = v }, validate = Nothing }
909
+
910
+ IntAltRedSigmoid ->
911
+ { min = 0, max = 100, get = .altRedSigmoid, set = \v f -> { f | altRedSigmoid = v }, validate = Nothing }
912
+
913
+ IntAltRedVibrance ->
914
+ { min = 0, max = 100, get = .altRedVibrance, set = \v f -> { f | altRedVibrance = v }, validate = Nothing }
915
+
916
+ IntAltRedHue ->
917
+ { min = -100, max = 100, get = .altRedHue, set = \v f -> { f | altRedHue = v }, validate = Nothing }
918
+
919
+ IntAltRedHueWindow ->
920
+ { min = 2, max = 30, get = .altRedHueWindow, set = \v f -> { f | altRedHueWindow = v }, validate = Nothing }
921
+
922
+ IntAltGreenGamma ->
923
+ { min = 0, max = 100, get = .altGreenGamma, set = \v f -> { f | altGreenGamma = v }, validate = Nothing }
924
+
925
+ IntAltGreenSigmoid ->
926
+ { min = 0, max = 100, get = .altGreenSigmoid, set = \v f -> { f | altGreenSigmoid = v }, validate = Nothing }
927
+
928
+ IntAltGreenHue ->
929
+ { min = -100, max = 100, get = .altGreenHue, set = \v f -> { f | altGreenHue = v }, validate = Nothing }
930
+
931
+ IntAltGreenHueWindow ->
932
+ { min = 2, max = 30, get = .altGreenHueWindow, set = \v f -> { f | altGreenHueWindow = v }, validate = Nothing }
933
+
934
+ IntAltGreenVibrance ->
935
+ { min = 0, max = 100, get = .altGreenVibrance, set = \v f -> { f | altGreenVibrance = v }, validate = Nothing }
936
+
937
+ IntAltBlueGamma ->
938
+ { min = 0, max = 100, get = .altBlueGamma, set = \v f -> { f | altBlueGamma = v }, validate = Nothing }
939
+
940
+ IntAltBlueSigmoid ->
941
+ { min = 0, max = 100, get = .altBlueSigmoid, set = \v f -> { f | altBlueSigmoid = v }, validate = Nothing }
942
+
943
+ IntAltBlueHue ->
944
+ { min = -100, max = 100, get = .altBlueHue, set = \v f -> { f | altBlueHue = v }, validate = Nothing }
945
+
946
+ IntAltBlueHueWindow ->
947
+ { min = 2, max = 30, get = .altBlueHueWindow, set = \v f -> { f | altBlueHueWindow = v }, validate = Nothing }
948
+
949
+ IntAltBlueVibrance ->
950
+ { min = 0, max = 100, get = .altBlueVibrance, set = \v f -> { f | altBlueVibrance = v }, validate = Nothing }
951
+
952
+ IntBrightness ->
953
+ { min = -255, max = 255, get = .brightness, set = \v f -> { f | brightness = v }, validate = Nothing }
954
+
955
+ IntCcBlue ->
956
+ { min = -100, max = 100, get = .ccBlue, set = \v f -> { f | ccBlue = v }, validate = Nothing }
957
+
958
+ IntCcGreen ->
959
+ { min = -100, max = 100, get = .ccGreen, set = \v f -> { f | ccGreen = v }, validate = Nothing }
960
+
961
+ IntCcRed ->
962
+ { min = -100, max = 100, get = .ccRed, set = \v f -> { f | ccRed = v }, validate = Nothing }
963
+
964
+ IntColourmapCenter ->
965
+ { min = 0, max = 255, get = .colourmapCenter, set = \v f -> { f | colourmapCenter = v }, validate = Nothing }
966
+
967
+ IntColourReplaceTolerance ->
968
+ { min = 0, max = 255, get = .colourReplaceTolerance, set = \v f -> { f | colourReplaceTolerance = v }, validate = Nothing }
969
+
970
+ IntPcaHue ->
971
+ { min = -180, max = 180, get = .pcaHue, set = \v f -> { f | pcaHue = v }, validate = Nothing }
972
+
973
+ IntHue ->
974
+ { min = -100, max = 100, get = .hue, set = \v f -> { f | hue = v }, validate = Nothing }
975
+
976
+ IntMorphKernel ->
977
+ { min = 3, max = 7, get = .morphKernel, set = \v f -> { f | morphKernel = v }, validate = Just validateMorphKernel }
978
+
979
+ IntRotation ->
980
+ { min = -180, max = 180, get = .rotation, set = \v f -> { f | rotation = v }, validate = Nothing }
981
+
982
+ IntSaturation ->
983
+ { min = -100, max = 100, get = .saturation, set = \v f -> { f | saturation = v }, validate = Nothing }
984
+
985
+ IntThreshold ->
986
+ { min = 0, max = 255, get = .threshold, set = \v f -> { f | threshold = v }, validate = Nothing }
987
+
988
+ IntVibrance ->
989
+ { min = -100, max = 100, get = .vibrance, set = \v f -> { f | vibrance = v }, validate = Nothing }
990
+
991
+
992
+ stringFilterConfig : FilterStringValue -> StringFilterConfig
993
+ stringFilterConfig value =
994
+ case value of
995
+ StringColourmapPreset ->
996
+ { get = .colourmapPreset
997
+ , set = \v f -> { f | colourmapPreset = v }
998
+ , validate = \v -> List.member v [ "gray", "hot", "cool" ]
999
+ }
1000
+
1001
+ StringColourReplaceSource ->
1002
+ { get = .colourReplaceSource
1003
+ , set = \v f -> { f | colourReplaceSource = v }
1004
+ , validate = always True
1005
+ }
1006
+
1007
+ StringColourReplaceTarget ->
1008
+ { get = .colourReplaceTarget
1009
+ , set = \v f -> { f | colourReplaceTarget = v }
1010
+ , validate = always True
1011
+ }
1012
+
1013
+ StringConvolutionPreset ->
1014
+ { get = .convolutionPreset
1015
+ , set = \v f -> { f | convolutionPreset = v }
1016
+ , validate = \v -> List.member v [ "sharpen", "blur", "edge", "emboss" ]
1017
+ }
1018
+
1019
+ StringPcaMode ->
1020
+ { get = .pcaMode
1021
+ , set = \v f -> { f | pcaMode = v }
1022
+ , validate = \v -> List.member v [ "pca-rgb", "pca1", "pca2", "pca3" ]
1023
+ }
1024
+
1025
+ StringMorphOperation ->
1026
+ { get = .morphOperation
1027
+ , set = \v f -> { f | morphOperation = v }
1028
+ , validate = \v -> v == "erode" || v == "dilate"
1029
+ }
1030
+
1031
+ StringPseudoColourMode ->
1032
+ { get = .pseudoColourMode
1033
+ , set = \v f -> { f | pseudoColourMode = v }
1034
+ , validate = \v -> List.member v [ "rg", "gb", "rb", "luma", "cmy", "heat" ]
1035
+ }
1036
+
1037
+
1038
+ validateMorphKernel : Int -> Int
1039
+ validateMorphKernel v =
1040
+ if v == 3 || v == 5 || v == 7 then
1041
+ v
1042
+
1043
+ else
1044
+ 3