Add very special handling for the MJPG video format
[kaka/cakelight.git] / src / kaka / cakelight / Configuration.java
CommitLineData
e59e98fc
TW
1package kaka.cakelight;
2
cc03403a
TW
3import org.opencv.imgproc.Imgproc;
4
e59e98fc
TW
5import java.io.FileInputStream;
6import java.io.IOException;
7import java.io.InputStream;
8import java.util.*;
9import java.util.stream.Collectors;
10
11public class Configuration {
12 private List<Map.Entry<String, String>> settings = new ArrayList<>();
13 public VideoConfiguration video;
14 public LedConfiguration leds;
38c759f8 15 public double gamma;
e59e98fc
TW
16
17 private Configuration(Properties prop) {
18 video = new VideoConfiguration(prop);
19 leds = new LedConfiguration(prop);
38c759f8 20 gamma = Double.parseDouble(get(prop,"gamma", "1"));
e59e98fc
TW
21 }
22
23 public static Configuration from(String propertiesFile) {
2d8ddb23
TW
24 Properties prop = new Properties();
25 try (InputStream input = new FileInputStream(propertiesFile)) {
e59e98fc 26 prop.load(input);
e59e98fc
TW
27 } catch (IOException ex) {
28 ex.printStackTrace();
e59e98fc 29 }
2d8ddb23 30 return new Configuration(prop);
e59e98fc
TW
31 }
32
33 private String get(Properties prop, String name) {
34 return addSetting(name, prop.getProperty(name));
35 }
36
37 private String get(Properties prop, String name, String dflt) {
38 return addSetting(name, prop.getProperty(name, dflt));
39 }
40
41 private String addSetting(String name, String value) {
42 settings.add(new AbstractMap.SimpleEntry<>(name, value));
43 return value;
44 }
45
46 @Override
47 public String toString() {
48 return settings.stream().map(entry -> entry.getKey() + "=" + entry.getValue()).collect(Collectors.joining("\n"));
49 }
50
51 public class VideoConfiguration {
e59e98fc
TW
52 public int width;
53 public int height;
54 public int bpp;
cc03403a 55 public int format;
eba8feca 56 public boolean mjpg;
a80ebf3e 57 public double saturation;
7434e71c
TW
58 public String device;
59 public boolean deviceIsAutomatic;
100b82fe 60 public CropConfiguration crop;
6a03452e 61 public ListConfiguration list;
e59e98fc
TW
62
63 private VideoConfiguration(Properties prop) {
e59e98fc
TW
64 width = Integer.parseInt(get(prop, "video.width", "720"));
65 height = Integer.parseInt(get(prop, "video.height", "576"));
66 bpp = Integer.parseInt(get(prop, "video.bpp", "2"));
7434e71c
TW
67 device = get(prop, "video.device", "auto");
68 deviceIsAutomatic = "auto".equals(device);
cc03403a
TW
69 switch (get(prop, "video.format", "").toUpperCase()) {
70 case "YUYV":
da7bef43 71 format = Imgproc.COLOR_YUV2BGR_YUYV;
cc03403a
TW
72 break;
73 case "YVYU":
da7bef43 74 format = Imgproc.COLOR_YUV2BGR_YVYU;
cc03403a 75 break;
eba8feca
TW
76 case "MJPG":
77 format = 0;
78 mjpg = true;
cc03403a 79 default:
da7bef43 80 format = Imgproc.COLOR_YUV2BGR_UYVY;
cc03403a 81 }
34d8fc09 82 saturation = inRange(Double.parseDouble(get(prop, "video.saturation", "0.5")), 0, 1);
100b82fe 83 crop = new CropConfiguration(prop);
6a03452e 84 list = new ListConfiguration(prop);
100b82fe
TW
85 }
86
87 public class CropConfiguration {
88 public int left, right, top, bottom;
89
90 private CropConfiguration(Properties prop) {
91 left = Integer.parseInt(get(prop, "video.crop.left", "0"));
92 right = Integer.parseInt(get(prop, "video.crop.right", "0"));
93 top = Integer.parseInt(get(prop, "video.crop.top", "0"));
94 bottom = Integer.parseInt(get(prop, "video.crop.bottom", "0"));
95 }
e59e98fc 96 }
6a03452e
TW
97
98 public class ListConfiguration {
99 public boolean top, bottom, left, right;
100
101 private ListConfiguration(Properties prop) {
102 top = get(prop, "video.list.top", "on").equals("on");
103 bottom = get(prop, "video.list.bottom", "on").equals("on");
104 left = get(prop, "video.list.left", "on").equals("on");
105 right = get(prop, "video.list.right", "on").equals("on");
106 }
107 }
e59e98fc
TW
108 }
109
110 public class LedConfiguration {
111 public int cols;
112 public int rows;
d3261df8 113 public int brightness;
aa9e49c2 114 public LedType type;
e59e98fc
TW
115
116 private LedConfiguration(Properties prop) {
117 cols = Integer.parseInt(get(prop, "leds.cols"));
118 rows = Integer.parseInt(get(prop, "leds.rows"));
34d8fc09 119 brightness = (int) inRange(Integer.parseInt(get(prop, "leds.brightness", "31")), 1, 31);
aa9e49c2
TW
120 switch (get(prop, "leds.type", "").toUpperCase()) {
121 case "WS2801":
122 type = LedType.WS2801;
123 break;
124 case "APA102":
125 default:
126 type = LedType.APA102;
127 }
e59e98fc 128 }
ed56b145
TW
129
130 public int getCount() {
131 return cols * 2 + rows * 2;
132 }
e59e98fc 133 }
aa9e49c2
TW
134
135 public enum LedType {
136 WS2801, APA102
137 }
34d8fc09
TW
138
139 private double inRange(double value, double lower, double upper) {
140 return value < lower ? lower
141 : value > upper ? upper
142 : value;
143 }
e59e98fc 144}