[libcamera-devel,v4,6/8] utils: raspberrypi: Add tuning file conversion script
diff mbox series

Message ID 20220713092159.9014-7-naush@raspberrypi.com
State Superseded
Headers show
Series
  • Replace boost JSON parser with libyaml in Raspberry Pi IPA
Related show

Commit Message

Naushir Patuck July 13, 2022, 9:21 a.m. UTC
Add a script to convert the Raspberry Pi camera tuning file format from version
1.0 to 2.0.

The version 1.0 format was originally used with the boost JSON parser that
happen to provided algorithm ordering based on the ordering in the file. The new
format provides implicit ordering by having the algorithms listed in an array.

This script also adds a root level version key set to 2.0 to the config file,
allowing the controller to distinguish between the two formats.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
---
 utils/raspberrypi/ctt/convert_tuning.py | 94 +++++++++++++++++++++++++
 1 file changed, 94 insertions(+)
 create mode 100755 utils/raspberrypi/ctt/convert_tuning.py

Patch
diff mbox series

diff --git a/utils/raspberrypi/ctt/convert_tuning.py b/utils/raspberrypi/ctt/convert_tuning.py
new file mode 100755
index 000000000000..3396bebe8f4e
--- /dev/null
+++ b/utils/raspberrypi/ctt/convert_tuning.py
@@ -0,0 +1,94 @@ 
+#!/bin/python3
+# Script to convert version 1.0 Raspberry Pi camera tuning files to version 2.0
+# and later.
+#
+# Copyright 2022 Raspberry Pi Ltd.
+
+import argparse
+import json
+import textwrap
+
+
+class Encoder(json.JSONEncoder):
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.indentation_level = 0
+        self.soft_break = 80
+        self.hard_break = 120
+
+    def encode(self, o):
+        if isinstance(o, (list, tuple)):
+            if not any(isinstance(el, (list, tuple, dict)) for el in o):
+                s = ', '.join(json.dumps(el) for el in o)
+                if len(s) > self.soft_break:
+                    self.indentation_level += 1
+                    t = textwrap.wrap(s, self.hard_break, break_long_words=False,
+                                      initial_indent=self.indent_str, subsequent_indent=self.indent_str)
+                    self.indentation_level -= 1
+                    output = '\n'.join(t)
+                    output = f'\n{self.indent_str}[\n{output}\n{self.indent_str}]'
+                else:
+                    output = f' [ {s} ]'
+                return output
+            else:
+                self.indentation_level += 1
+                output = [self.indent_str + self.encode(el) for el in o]
+                self.indentation_level -= 1
+                output = ',\n'.join(output)
+                return f' [\n{output}\n{self.indent_str}]'
+
+        elif isinstance(o, dict):
+            self.indentation_level += 1
+            output = []
+            for k, v in o.items():
+                sep = f'\n{self.indent_str}' if isinstance(v, dict) else ''
+                output.append(self.indent_str + f'{json.dumps(k)}:{sep}{self.encode(v)}')
+            self.indentation_level -= 1
+            output = ',\n'.join(output)
+            return f'{{\n{output}\n{self.indent_str}}}'
+
+        else:
+            return ' ' + json.dumps(o)
+
+    @property
+    def indent_str(self) -> str:
+        return ' ' * self.indentation_level * self.indent
+
+    def iterencode(self, o, **kwargs):
+        return self.encode(o)
+
+
+def convert_v2(in_json):
+
+    ver = 1.0 if 'version' not in in_json.keys() else in_json['version']
+
+    if ver != 1.0:
+        print(f'Cannot convert version {ver} format to version 2.0!')
+        exit(-1)
+
+    converted = {}
+    converted['version'] = 2.0
+    converted['algorithms'] = []
+
+    for k, v in in_json.items():
+        if k == 'version':
+            continue
+        converted['algorithms'].append(dict(zip([k], [v])))
+
+    return json.dumps(converted, cls=Encoder, indent=4, sort_keys=False)
+
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(description='Convert the format of the Raspberry Pi camera tuning file from v1 to v2.')
+    parser.add_argument('input', type=str, nargs=1, help='Input config file')
+    parser.add_argument('output', type=str, nargs='?', help='Output converted config file', default=None)
+    args = parser.parse_args()
+
+    with open(args.input[0], 'r') as f:
+        in_json = json.load(f)
+
+    out_json = convert_v2(in_json)
+
+    with open(args.output if args.output is not None else args.input[0], 'w') as f:
+        f.write(out_json)