An attempt at getting image data back

This commit is contained in:
2024-07-14 00:27:33 +02:00
parent e026bc93f7
commit 6452d2e774
1314 changed files with 218350 additions and 38 deletions

View File

@@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (C) 2022, Paul Elder <paul.elder@ideasonboard.com>
from libtuning.generators.raspberrypi_output import RaspberryPiOutput
from libtuning.generators.yaml_output import YamlOutput

View File

@@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (C) 2022, Paul Elder <paul.elder@ideasonboard.com>
#
# Base class for a generator to convert dict to tuning file
from pathlib import Path
class Generator(object):
def __init__(self):
pass
def write(self, output_path: Path, output_dict: dict, output_order: list):
raise NotImplementedError

View File

@@ -0,0 +1,114 @@
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright 2022 Raspberry Pi Ltd
#
# Generate tuning file in Raspberry Pi's json format
#
# (Copied from ctt_pretty_print_json.py)
from .generator import Generator
import json
from pathlib import Path
import textwrap
class Encoder(json.JSONEncoder):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.indentation_level = 0
self.hard_break = 120
self.custom_elems = {
'table': 16,
'luminance_lut': 16,
'ct_curve': 3,
'ccm': 3,
'gamma_curve': 2,
'y_target': 2,
'prior': 2
}
def encode(self, o, node_key=None):
if isinstance(o, (list, tuple)):
# Check if we are a flat list of numbers.
if not any(isinstance(el, (list, tuple, dict)) for el in o):
s = ', '.join(json.dumps(el) for el in o)
if node_key in self.custom_elems.keys():
# Special case handling to specify number of elements in a row for tables, ccm, etc.
self.indentation_level += 1
sl = s.split(', ')
num = self.custom_elems[node_key]
chunk = [self.indent_str + ', '.join(sl[x:x + num]) for x in range(0, len(sl), num)]
t = ',\n'.join(chunk)
self.indentation_level -= 1
output = f'\n{self.indent_str}[\n{t}\n{self.indent_str}]'
elif len(s) > self.hard_break - len(self.indent_str):
# Break a long list with wraps.
self.indentation_level += 1
t = textwrap.fill(s, self.hard_break, break_long_words=False,
initial_indent=self.indent_str, subsequent_indent=self.indent_str)
self.indentation_level -= 1
output = f'\n{self.indent_str}[\n{t}\n{self.indent_str}]'
else:
# Smaller lists can remain on a single line.
output = f' [ {s} ]'
return output
else:
# Sub-structures in the list case.
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():
if isinstance(v, dict) and len(v) == 0:
# Empty config block special case.
output.append(self.indent_str + f'{json.dumps(k)}: {{ }}')
else:
# Only linebreak if the next node is a config block.
sep = f'\n{self.indent_str}' if isinstance(v, dict) else ''
output.append(self.indent_str + f'{json.dumps(k)}:{sep}{self.encode(v, k)}')
output = ',\n'.join(output)
self.indentation_level -= 1
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)
class RaspberryPiOutput(Generator):
def __init__(self):
super().__init__()
def _pretty_print(self, in_json: dict) -> str:
if 'version' not in in_json or \
'target' not in in_json or \
'algorithms' not in in_json or \
in_json['version'] < 2.0:
raise RuntimeError('Incompatible JSON dictionary has been provided')
return json.dumps(in_json, cls=Encoder, indent=4, sort_keys=False)
def write(self, output_file: Path, output_dict: dict, output_order: list):
# Write json dictionary to file using ctt's version 2 format
out_json = {
"version": 2.0,
'target': 'bcm2835',
"algorithms": [{f'{module.out_name}': output_dict[module]} for module in output_order]
}
with open(output_file, 'w') as f:
f.write(self._pretty_print(out_json))

View File

@@ -0,0 +1,127 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright 2022 Paul Elder <paul.elder@ideasonboard.com>
#
# Generate tuning file in YAML format
from .generator import Generator
from numbers import Number
from pathlib import Path
import logging
logger = logging.getLogger(__name__)
class YamlOutput(Generator):
def __init__(self):
super().__init__()
def _stringify_number_list(self, listt: list):
line_wrap = 80
line = '[ ' + ', '.join([str(x) for x in listt]) + ' ]'
if len(line) <= line_wrap:
return [line]
out_lines = ['[']
line = ' '
for x in listt:
x_str = str(x)
# If the first number is longer than line_wrap, it'll add an extra line
if len(line) + len(x_str) > line_wrap:
out_lines.append(line)
line = f' {x_str},'
continue
line += f' {x_str},'
out_lines.append(line)
out_lines.append(']')
return out_lines
# @return Array of lines, and boolean of if all elements were numbers
def _stringify_list(self, listt: list):
out_lines = []
all_numbers = set([isinstance(x, Number) for x in listt]).issubset({True})
if all_numbers:
return self._stringify_number_list(listt), True
for value in listt:
if isinstance(value, Number):
out_lines.append(f'- {str(value)}')
elif isinstance(value, str):
out_lines.append(f'- "{value}"')
elif isinstance(value, list):
lines, all_numbers = self._stringify_list(value)
if all_numbers:
out_lines.append( f'- {lines[0]}')
out_lines += [f' {line}' for line in lines[1:]]
else:
out_lines.append( f'-')
out_lines += [f' {line}' for line in lines]
elif isinstance(value, dict):
lines = self._stringify_dict(value)
out_lines.append( f'- {lines[0]}')
out_lines += [f' {line}' for line in lines[1:]]
return out_lines, False
def _stringify_dict(self, dictt: dict):
out_lines = []
for key in dictt:
value = dictt[key]
if isinstance(value, Number):
out_lines.append(f'{key}: {str(value)}')
elif isinstance(value, str):
out_lines.append(f'{key}: "{value}"')
elif isinstance(value, list):
lines, all_numbers = self._stringify_list(value)
if all_numbers:
out_lines.append( f'{key}: {lines[0]}')
out_lines += [f'{" " * (len(key) + 2)}{line}' for line in lines[1:]]
else:
out_lines.append( f'{key}:')
out_lines += [f' {line}' for line in lines]
elif isinstance(value, dict):
lines = self._stringify_dict(value)
out_lines.append( f'{key}:')
out_lines += [f' {line}' for line in lines]
return out_lines
def write(self, output_file: Path, output_dict: dict, output_order: list):
out_lines = [
'%YAML 1.1',
'---',
'version: 1',
# No need to condition this, as libtuning already guarantees that
# we have at least one module. Even if the module has no output,
# its prescence is meaningful.
'algorithms:'
]
for module in output_order:
if module not in output_dict:
continue
out_lines.append(f' - {module.out_name}:')
if len(output_dict[module]) == 0:
continue
if not isinstance(output_dict[module], dict):
logger.error(f'Error: Output of {module.type} is not a dictionary')
continue
lines = self._stringify_dict(output_dict[module])
out_lines += [f' {line}' for line in lines]
with open(output_file, 'w', encoding='utf-8') as f:
for line in out_lines:
f.write(f'{line}\n')